summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYun-chieh, Lee <lyunjie@google.com>2020-09-10 21:57:00 +0800
committerCommit Bot <commit-bot@chromium.org>2020-09-21 17:34:15 +0000
commitdb78abe0160364bf075e1595850407dfdd182297 (patch)
tree4a6a28dfbc18485285b90eca5a2be49e7a5b47b0
parentb7dc125ebb97fcc87ff606696f4fb5315b767c45 (diff)
downloadchrome-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.c20
-rw-r--r--board/fusb307bgevb/build.mk2
-rw-r--r--board/fusb307bgevb/lcd.c166
-rw-r--r--board/fusb307bgevb/lcd.h69
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 */