diff --git a/samples/drivers/lcd_hd44780/Makefile b/samples/drivers/lcd_hd44780/Makefile new file mode 100644 index 00000000000..7c40b875f61 --- /dev/null +++ b/samples/drivers/lcd_hd44780/Makefile @@ -0,0 +1,5 @@ +KERNEL_TYPE = nano +BOARD = arduino_due +CONF_FILE = prj.conf + +include ${ZEPHYR_BASE}/Makefile.inc diff --git a/samples/drivers/lcd_hd44780/prj.conf b/samples/drivers/lcd_hd44780/prj.conf new file mode 100644 index 00000000000..a032cfbd1d3 --- /dev/null +++ b/samples/drivers/lcd_hd44780/prj.conf @@ -0,0 +1,3 @@ +CONFIG_GPIO=y +CONFIG_NANO_TIMERS=y +CONFIG_NANO_TIMEOUTS=y diff --git a/samples/drivers/lcd_hd44780/src/Makefile b/samples/drivers/lcd_hd44780/src/Makefile new file mode 100644 index 00000000000..00066e15678 --- /dev/null +++ b/samples/drivers/lcd_hd44780/src/Makefile @@ -0,0 +1 @@ +obj-y = main.o diff --git a/samples/drivers/lcd_hd44780/src/main.c b/samples/drivers/lcd_hd44780/src/main.c new file mode 100644 index 00000000000..117573076cd --- /dev/null +++ b/samples/drivers/lcd_hd44780/src/main.c @@ -0,0 +1,611 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Display text strings on HD44780 based 20x4 LCD controller + * using GPIO for parallel interface on Arduino Due. + * + * Datasheet: http://lcd-linux.sourceforge.net/pdfdocs/hd44780.pdf + * + * LCD Wiring + * ---------- + * + * The wiring for the LCD is as follows: + * 1 : GND + * 2 : 5V + * 3 : Contrast (0-5V)* + * 4 : RS (Register Select) + * 5 : R/W (Read Write) - GROUND THIS PIN + * 6 : Enable or Strobe + * 7 : Data Bit 0 - NOT USED + * 8 : Data Bit 1 - NOT USED + * 9 : Data Bit 2 - NOT USED + * 10: Data Bit 3 - NOT USED + * 11: Data Bit 4 + * 12: Data Bit 5 + * 13: Data Bit 6 + * 14: Data Bit 7 + * 15: LCD Backlight +5V** + * 16: LCD Backlight GND + * + * + * Arduino Due + * ----------- + * + * On Arduino Due: + * 1. IO_3 is PC28 + * 2. IO_5 is PC25 + * 3. IO_6 is PC24 + * 4. IO_7 is PC23 + * 5. IO_8 is PC22 + * 6. IO_9 is PC21 + * + * The gpio_atmel_sam3 driver is being used. + * + * This sample app display text strings per line & page wise. + * + * Every 3 second you should see this repeatedly + * on display: + * " + * ********************* + * Arduino Due + * 20x4 LCD Display + * ********************* + * + * ------------------ + * - Zephyr Rocks! + * - My super RTOS + * ------------------ + * + * --------HOME-------- + * I am home! + * + * -------------------- + */ + +#include + +#include +#include +#include +#include + + +#if defined(CONFIG_GPIO_ATMEL_SAM3) +#define GPIO_DRV_NAME CONFIG_GPIO_ATMEL_SAM3_PORTC_DEV_NAME +#else +#error "Unsupported GPIO driver" +#endif + +#if defined(CONFIG_SOC_ATMEL_SAM3) +/* Define GPIO OUT to LCD */ +#define GPIO_PIN_PC12_D0 12 /* PC12 - pin 51 */ +#define GPIO_PIN_PC13_D1 13 /* PC13 - pin 50 */ +#define GPIO_PIN_PC14_D2 14 /* PC14 - pin 49 */ +#define GPIO_PIN_PC15_D3 15 /* PC15 - pin 48 */ +#define GPIO_PIN_PC24_D4 24 /* PC24 - pin 6 */ +#define GPIO_PIN_PC23_D5 23 /* PC23 - pin 7 */ +#define GPIO_PIN_PC22_D6 22 /* PC22 - pin 8 */ +#define GPIO_PIN_PC21_D7 21 /* PC21 - pin 9 */ +#define GPIO_PIN_PC28_RS 28 /* PC28 - pin 3 */ +#define GPIO_PIN_PC25_E 25 /* PC25 - pin 5 */ +#define GPIO_NAME "GPIO_" +#endif + +/* Commands */ +#define LCD_CLEAR_DISPLAY 0x01 +#define LCD_RETURN_HOME 0x02 +#define LCD_ENTRY_MODE_SET 0x04 +#define LCD_DISPLAY_CONTROL 0x08 +#define LCD_CURSOR_SHIFT 0x10 +#define LCD_FUNCTION_SET 0x20 +#define LCD_SET_CGRAM_ADDR 0x40 +#define LCD_SET_DDRAM_ADDR 0x80 + +/* Display entry mode */ +#define LCD_ENTRY_RIGHT 0x00 +#define LCD_ENTRY_LEFT 0x02 +#define LCD_ENTRY_SHIFT_INCREMENT 0x01 +#define LCD_ENTRY_SHIFT_DECREMENT 0x00 + +/* Display on/off control */ +#define LCD_DISPLAY_ON 0x04 +#define LCD_DISPLAY_OFF 0x00 +#define LCD_CURSOR_ON 0x02 +#define LCD_CURSOR_OFF 0x00 +#define LCD_BLINK_ON 0x01 +#define LCD_BLINK_OFF 0x00 + +/* Display/cursor shift */ +#define LCD_DISPLAY_MOVE 0x08 +#define LCD_CURSOR_MOVE 0x00 +#define LCD_MOVE_RIGHT 0x04 +#define LCD_MOVE_LEFT 0x00 + +/* Function set */ +#define LCD_8BIT_MODE 0x10 +#define LCD_4BIT_MODE 0x00 +#define LCD_2_LINE 0x08 +#define LCD_1_LINE 0x00 +#define LCD_5x10_DOTS 0x04 +#define LCD_5x8_DOTS 0x00 + +/* Define some device constants */ +#define LCD_WIDTH 20 /* Max char per line */ +#define HIGH 1 +#define LOW 0 +#define ENABLE_DELAY 0.0100 + + +#define GPIO_PIN_WR(dev, pin, bit) \ + do { \ + if (gpio_pin_write((dev), (pin), (bit))) { \ + printk("Err set " GPIO_NAME "%d! %x\n", (pin), (bit)); \ + } \ + } while (0) \ + + +#define GPIO_PIN_CFG(dev, pin, dir) \ + do { \ + if (gpio_pin_configure((dev), (pin), (dir))) { \ + printk("Err cfg " GPIO_NAME "%d! %x\n", (pin), (dir)); \ + } \ + } while (0) + + +struct pi_lcd_data { + uint8_t disp_func; /* Display Function */ + uint8_t disp_cntl; /* Display Control */ + uint8_t disp_mode; /* Display Mode */ + uint8_t cfg_rows; + uint8_t row_offsets[4]; +}; + +/* Default Configuration - User can update */ +struct pi_lcd_data lcd_data = { + .disp_func = LCD_4BIT_MODE | LCD_1_LINE | LCD_5x8_DOTS, + .disp_cntl = 0, + .disp_mode = 0, + .cfg_rows = 0, + .row_offsets = {0x00, 0x00, 0x00, 0x00} +}; + +void _set_row_offsets(int8_t row0, int8_t row1, int8_t row2, int8_t row3) +{ + lcd_data.row_offsets[0] = row0; + lcd_data.row_offsets[1] = row1; + lcd_data.row_offsets[2] = row2; + lcd_data.row_offsets[3] = row3; +} + + +void _pi_lcd_toggle_enable(struct device *gpio_dev) +{ + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC25_E, LOW); + task_sleep(SECONDS(ENABLE_DELAY)); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC25_E, HIGH); + task_sleep(SECONDS(ENABLE_DELAY)); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC25_E, LOW); + task_sleep(SECONDS(ENABLE_DELAY)); +} + + +void _pi_lcd_4bits_wr(struct device *gpio_dev, uint8_t bits) +{ + /* High bits */ + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC24_D4, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC23_D5, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC22_D6, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC21_D7, LOW); + if ((bits & BIT(4)) == BIT(4)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC24_D4, HIGH); + } + if ((bits & BIT(5)) == BIT(5)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC23_D5, HIGH); + } + if ((bits & BIT(6)) == BIT(6)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC22_D6, HIGH); + } + if ((bits & BIT(7)) == BIT(7)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC21_D7, HIGH); + } + + /* Toggle 'Enable' pin */ + _pi_lcd_toggle_enable(gpio_dev); + + /* Low bits */ + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC24_D4, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC23_D5, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC22_D6, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC21_D7, LOW); + if ((bits & BIT(0)) == BIT(0)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC24_D4, HIGH); + } + if ((bits & BIT(1)) == BIT(1)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC23_D5, HIGH); + } + if ((bits & BIT(2)) == BIT(2)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC22_D6, HIGH); + } + if ((bits & BIT(3)) == BIT(3)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC21_D7, HIGH); + } + + /* Toggle 'Enable' pin */ + _pi_lcd_toggle_enable(gpio_dev); +} + +void _pi_lcd_8bits_wr(struct device *gpio_dev, uint8_t bits) +{ + /* High bits */ + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC21_D7, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC22_D6, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC23_D5, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC24_D4, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC15_D3, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC14_D2, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC13_D1, LOW); + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC12_D0, LOW); + + /* Low bits */ + if ((bits & BIT(0)) == BIT(0)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC12_D0, HIGH); + } + if ((bits & BIT(1)) == BIT(1)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC13_D1, HIGH); + } + if ((bits & BIT(2)) == BIT(2)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC14_D2, HIGH); + } + if ((bits & BIT(3)) == BIT(3)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC15_D3, HIGH); + } + if ((bits & BIT(4)) == BIT(4)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC24_D4, HIGH); + } + if ((bits & BIT(5)) == BIT(5)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC23_D5, HIGH); + } + if ((bits & BIT(6)) == BIT(6)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC22_D6, HIGH); + } + if ((bits & BIT(7)) == BIT(7)) { + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC21_D7, HIGH); + } + + /* Toggle 'Enable' pin */ + _pi_lcd_toggle_enable(gpio_dev); +} + +void _pi_lcd_data(struct device *gpio_dev, uint8_t bits) +{ + if (lcd_data.disp_func & LCD_8BIT_MODE) { + _pi_lcd_8bits_wr(gpio_dev, bits); + } else { + _pi_lcd_4bits_wr(gpio_dev, bits); + } +} + +void _pi_lcd_command(struct device *gpio_dev, uint8_t bits) +{ + /* mode = False for command */ + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC28_RS, LOW); + _pi_lcd_data(gpio_dev, bits); +} + +void _pi_lcd_write(struct device *gpio_dev, uint8_t bits) +{ + /* mode = True for character */ + GPIO_PIN_WR(gpio_dev, GPIO_PIN_PC28_RS, HIGH); + _pi_lcd_data(gpio_dev, bits); +} + + +/************************* + * USER can use these APIs + *************************/ +/** Home */ +void pi_lcd_home(struct device *gpio_dev) +{ + _pi_lcd_command(gpio_dev, LCD_RETURN_HOME); + task_sleep(USEC(2000)); /* wait for 4.1ms */ +} + +/** Set curson position */ +void pi_lcd_set_cursor(struct device *gpio_dev, uint8_t col, uint8_t row) +{ + size_t max_lines; + + max_lines = (sizeof(lcd_data.row_offsets) / sizeof(*lcd_data.row_offsets)); + if (row >= max_lines) { + row = max_lines - 1; /* Count rows starting w/0 */ + } + if (row >= lcd_data.cfg_rows) { + row = lcd_data.cfg_rows - 1; /* Count rows starting w/0 */ + } + _pi_lcd_command(gpio_dev, (LCD_SET_DDRAM_ADDR | (col + lcd_data.row_offsets[row]))); +} + + +/** Clear display */ +void pi_lcd_clear(struct device *gpio_dev) +{ + _pi_lcd_command(gpio_dev, LCD_CLEAR_DISPLAY); + task_sleep(USEC(2000)); /* wait for 4.1ms */ +} + + +/** Display ON */ +void pi_lcd_display_on(struct device *gpio_dev) +{ + lcd_data.disp_cntl |= LCD_DISPLAY_ON; + _pi_lcd_command(gpio_dev, + LCD_DISPLAY_CONTROL | lcd_data.disp_cntl); +} + +/** Display OFF */ +void pi_lcd_display_off(struct device *gpio_dev) +{ + lcd_data.disp_cntl &= ~LCD_DISPLAY_ON; + _pi_lcd_command(gpio_dev, + LCD_DISPLAY_CONTROL | lcd_data.disp_cntl); +} + + +/** Turns cursor off */ +void pi_lcd_cursor_off(struct device *gpio_dev) +{ + lcd_data.disp_cntl &= ~LCD_CURSOR_ON; + _pi_lcd_command(gpio_dev, + LCD_DISPLAY_CONTROL | lcd_data.disp_cntl); +} + +/** Turn cursor on */ +void pi_lcd_cursor_on(struct device *gpio_dev) +{ + lcd_data.disp_cntl |= LCD_CURSOR_ON; + _pi_lcd_command(gpio_dev, + LCD_DISPLAY_CONTROL | lcd_data.disp_cntl); +} + + +/** Turn off the blinking cursor */ +void pi_lcd_blink_off(struct device *gpio_dev) +{ + lcd_data.disp_cntl &= ~LCD_BLINK_ON; + _pi_lcd_command(gpio_dev, + LCD_DISPLAY_CONTROL | lcd_data.disp_cntl); +} + +/** Turn on the blinking cursor */ +void pi_lcd_blink_on(struct device *gpio_dev) +{ + lcd_data.disp_cntl |= LCD_BLINK_ON; + _pi_lcd_command(gpio_dev, + LCD_DISPLAY_CONTROL | lcd_data.disp_cntl); +} + +/** Scroll the display left without changing the RAM */ +void pi_lcd_scroll_left(struct device *gpio_dev) +{ + _pi_lcd_command(gpio_dev, LCD_CURSOR_SHIFT | + LCD_DISPLAY_MOVE | LCD_MOVE_LEFT); +} + +/** Scroll the display right without changing the RAM */ +void pi_lcd_scroll_right(struct device *gpio_dev) +{ + _pi_lcd_command(gpio_dev, LCD_CURSOR_SHIFT | + LCD_DISPLAY_MOVE | LCD_MOVE_RIGHT); +} + +/** Text that flows from left to right */ +void pi_lcd_left_to_right(struct device *gpio_dev) +{ + lcd_data.disp_mode |= LCD_ENTRY_LEFT; + _pi_lcd_command(gpio_dev, + LCD_ENTRY_MODE_SET | lcd_data.disp_cntl); +} + +/** Text that flows from right to left */ +void pi_lcd_right_to_left(struct device *gpio_dev) +{ + lcd_data.disp_mode &= ~LCD_ENTRY_LEFT; + _pi_lcd_command(gpio_dev, + LCD_ENTRY_MODE_SET | lcd_data.disp_cntl); +} + +/** Right justify text from the cursor location */ +void pi_lcd_auto_scroll_right(struct device *gpio_dev) +{ + lcd_data.disp_mode |= LCD_ENTRY_SHIFT_INCREMENT; + _pi_lcd_command(gpio_dev, + LCD_ENTRY_MODE_SET | lcd_data.disp_cntl); +} + +/** Left justify text from the cursor location */ +void pi_lcd_auto_scroll_left(struct device *gpio_dev) +{ + lcd_data.disp_mode &= ~LCD_ENTRY_SHIFT_INCREMENT; + _pi_lcd_command(gpio_dev, + LCD_ENTRY_MODE_SET | lcd_data.disp_cntl); +} + +void pi_lcd_string(struct device *gpio_dev, char *msg) +{ + int i; + int len = 0; + uint8_t data; + + len = strlen(msg); + if (len > LCD_WIDTH) { + printk("Too long message! len %d %s\n", len, msg); + } + + for (i = 0; i < len; i++) { + data = msg[i]; + _pi_lcd_write(gpio_dev, data); + } +} + + +/** LCD initialization function */ +void pi_lcd_init(struct device *gpio_dev, uint8_t cols, uint8_t rows, uint8_t dotsize) +{ + if (rows > 1) { + lcd_data.disp_func |= LCD_2_LINE; + } + lcd_data.cfg_rows = rows; + + _set_row_offsets(0x00, 0x40, 0x00 + cols, 0x40 + cols); + + /* For 1 line displays, a 10 pixel high font looks OK */ + if ((dotsize != LCD_5x8_DOTS) && (rows == 1)) { + lcd_data.disp_func |= LCD_5x10_DOTS; + } + + /* SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! + * according to datasheet, we need at least 40ms after power rises + * above 2.7V before sending commands. Arduino can turn on way + * before 4.5V so we'll wait 50 + */ + task_sleep(USEC(50000)); + + /* this is according to the hitachi HD44780 datasheet + * figure 23/24, pg 45/46 try to set 4/8 bits mode + */ + if (lcd_data.disp_func & LCD_8BIT_MODE) { + /* 1st try */ + _pi_lcd_command(gpio_dev, 0x30); + task_sleep(USEC(4500)); /* wait for 4.1ms */ + + /* 2nd try */ + _pi_lcd_command(gpio_dev, 0x30); + task_sleep(USEC(4500)); /* wait for 4.1ms */ + + /* 3rd try */ + _pi_lcd_command(gpio_dev, 0x30); + task_sleep(USEC(150)); /* wait for 100us */ + + /* Set 4bit interface */ + _pi_lcd_command(gpio_dev, 0x30); + } else { + /* 1st try */ + _pi_lcd_command(gpio_dev, 0x03); + task_sleep(USEC(4500)); /* wait for 4.1ms */ + + /* 2nd try */ + _pi_lcd_command(gpio_dev, 0x03); + task_sleep(USEC(4500)); /* wait for 4.1ms */ + + /* 3rd try */ + _pi_lcd_command(gpio_dev, 0x03); + task_sleep(USEC(150)); /* wait for 100us */ + + /* Set 4bit interface */ + _pi_lcd_command(gpio_dev, 0x02); + } + + /* finally, set # lines, font size, etc. */ + _pi_lcd_command(gpio_dev, (LCD_FUNCTION_SET | lcd_data.disp_func)); + + /* turn the display on with no cursor or blinking default */ + lcd_data.disp_cntl = LCD_DISPLAY_ON | LCD_CURSOR_OFF | LCD_BLINK_OFF; + pi_lcd_display_on(gpio_dev); + + /* clear it off */ + pi_lcd_clear(gpio_dev); + + /* Initialize to default text direction */ + lcd_data.disp_mode = LCD_ENTRY_LEFT | LCD_ENTRY_SHIFT_DECREMENT; + /* set the entry mode */ + _pi_lcd_command(gpio_dev, LCD_ENTRY_MODE_SET | lcd_data.disp_mode); +} + +void main(void) +{ + struct device *gpio_dev; + + gpio_dev = device_get_binding(GPIO_DRV_NAME); + if (!gpio_dev) { + printk("Cannot find %s!\n", GPIO_DRV_NAME); + } + + /* Setup GPIO output */ + GPIO_PIN_CFG(gpio_dev, GPIO_PIN_PC25_E, GPIO_DIR_OUT); + GPIO_PIN_CFG(gpio_dev, GPIO_PIN_PC28_RS, GPIO_DIR_OUT); + GPIO_PIN_CFG(gpio_dev, GPIO_PIN_PC12_D0, GPIO_DIR_OUT); + GPIO_PIN_CFG(gpio_dev, GPIO_PIN_PC13_D1, GPIO_DIR_OUT); + GPIO_PIN_CFG(gpio_dev, GPIO_PIN_PC14_D2, GPIO_DIR_OUT); + GPIO_PIN_CFG(gpio_dev, GPIO_PIN_PC15_D3, GPIO_DIR_OUT); + GPIO_PIN_CFG(gpio_dev, GPIO_PIN_PC24_D4, GPIO_DIR_OUT); + GPIO_PIN_CFG(gpio_dev, GPIO_PIN_PC23_D5, GPIO_DIR_OUT); + GPIO_PIN_CFG(gpio_dev, GPIO_PIN_PC22_D6, GPIO_DIR_OUT); + GPIO_PIN_CFG(gpio_dev, GPIO_PIN_PC21_D7, GPIO_DIR_OUT); + + printk("LCD Init\n"); + pi_lcd_init(gpio_dev, 20, 4, LCD_5x8_DOTS); + + /* Clear display */ + pi_lcd_clear(gpio_dev); + + while (1) { + printk("Page 1: message\n"); + + pi_lcd_string(gpio_dev, "********************"); + pi_lcd_set_cursor(gpio_dev, 0, 1); + pi_lcd_string(gpio_dev, "Arduino Due"); + pi_lcd_right_to_left(gpio_dev); + pi_lcd_set_cursor(gpio_dev, 15, 2); + pi_lcd_string(gpio_dev, "yalpsiD DCL 4x02"); + pi_lcd_set_cursor(gpio_dev, 19, 3); + pi_lcd_left_to_right(gpio_dev); + pi_lcd_string(gpio_dev, "********************"); + task_sleep(SECONDS(3)); + + /* Clear display */ + pi_lcd_clear(gpio_dev); + + printk("Page 2: message\n"); + + pi_lcd_scroll_right(gpio_dev); + pi_lcd_string(gpio_dev, "-------------------"); + pi_lcd_set_cursor(gpio_dev, 0, 1); + pi_lcd_scroll_right(gpio_dev); + pi_lcd_string(gpio_dev, "Zephyr Rocks!"); + pi_lcd_set_cursor(gpio_dev, 0, 2); + pi_lcd_string(gpio_dev, "My super RTOS"); + pi_lcd_set_cursor(gpio_dev, 0, 3); + pi_lcd_string(gpio_dev, "-------------------"); + task_sleep(SECONDS(3)); + + /* Clear display */ + pi_lcd_clear(gpio_dev); + + printk("Page 3: message\n"); + + pi_lcd_set_cursor(gpio_dev, 0, 3); + pi_lcd_string(gpio_dev, "--------------------"); + pi_lcd_home(gpio_dev); + pi_lcd_string(gpio_dev, "--------HOME--------"); + pi_lcd_set_cursor(gpio_dev, 0, 1); + pi_lcd_string(gpio_dev, "I am home!"); + pi_lcd_set_cursor(gpio_dev, 0, 2); + pi_lcd_string(gpio_dev, ""); + task_sleep(SECONDS(3)); + + /* Clear display */ + pi_lcd_clear(gpio_dev); + } +}