diff options
author | Yun-chieh, Lee <lyunjie@google.com> | 2020-09-10 21:57:00 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-09-21 17:34:15 +0000 |
commit | db78abe0160364bf075e1595850407dfdd182297 (patch) | |
tree | 4a6a28dfbc18485285b90eca5a2be49e7a5b47b0 | |
parent | b7dc125ebb97fcc87ff606696f4fb5315b767c45 (diff) | |
download | chrome-ec-db78abe0160364bf075e1595850407dfdd182297.tar.gz |
ucsa: add lcd driver
LCD 2004A driver, show "USB-C Sink Advertiser" on screen.
BUG=none
TEST=make buildall
BRANCH=master
Signed-off-by: Yun-Chieh Lee <lyunjie@google.com>
Change-Id: I4dc3932fba0077bc215f2e6c7855ba26995370ac
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2402852
Reviewed-by: Ting Shen <phoenixshen@chromium.org>
-rw-r--r-- | board/fusb307bgevb/board.c | 20 | ||||
-rw-r--r-- | board/fusb307bgevb/build.mk | 2 | ||||
-rw-r--r-- | board/fusb307bgevb/lcd.c | 166 | ||||
-rw-r--r-- | board/fusb307bgevb/lcd.h | 69 |
4 files changed, 244 insertions, 13 deletions
diff --git a/board/fusb307bgevb/board.c b/board/fusb307bgevb/board.c index 71b2c445da..9d92b5a560 100644 --- a/board/fusb307bgevb/board.c +++ b/board/fusb307bgevb/board.c @@ -8,27 +8,18 @@ #include "ec_version.h" #include "gpio.h" #include "hooks.h" +#include "i2c.h" +#include "lcd.h" #include "queue_policies.h" #include "registers.h" #include "task.h" +#include "timer.h" #include "usart-stm32f0.h" #include "usart_tx_dma.h" #include "usart_rx_dma.h" #include "usb_gpio.h" #include "usb-stream.h" #include "util.h" -#include "usb_mux.h" -#include "usb_charge.h" -#include "usb_common.h" -#include "usb_pd_tcpm.h" -#include "usb_pd.h" -#include "charge_state.h" -#include "tcpm.h" -#include "i2c.h" -#include "power.h" -#include "power_button.h" -#include "printf.h" -#include "timer.h" #define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) #define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) @@ -171,6 +162,11 @@ static void board_init(void) /* Enable TCPC alert interrupts */ gpio_enable_interrupt(GPIO_USB_C0_PD_INT_ODL); + lcd_init(20, 4, 0); + lcd_set_cursor(0, 0); + lcd_print_string("USB-C"); + lcd_set_cursor(0, 1); + lcd_print_string("Sink Advertiser"); queue_init(&loopback_queue); queue_init(&usart_to_usb); queue_init(&usb_to_usart); diff --git a/board/fusb307bgevb/build.mk b/board/fusb307bgevb/build.mk index ce45995412..1372562107 100644 --- a/board/fusb307bgevb/build.mk +++ b/board/fusb307bgevb/build.mk @@ -10,4 +10,4 @@ CHIP:=stm32 CHIP_FAMILY:=stm32f0 CHIP_VARIANT:=stm32f07x -board-y=board.o +board-y=board.o lcd.o diff --git a/board/fusb307bgevb/lcd.c b/board/fusb307bgevb/lcd.c new file mode 100644 index 0000000000..892888329e --- /dev/null +++ b/board/fusb307bgevb/lcd.c @@ -0,0 +1,166 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * LCD driver for I2C LCD 2004. + */ + +#include "i2c.h" +#include "lcd.h" +#include "timer.h" + +struct lcd_state_info { + uint8_t addr; + uint8_t displayfunction; + uint8_t displaycontrol; + uint8_t backlightval; +}; + +static struct lcd_state_info state = { + .addr = LCD_SLAVE_ADDR, + .backlightval = LCD_BACKLIGHT, + .displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5X8DOTS, +}; + +/************ low level data pushing commands **********/ +/* write either command or data */ +static void expander_write(uint8_t data) +{ + i2c_write8(I2C_PORT_TCPC, LCD_SLAVE_ADDR, 0x00, data | + state.backlightval); +} + +static void pulse_enable(uint8_t data) +{ + expander_write(data | LCD_EN);/* En high */ + usleep(1); /* enable pulse must be >450ns */ + + expander_write(data & ~LCD_EN);/* En low */ + usleep(50); /* commands need > 37us to settle */ +} + +static void write_4bits(uint8_t value) +{ + expander_write(value); + pulse_enable(value); +} + +static void send(uint8_t value, uint8_t mode) +{ + uint8_t highnib = value & 0xf0; + uint8_t lownib = (value << 4) & 0xf0; + + write_4bits(highnib | mode); + write_4bits(lownib | mode); +} + +/*********** mid level commands, for sending data/cmds */ +static void command(uint8_t value) +{ + send(value, 0); +} + +/********** high level commands, for the user! */ +void lcd_clear(void) +{ + command(LCD_CLEAR_DISPLAY);/* clear display, set cursor to zero */ + usleep(2000); /* this command takes a long time! */ +} + +void lcd_set_cursor(uint8_t col, uint8_t row) +{ + int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; + + command(LCD_SET_DDRAMADDR | (col + row_offsets[row])); +} + +void lcd_print_char(char data) +{ + send(data, LCD_RS); +} + +void lcd_print_string(const char *str) +{ + while (*str) + lcd_print_char(*str++); +} + +/* Turn the display on/off (quickly) */ +void lcd_disable_display(void) +{ + state.displaycontrol &= ~LCD_DISPLAY_ON; + command(LCD_DISPLAY_CONTROL | state.displaycontrol); +} +void lcd_enable_display(void) +{ + state.displaycontrol |= LCD_DISPLAY_ON; + command(LCD_DISPLAY_CONTROL | state.displaycontrol); +} + +/* Turn the (optional) backlight off/on */ +void lcd_disable_backlight(void) +{ + state.backlightval = LCD_NO_BACKLIGHT; + expander_write(0); +} + +void lcd_enable_backlight(void) +{ + state.backlightval = LCD_BACKLIGHT; + expander_write(0); +} + +void lcd_init(uint8_t cols, uint8_t rows, uint8_t dotsize) +{ + if (rows > 1) + state.displayfunction |= LCD_2LINE; + + /* for some 1 line displays you can select a 10 pixel high font */ + if ((dotsize != 0) && (rows == 1)) + state.displayfunction |= LCD_5X10DOTS; + + /* 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 + */ + usleep(50); + + /* Now we pull both RS and R/W low to begin commands */ + /* reset expanderand turn backlight off (Bit 8 =1) */ + expander_write(state.backlightval); + usleep(1000); + + /* put the LCD into 4 bit mode + * this is according to the hitachi HD44780 datasheet + * figure 24, pg 46 + * we start in 8bit mode, try to set 4 bit mode + */ + write_4bits(0x03 << 4); + usleep(4500); /* wait min 4.1ms */ + /*second try */ + write_4bits(0x03 << 4); + usleep(4500); /* wait min 4.1ms */ + /* third go! */ + write_4bits(0x03 << 4); + usleep(150); + /* finally, set to 4-bit interface */ + write_4bits(0x02 << 4); + + /* set # lines, font size, etc. */ + command(LCD_FUNCTION_SET | state.displayfunction); + + /* turn the display on with no cursor or blinking default */ + state.displaycontrol = LCD_DISPLAY_ON | LCD_CURSOR_OFF | LCD_BLINK_OFF; + lcd_enable_display(); + + /* clear it off */ + lcd_clear(); + + /* Initialize to default text direction (for roman languages) + * and set the entry mode + */ + command(LCD_ENTRYMODE_SET | LCD_ENTRY_LEFT | LCD_ENTRY_SHIFT_DECREMENT); + + lcd_set_cursor(0, 0); +} diff --git a/board/fusb307bgevb/lcd.h b/board/fusb307bgevb/lcd.h new file mode 100644 index 0000000000..21b0ee9ce9 --- /dev/null +++ b/board/fusb307bgevb/lcd.h @@ -0,0 +1,69 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * LCD driver for I2C LCD 2004. + */ + +#ifndef __CROS_EC_LCD_H +#define __CROS_EC_LCD_H + +#include "common.h" + +/* commands */ +#define LCD_CLEAR_DISPLAY BIT(0) +#define LCD_RETURN_HOME BIT(1) +#define LCD_ENTRYMODE_SET BIT(2) +#define LCD_DISPLAY_CONTROL BIT(3) +#define LCD_CURSOR_SHIFT BIT(4) +#define LCD_FUNCTION_SET BIT(5) +#define LCD_SET_CGRAMADDR BIT(6) +#define LCD_SET_DDRAMADDR BIT(7) + +/* flags for display entry mode */ +#define LCD_ENTRY_RIGHT 0x00 +#define LCD_ENTRY_LEFT BIT(1) +#define LCD_ENTRY_SHIFT_INCREMENT BIT(0) +#define LCD_ENTRY_SHIFT_DECREMENT 0x00 + +/* flags for display on/off control */ +#define LCD_DISPLAY_ON BIT(2) +#define LCD_DISPLAY_OFF 0x00 +#define LCD_CURSOR_ON BIT(1) +#define LCD_CURSOR_OFF 0x00 +#define LCD_BLINK_ON BIT(0) +#define LCD_BLINK_OFF 0x00 + +/* flags for display/cursor shift */ +#define LCD_DISPLAY_MOVE BIT(3) +#define LCD_CURSOR_MOVE 0x00 +#define LCD_MOVE_RIGHT BIT(2) +#define LCD_MOVE_LEFT 0x00 + +/* flags for function set */ +#define LCD_8BITMODE BIT(4) +#define LCD_4BITMODE 0x00 +#define LCD_2LINE BIT(3) +#define LCD_1LINE 0x00 +#define LCD_5X10DOTS BIT(2) +#define LCD_5X8DOTS 0x00 + +/* flags for backlight control */ +#define LCD_BACKLIGHT BIT(3) +#define LCD_NO_BACKLIGHT 0x00 + +#define LCD_EN BIT(2) /* Enable bit */ +#define LCD_RW BIT(1) /* Read/Write bit */ +#define LCD_RS BIT(0) /* Register select bit */ + +void lcd_init(uint8_t cols, uint8_t rows, uint8_t dotsize); +void lcd_set_cursor(uint8_t col, uint8_t row); +void lcd_set_char(char data); +void lcd_print_string(const char *str); +void lcd_clear(void); +void lcd_enable_display(void); +void lcd_disable_display(void); +void lcd_enable_backlight(void); +void lcd_disable_backlight(void); + +#endif /*__CROS_EC_LCD_H */ |