546 lines
16 KiB
C
546 lines
16 KiB
C
/****************************************************************************
|
|
*
|
|
* Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
*
|
|
* This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics Ltd and MAY NOT
|
|
* be copied by any method or incorporated into another program without
|
|
* the express written consent of Aerospace C.Power. This Information or any portion
|
|
* thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
* is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
* liability for its use in any way and conveys no license or title under
|
|
* any patent or copyright and makes no representation or warranty that this
|
|
* Information is free from patent or copyright infringement.
|
|
*
|
|
* ****************************************************************************/
|
|
#include "os_utils.h"
|
|
#include "os_types.h"
|
|
#include "os_mem.h"
|
|
|
|
#include "iot_i2c_api.h"
|
|
#include "iot_gpio_api.h"
|
|
#include "iot_errno.h"
|
|
#include "iot_lcd.h"
|
|
#include "iot_io_api.h"
|
|
|
|
|
|
/* Whether enable dump display data. */
|
|
#define IOT_LCD_DUMP_DEBUG 1
|
|
|
|
/* Whether key interruption is allowed. */
|
|
#define HT16K23_KEY_INT_ENABLE 0
|
|
|
|
/* The iic config of ht16k23. */
|
|
#define HT16K23_IIC_SLAVE_ADDR 0x73 /* I2C slave device addr. */
|
|
|
|
#define HT16K23_IIC_DISPLAY_RAM_START_ADDR 0 /* iot lcd display ram start addr. */
|
|
#define HT16K23_IIC_KEY_ADDR 0x20 /* iot lcd key addr. */
|
|
|
|
#define HT16K23_IIC_INIT_COMPLETED 1
|
|
#define HT16K23_IIC_INIT_UNCOMPLETED 0
|
|
#define HT16K23_IIC_DEF_PORT 0 /* Port#0. */
|
|
#define HT16K23_IIC_DEF_SPEED 50 /* 50K. */
|
|
#define HT16K23_IIC_DEF_NACK_NUM 1 /* N-ACK number. */
|
|
#define HT16K23_IIC_DEF_GPIO_SCL 28 /* GPIO28. */
|
|
#define HT16K23_IIC_DEF_GPIO_SDA 36 /* GPIO36. */
|
|
|
|
#define HT16K23_IIC_DEF_GPIO_INT 22 /* GPIO22. */
|
|
#define HT16K23_IIC_INT_ADDR 0x30 /* iot lcd int addr. */
|
|
|
|
#if HT16K23_KEY_INT_ENABLE
|
|
/* set LCD to 16 * 8 display mode, int output, int pin level high is valied. */
|
|
#define HT16K23_SET_MODE_CMD 0xA7
|
|
#else
|
|
/* set LCD to 16 * 8 display mode, no INT */
|
|
#define HT16K23_SET_MODE_CMD 0xA1
|
|
#endif
|
|
|
|
/* into normal mode and open the display. */
|
|
#define HT16K23_SET_SYS_CMD_WORK 0x83
|
|
|
|
/* into standby mode. */
|
|
#define HT16K23_SET_SYS_CMD_STANDBY 0x80
|
|
|
|
/* set key scan period to 3 clock period. */
|
|
#define HT16K23_SET_CMD_KEY_SCAN 0xf9
|
|
|
|
/* seg reg operation. */
|
|
typedef struct {
|
|
uint8_t seg_addr; /* start addr of the display ram. */
|
|
display_bitmap seg_data; /* the data that need to display. */
|
|
}lcd_seg_item;
|
|
|
|
typedef struct _iot_lcd_iic_cfg_t
|
|
{
|
|
uint32_t inited; /* IIC initialization completed? 0, not yet
|
|
* 1, done. */
|
|
uint32_t port; /* IIC port number. */
|
|
uint32_t baud; /* IIC baudrate, unit is Kb. */
|
|
uint32_t nack_wait_num; /* wait nack number. */
|
|
uint16_t gpio_scl; /* SCL gpio pin. */
|
|
uint16_t gpio_sda; /* SDA gpio pin. */
|
|
} iot_lcd_iic_cfg_t;
|
|
|
|
static iot_lcd_iic_cfg_t ht16k23_iic_cfg =
|
|
{
|
|
HT16K23_IIC_INIT_UNCOMPLETED, /* IIC initialization uncompleted. */
|
|
HT16K23_IIC_DEF_PORT, /* IIC device port number. */
|
|
HT16K23_IIC_DEF_SPEED, /* Baudrate, unit is Kb. */
|
|
HT16K23_IIC_DEF_NACK_NUM, /* Wait nack number. */
|
|
HT16K23_IIC_DEF_GPIO_SCL, /* SCL gpio pin. */
|
|
HT16K23_IIC_DEF_GPIO_SDA /* SDA gpio pin. */
|
|
};
|
|
|
|
iot_lcd_key_handle_cb key_handle_cb;
|
|
|
|
uint8_t iot_lcd_status = HT16K23_STAT_STANDBY;
|
|
|
|
/* display ram. */
|
|
lcd_seg_item iot_lcd_seg_item_g;
|
|
|
|
#ifdef IOT_LCD_DUMP_DEBUG
|
|
/*
|
|
@brief iot_lcd_dump_display_data() - dump the display data.
|
|
*/
|
|
static void iot_lcd_dump_display_data_inner(uint8_t *display_buf,
|
|
uint32_t line)
|
|
{
|
|
uint8_t *p = display_buf;
|
|
uint32_t i = 0, len = HT16K23_MAX_DISPLAY_RAM_LEN;
|
|
|
|
iot_printf("lcd display data DUMP(%03d):", len);
|
|
|
|
for(; i < len; i++) {
|
|
iot_printf("%02X ", p[i]);
|
|
}
|
|
|
|
iot_printf("\n[dump end.@%04d]\n", line);
|
|
|
|
return;
|
|
}
|
|
#else
|
|
static void iot_lcd_dump_display_data_inner(uint8_t *display_buf,
|
|
uint32_t line)
|
|
{
|
|
(void)display_buf;
|
|
(void)line;
|
|
}
|
|
#endif
|
|
|
|
#define iot_lcd_dump_display_data(buf) \
|
|
iot_lcd_dump_display_data_inner(buf, __LINE__)
|
|
|
|
/*
|
|
@brief iot_lcd_iic_init() - init iic
|
|
return: ERR_OK:success.
|
|
* ERR_FAIL:failed.
|
|
*/
|
|
static uint8_t iot_lcd_iic_init()
|
|
{
|
|
iot_i2c_module_cfg_t iic_cfg;
|
|
|
|
iic_cfg.port = ht16k23_iic_cfg.port;
|
|
iic_cfg.baud = ht16k23_iic_cfg.baud;
|
|
iic_cfg.nack_wait_num = ht16k23_iic_cfg.nack_wait_num;
|
|
iic_cfg.gpio.scl = ht16k23_iic_cfg.gpio_scl;
|
|
iic_cfg.gpio.sda = ht16k23_iic_cfg.gpio_sda;
|
|
|
|
/* iot_gpio_open_as_output can cancel the function bound on the GPIO.
|
|
* This is not necessary if those GPIOs are not multiplex.
|
|
*/
|
|
if ((ERR_OK != iot_gpio_open_as_output(iic_cfg.gpio.scl))
|
|
|| (ERR_OK != iot_gpio_open_as_output(iic_cfg.gpio.sda))) {
|
|
iot_printf("[%s][err] open gpio failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
if (ERR_OK != iot_i2c_module_init(&iic_cfg)) {
|
|
iot_printf("[%s][err] init i2c failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_printf("[%s] init i2c of the LCD ht16k23 successfully!\n", __FUNCTION__);
|
|
ht16k23_iic_cfg.inited = HT16K23_IIC_INIT_COMPLETED;
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/*
|
|
@brief lcd_open() - open lcd, init into normal mode, LCD is 16*8
|
|
return: ERR_OK:success.
|
|
* ERR_FAIL:failed.
|
|
*/
|
|
static uint8_t iot_lcd_open(void)
|
|
{
|
|
uint8_t ret = 0;
|
|
/* set LCD to 16 * 8 display mode, no INT. */
|
|
uint8_t mode_cmd = HT16K23_SET_MODE_CMD;
|
|
|
|
/* into work mode and open the display. */
|
|
uint8_t sys_cmd = HT16K23_SET_SYS_CMD_WORK;
|
|
|
|
/* set key scan period to 3 clock period. */
|
|
uint8_t key_scan_mode = HT16K23_SET_CMD_KEY_SCAN;
|
|
|
|
if(HT16K23_IIC_INIT_COMPLETED != ht16k23_iic_cfg.inited) {
|
|
iot_printf("[%s][err] iot lcd iic not init!\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
ret |= iot_i2c_write(IOT_I2C_PORT_0, HT16K23_IIC_SLAVE_ADDR,
|
|
(char*)&mode_cmd, sizeof(mode_cmd));
|
|
|
|
ret |= iot_i2c_write(IOT_I2C_PORT_0, HT16K23_IIC_SLAVE_ADDR,
|
|
(char*)&key_scan_mode, sizeof(key_scan_mode));
|
|
|
|
ret |= iot_i2c_write(IOT_I2C_PORT_0, HT16K23_IIC_SLAVE_ADDR,
|
|
(char*)&sys_cmd, sizeof(sys_cmd));
|
|
|
|
if(ret != ERR_OK) {
|
|
iot_printf("[%s][err] open lcd failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_printf("[%s] open the LCD ht16k23 successfully!\n", __FUNCTION__);
|
|
iot_lcd_status = HT16K23_STAT_NORMAL;
|
|
return ERR_OK;
|
|
}
|
|
|
|
/*
|
|
@brief lcd_stand_by_set() - set system mode to stand by
|
|
return: ERR_OK:success.
|
|
* ERR_FAIL:failed.
|
|
*/
|
|
uint8_t iot_lcd_set_standby()
|
|
{
|
|
uint8_t sys_cmd = HT16K23_SET_SYS_CMD_STANDBY;
|
|
uint8_t ret = 0;
|
|
|
|
/* read key data before set mode standby. */
|
|
iot_poll_read_key_data();
|
|
/* will set standby fail, so delay 50ms.*/
|
|
os_delay(50);
|
|
ret = iot_i2c_write(IOT_I2C_PORT_0, HT16K23_IIC_SLAVE_ADDR, (char*)&sys_cmd,
|
|
sizeof(sys_cmd));
|
|
if(ret != ERR_OK) {
|
|
iot_printf("[%s][err] set standby failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_printf("[%s] set the LCD ht16k23 into standby mode successfully!\n",
|
|
__FUNCTION__);
|
|
iot_lcd_status = HT16K23_STAT_STANDBY;
|
|
return ERR_OK;
|
|
}
|
|
|
|
/*
|
|
@brief iot_lcd_set_weakup() - set system mode to wakeup
|
|
return: ERR_OK:success.
|
|
* ERR_FAIL:failed.
|
|
*/
|
|
uint8_t iot_lcd_set_weakup()
|
|
{
|
|
uint8_t sys_cmd = HT16K23_SET_SYS_CMD_WORK;
|
|
uint8_t ret = 0;
|
|
|
|
ret = iot_i2c_write(IOT_I2C_PORT_0, HT16K23_IIC_SLAVE_ADDR, (char*)&sys_cmd,
|
|
sizeof(sys_cmd));
|
|
if(ret != ERR_OK) {
|
|
iot_printf("[%s][err] set wakeup failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_printf("[%s] set the LCD ht16k23 into weakup mode successfully!\n",
|
|
__FUNCTION__);
|
|
iot_lcd_status = HT16K23_STAT_NORMAL;
|
|
return ERR_OK;
|
|
}
|
|
|
|
/*
|
|
@brief iot_lcd_get_status() - get lcd work status, normal or standby.
|
|
return: reference HT16K23_STAT_XXX.
|
|
*/
|
|
uint8_t iot_lcd_get_status()
|
|
{
|
|
return iot_lcd_status;
|
|
}
|
|
|
|
/*
|
|
@brief lcd_clear_screen() - clear lcd screen
|
|
return: ERR_OK:success.
|
|
* ERR_FAIL:failed.
|
|
*/
|
|
uint8_t iot_lcd_clear_screen()
|
|
{
|
|
uint8_t ret = 0;
|
|
|
|
iot_lcd_seg_item_g.seg_addr = HT16K23_IIC_DISPLAY_RAM_START_ADDR;
|
|
os_mem_set(iot_lcd_seg_item_g.seg_data.display_data, 0,
|
|
HT16K23_MAX_DISPLAY_RAM_LEN);
|
|
|
|
ret = iot_i2c_write(IOT_I2C_PORT_0, HT16K23_IIC_SLAVE_ADDR,
|
|
(char*)&iot_lcd_seg_item_g, sizeof(iot_lcd_seg_item_g));
|
|
if(ret != ERR_OK) {
|
|
iot_printf("[%s][err] clear lcd failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_printf("[%s] clear screen of the LCD ht16k23 successfully!\n",
|
|
__FUNCTION__);
|
|
return ERR_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief iic_read_bytes() - read datas from reg addr 30H, 20H, 21H, 22H
|
|
*
|
|
* @param addr adress of slave address
|
|
* @param reg addr of read
|
|
* @param data the pointer to read data buffer
|
|
* @param len the number of read data
|
|
*
|
|
* @return 0: read successful
|
|
* @return other: read failed
|
|
*
|
|
*/
|
|
static uint8_t iot_lcd_iic_read_bytes(uint8_t reg_addr, uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t ret = 0;
|
|
uint8_t addr = reg_addr;
|
|
if((NULL == data) || (len == 0)) {
|
|
iot_printf("[%s][err] invalid params func.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
if(HT16K23_IIC_INIT_COMPLETED != ht16k23_iic_cfg.inited) {
|
|
iot_printf("[%s][err] not init the i2c\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
ret = iot_i2c_write(IOT_I2C_PORT_0, HT16K23_IIC_SLAVE_ADDR, (char*)&addr, 1);
|
|
ret |= iot_i2c_read(IOT_I2C_PORT_0, HT16K23_IIC_SLAVE_ADDR, (char*)data, len);
|
|
if(ret != ERR_OK) {
|
|
iot_printf("[%s][err] i2c wirte|read failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/*
|
|
@brief iot_lcd_get_display_status() - query display status.
|
|
@param: display_buf the buffer that save display ram data.
|
|
@param: buf_len the length of buf.
|
|
return: ERR_OK:success.
|
|
* ERR_FAIL:failed.
|
|
*/
|
|
uint8_t iot_lcd_get_display_data(display_bitmap *display_buf)
|
|
{
|
|
if(NULL == display_buf) {
|
|
iot_printf("[%s][err]invaled params!\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
if(HT16K23_STAT_STANDBY == iot_lcd_status) {
|
|
iot_printf("[%s][err] LCD standby, not support operate the lcd ram!\n",
|
|
__FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_lcd_seg_item_g.seg_addr = HT16K23_IIC_DISPLAY_RAM_START_ADDR;
|
|
os_mem_set(iot_lcd_seg_item_g.seg_data.display_data, 0,
|
|
HT16K23_MAX_DISPLAY_RAM_LEN);
|
|
if(ERR_OK != iot_lcd_iic_read_bytes(iot_lcd_seg_item_g.seg_addr,
|
|
iot_lcd_seg_item_g.seg_data.display_data, HT16K23_MAX_DISPLAY_RAM_LEN))
|
|
{
|
|
iot_printf("[%s][err] read i2c failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_lcd_dump_display_data(iot_lcd_seg_item_g.seg_data.display_data);
|
|
|
|
os_mem_cpy(display_buf->display_data,
|
|
iot_lcd_seg_item_g.seg_data.display_data, HT16K23_MAX_DISPLAY_RAM_LEN);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/*
|
|
@brief iot_lcd_set_display_data() - set display data.
|
|
@param: display_data data that set to the display memory.
|
|
@param: data_len the length of the display data.
|
|
return: ERR_OK:success.
|
|
* ERR_FAIL:failed.
|
|
*/
|
|
uint8_t iot_lcd_set_display_data(display_bitmap *display_data)
|
|
{
|
|
if(NULL == display_data) {
|
|
iot_printf("[%s][err] invaled params!\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
if(HT16K23_STAT_STANDBY == iot_lcd_status) {
|
|
iot_printf("[%s][err] LCD standby, not support operate the lcd ram!\n",
|
|
__FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_lcd_seg_item_g.seg_addr = HT16K23_IIC_DISPLAY_RAM_START_ADDR;
|
|
os_mem_set(iot_lcd_seg_item_g.seg_data.display_data,
|
|
0, HT16K23_MAX_DISPLAY_RAM_LEN);
|
|
os_mem_cpy(iot_lcd_seg_item_g.seg_data.display_data,
|
|
display_data->display_data, HT16K23_MAX_DISPLAY_RAM_LEN);
|
|
|
|
iot_lcd_dump_display_data(iot_lcd_seg_item_g.seg_data.display_data);
|
|
|
|
if(ERR_OK !=iot_i2c_write(IOT_I2C_PORT_0, HT16K23_IIC_SLAVE_ADDR,
|
|
(char*)&iot_lcd_seg_item_g, HT16K23_MAX_DISPLAY_RAM_LEN + 1)) {
|
|
iot_printf("[%s][err] write i2c failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
return ERR_OK;
|
|
|
|
}
|
|
|
|
#if HT16K23_KEY_INT_ENABLE
|
|
|
|
/*
|
|
@brief iot_lcd_key_handle_register() - register lcd key handle callback func.
|
|
@param: keycb the lcd key handle callback func.
|
|
return: ERR_OK:success.
|
|
* ERR_FAIL:failed.
|
|
*/
|
|
uint8_t iot_lcd_key_handle_register(iot_lcd_key_handle_cb keycb)
|
|
{
|
|
if(NULL != keycb) {
|
|
key_handle_cb = keycb;
|
|
return ERR_OK;
|
|
}
|
|
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
/*
|
|
@brief get_int_status() - get interrupt status
|
|
return: int_satus.
|
|
* ERR_FAIL:failed.
|
|
*/
|
|
static uint8_t iot_lcd_get_int_status()
|
|
{
|
|
uint8_t int_reg_addr = HT16K23_IIC_INT_ADDR;
|
|
uint8_t int_satus = 0;
|
|
|
|
if(ERR_OK != iot_lcd_iic_read_bytes(int_reg_addr, &int_satus, 1)) {
|
|
iot_printf("[%s][err] read i2c failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
return int_satus;
|
|
}
|
|
|
|
/* isr */
|
|
static void key_handler_isr(int arg)
|
|
{
|
|
uint8_t key_data = 0;
|
|
int int_status = 0;
|
|
(void)arg;
|
|
|
|
int_status = iot_lcd_get_int_status();
|
|
key_data = iot_poll_read_key_data();
|
|
iot_printf("[%s] int_status:%d, key_data:%d\n", int_status, key_data);
|
|
|
|
if(NULL != key_handle_cb) {
|
|
key_handle_cb(key_data);
|
|
}
|
|
|
|
/* Prevent interrupted scanning too fast. */
|
|
os_delay(100);
|
|
iot_gpio_interrupt_enable(HT16K23_IIC_DEF_GPIO_INT, 1);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
@brief iot_lcd_int_init() - init interrupt
|
|
return: ERR_OK:success.
|
|
* ERR_FAIL:failed.
|
|
*/
|
|
uint8_t iot_lcd_int_init()
|
|
{
|
|
uint8_t ret = 0;
|
|
|
|
iot_gpio_set_pull_mode(HT16K23_IIC_DEF_GPIO_INT, GPIO_PULL_DOWN);
|
|
ret |= iot_gpio_open_as_interrupt(HT16K23_IIC_DEF_GPIO_INT);
|
|
ret |= iot_gpio_interrupt_config(HT16K23_IIC_DEF_GPIO_INT, GPIO_INT_LEVEL_HIGH,
|
|
(iot_gpio_isr_func)key_handler_isr, 0, GPIO_INT_FUNC_ENABLE_AUTOSTOP);
|
|
ret |= iot_gpio_interrupt_enable(HT16K23_IIC_DEF_GPIO_INT, 1);
|
|
if(ret != ERR_OK) {
|
|
iot_printf("[%s][err] int init failed!\n", __FUNCTION__);
|
|
iot_gpio_close(HT16K23_IIC_DEF_GPIO_INT);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
iot_printf("[%s] init the LCD ht16k23 successfully!\n", __FUNCTION__);
|
|
return ERR_OK;
|
|
}
|
|
|
|
#else
|
|
|
|
uint8_t iot_lcd_key_handle_register(iot_lcd_key_handle_cb keycb)
|
|
{
|
|
(void)keycb;
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
uint8_t iot_lcd_int_init()
|
|
{
|
|
return ERR_OK;
|
|
}
|
|
|
|
#endif
|
|
|
|
/*
|
|
@brief iot_poll_read_key_data() - poll read ram key data
|
|
If enable interrupt,when interrupt triggered will call it.
|
|
otherwise upper-app polling call is required
|
|
* @return which key was pressed.
|
|
* ERR_FAIL: something error.
|
|
*/
|
|
uint8_t iot_poll_read_key_data()
|
|
{
|
|
/* key reg start addr. */
|
|
uint8_t addr = HT16K23_IIC_KEY_ADDR;
|
|
/* Three registers need to be read to empty them. */
|
|
uint8_t key_data[3];
|
|
|
|
os_mem_set(key_data, 0, sizeof(key_data));
|
|
if(ERR_OK != iot_lcd_iic_read_bytes(addr, key_data, sizeof(key_data))) {
|
|
iot_printf("[%s][err] read i2c failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
/* only data[0] is valied. */
|
|
return key_data[0];
|
|
}
|
|
|
|
/*
|
|
@brief lcd_init() - lcd init, int init, open lcd, clear screen.
|
|
@param: iot_lcd_type lcd type..
|
|
return: ERR_OK:success.
|
|
* ERR_FAIL:failed.
|
|
*/
|
|
uint8_t iot_lcd_init()
|
|
{
|
|
uint8_t ret = ERR_OK;
|
|
|
|
ret |= iot_lcd_iic_init();
|
|
ret |= iot_lcd_open();
|
|
ret |= iot_lcd_clear_screen();
|
|
if(ret != ERR_OK) {
|
|
iot_printf("[%s][err] iot lcd init failed.\n", __FUNCTION__);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|