BSP430  20141115
Board Support Package for MSP430 microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
U8GLIB LCD Text and Graphics

This example shows how to use the Universal Graphics Library for 8 Bit Embedded Systems library to produce text and graphical elements using an on-board LCD. The example works with BSP430_PLATFORM_EXP430F5438, BSP430_PLATFORM_EXP430F5529, and BSP430_PLATFORM_TRXEB.

When built with SHARP96=1 it also works with the BSP430_PLATFORM_BOOSTERPACK_SHARP96. Note that these displays require a periodic refresh, which is supported using the BSP430 alarm infrastructure.

main.c

#include <bsp430/clock.h>
#include <bsp430/serial.h>
#include <string.h>
static u8g_t u8g_data;
#if (BSP430_U8GLIB_REFRESH_INTERVAL_MS - 0)
#ifndef REFRESH_ALARM_CCIDX
#define REFRESH_ALARM_CCIDX 1
#endif /* REFRESH_ALARM_CCIDX */
typedef struct sRefreshTimerState {
hBSP430timerAlarm active_alarm;
unsigned long interval_tck;
u8g_t * u8g;
} sRefreshTimerState;
static sRefreshTimerState refresh_state;
static int
refresh_cb_ni (hBSP430timerAlarm alarm)
{
sRefreshTimerState * rtsp = (sRefreshTimerState *)alarm;
unsigned long setting_tck;
int rc;
int rv;
rv = iBSP430u8gRefresh(rtsp->u8g);
setting_tck = alarm->setting_tck;
do {
setting_tck += rtsp->interval_tck;
rc = iBSP430timerAlarmSet_ni(alarm, setting_tck);
} while (0 < rc);
return rv;
}
static int
enableRefreshTimer ()
{
int rc = 0;
if (0 == refresh_state.interval_tck) {
cprintf("Refresh timer defined but empty interval?");
return -1;
}
cprintf("Enable refresh every %lu ticks\n", refresh_state.interval_tck);
refresh_state.u8g = &u8g_data;
ah = hBSP430timerAlarmInitialize(&refresh_state.alarm,
REFRESH_ALARM_CCIDX,
refresh_cb_ni);
if (ah) {
do {
if (0 == rc) {
rc = iBSP430timerAlarmSet_ni(ah, ulBSP430uptime_ni() + refresh_state.interval_tck);
}
} while (0);
}
if (0 != rc) {
cprintf("Failed to initialize alarm\n");
}
return rc;
}
#else /* BSP430_U8GLIB_REFRESH_INTERVAL_MS */
static int
enableRefreshTimer ()
{
cprintf("No refresh timer required\n");
return 0;
}
#endif /* BSP430_U8GLIB_REFRESH_INTERVAL_MS */
void main ()
{
int w;
int h;
int rc;
unsigned long t0;
unsigned long t1;
u8g_t * u8g = &u8g_data;
cprintf("\nBuild " __DATE__ " " __TIME__ "\n");
rc = u8g_Init(u8g, &xBSP430u8gDevice);
cprintf("U8G device initialization got %d\n", rc);
spi = hBSP430u8gSPI();
if (0 != enableRefreshTimer()) {
/* Failure to configure the refresh timer is a fatal error, on the
* theory that it could result in damage due to DC bias */
cprintf("ERROR: Unable to configure refresh timer\n");
return;
}
cprintf("Device size %u x %u, mode %d\n", u8g_GetWidth(u8g), u8g_GetHeight(u8g), u8g_GetMode(u8g));
u8g_SetDefaultForegroundColor(u8g);
u8g_SetFont(u8g, u8g_font_10x20);
w = u8g_GetFontBBXWidth(u8g);
h = u8g_GetFontBBXHeight(u8g);
cprintf("Font cell %u x %u\n", w, h);
u8g_FirstPage(u8g);
do {
u8g_DrawLine(u8g, 0, 0, u8g_GetWidth(u8g), u8g_GetHeight(u8g));
u8g_DrawStr(u8g, 0, h, __DATE__);
u8g_DrawStr(u8g, 0, 3*h, __TIME__);
} while (u8g_NextPage(u8g));
cprintf("Write screen took %lu ticks\n", t1-t0);
#if 0
{
unsigned int contrast;
cprintf("Cycling through contrast levels\n");
for (contrast = 0; contrast < 256; contrast += 16) {
u8g_SetContrast(u8g, contrast);
}
/* Don't muck with contrast unless you have to. Legibility is
* different on different LCDs; TrxEB works with 22/64,
* EXP430F5529 works at 8/64, EXP430F5438 works at 0x58/128.
* None is legible at another's setting. */
u8g_SetContrast(u8g, 22 << 2);
}
#endif
cprintf("Toggling sleep mode\n");
while (1) {
u8g_SleepOff(u8g);
u8g_SleepOn(u8g);
}
}

bsp430_config.h

/* Use a crystal if one is installed. Much more accurate timing
* results. */
#define BSP430_PLATFORM_BOOT_CONFIGURE_LFXT1 1
/* Application does output: support spin-for-jumper */
#define configBSP430_PLATFORM_SPIN_FOR_JUMPER 1
/* Support console output */
#define configBSP430_CONSOLE 1
/* Monitor uptime and provide generic ACLK-driven timer */
#define configBSP430_UPTIME 1
/* Enable platform LCD where available */
#define configBSP430_UTILITY_U8GLIB 1
/* Request platform help so we can know where to trace SPI for LCD */
#define configBSP430_PLATFORM_PERIPHERAL_HELP 1
/* Get platform defaults */

Makefile

# For SHARP96 boosterpack: SHARP96=1
# For LS013B7DH03: SHARP96=1 COLS=128 ROWS=128
# For LS027B7DH01: SHARP96=1 COLS=400 ROWS=240 WITH_WIDE_U8G=1
TEST_PLATFORMS=trxeb exp430f5438 exp430f5529
SHARP96 ?=
U8GLIB_ROOT ?= /opt/u8glib
U8GLIB_CSRC = $(U8GLIB_ROOT)/csrc
AUX_CPPFLAGS = -I$(U8GLIB_CSRC)
ifneq (,$(COLS))
AUX_CPPFLAGS += -DBSP430_PLATFORM_SHARPLCD_COLUMNS=$(COLS)
endif # COLS
ifneq (,$(ROWS))
AUX_CPPFLAGS += -DBSP430_PLATFORM_SHARPLCD_ROWS=$(ROWS)
endif # ROWS
WITH_WIDE_U8G ?=
ifneq (,$(WITH_WIDE_U8G))
# Required when $(COLS) > 255
AUX_CPPFLAGS += -DU8G_16BIT
endif # WITH_WIDE_U8G
PLATFORM ?= trxeb
MODULES=$(MODULES_PLATFORM)
MODULES += $(MODULES_UPTIME)
MODULES += $(MODULES_CONSOLE)
MODULES += $(MODULES_SERIAL)
MODULES += periph/port
ifneq (,$(SHARP96))
AUX_CPPFLAGS += -DconfigBSP430_PLATFORM_BOOSTERPACK_SHARP96=1
VPATH += $(BSP430_ROOT)/src/boosterpack/sharp96
MODULES += utility/sharplcd
PLATFORM_U8G_PB_C ?= $(U8GLIB_CSRC)/u8g_pb8h1.c
endif # SHARP96
U8GLIB_SRC = \
$(U8GLIB_CSRC)/u8g_com_api.c \
$(U8GLIB_CSRC)/u8g_ll_api.c \
$(U8GLIB_CSRC)/u8g_font.c \
$(U8GLIB_CSRC)/u8g_line.c \
$(U8GLIB_CSRC)/u8g_clip.c \
$(U8GLIB_CSRC)/u8g_page.c \
$(U8GLIB_CSRC)/u8g_state.c \
$(U8GLIB_CSRC)/u8g_pb.c \
$(PLATFORM_U8G_PB_C) \
$(U8GLIB_ROOT)/fntsrc/u8g_font_10x20.c
SRC = $(U8GLIB_SRC) u8g_bsp430.c main.c
include $(BSP430_ROOT)/make/Makefile.common