diff --git a/.gitmodules b/.gitmodules index dcc3b8dd1..59ee5c1d2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,12 +7,12 @@ [submodule "Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-riscv64-board/kendryte-sdk/kendryte-sdk-source"] path = Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-riscv64-board/kendryte-sdk/kendryte-sdk-source url = https://code.gitlink.org.cn/chunyexixiaoyu/kendryte-sdk-source.git -[submodule "Ubiquitous/Nuttx_Fusion_XiUOS/apps"] - path = Ubiquitous/Nuttx_Fusion_XiUOS/apps - url = https://code.gitlink.org.cn/wgzAIIT/incubator-nuttx-apps.git -[submodule "Ubiquitous/Nuttx_Fusion_XiUOS/nuttx"] - path = Ubiquitous/Nuttx_Fusion_XiUOS/nuttx - url = https://code.gitlink.org.cn/wgzAIIT/incubator-nuttx.git [submodule "Ubiquitous/XiZi/fs/lwext4/lwext4_submodule"] path = Ubiquitous/XiZi/fs/lwext4/lwext4_submodule url = https://gitlink.org.cn/xuos/lwext4_filesystem_support_XiUOS.git +[submodule "Ubiquitous/Nuttx_Fusion_XiUOS/nuttx"] + path = Ubiquitous/Nuttx_Fusion_XiUOS/nuttx + url = https://code.gitlink.org.cn/wgzAIIT/incubator-nuttx.git +[submodule "Ubiquitous/Nuttx_Fusion_XiUOS/apps"] + path = Ubiquitous/Nuttx_Fusion_XiUOS/apps + url = https://code.gitlink.org.cn/wgzAIIT/incubator-nuttx-apps.git diff --git a/APP_Framework/Applications/lv_app/lv_demo.c b/APP_Framework/Applications/lv_app/lv_demo.c index 13536434d..93a4e3d0f 100644 --- a/APP_Framework/Applications/lv_app/lv_demo.c +++ b/APP_Framework/Applications/lv_app/lv_demo.c @@ -1,12 +1,3 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-10-17 Meco Man First version - */ #include #include #include "lv_demo_calendar.h" @@ -22,11 +13,11 @@ extern void lv_example_aoteman(void); void* lvgl_thread(void *parameter) { /* display demo; you may replace with your LVGL application at here */ - // lv_demo_calendar(); + lv_demo_calendar(); // lv_example_img_1(); // lv_example_chart_2(); // lv_example_line_1(); - lv_example_aoteman(); + // lv_example_aoteman(); /* handle the tasks of LVGL */ while(1) { diff --git a/APP_Framework/Applications/lv_app/lv_demo_calendar.c b/APP_Framework/Applications/lv_app/lv_demo_calendar.c index 3b4cabb68..2d354fd28 100644 --- a/APP_Framework/Applications/lv_app/lv_demo_calendar.c +++ b/APP_Framework/Applications/lv_app/lv_demo_calendar.c @@ -18,7 +18,7 @@ static void event_handler(lv_event_t * e) void lv_demo_calendar(void) { lv_obj_t * calendar = lv_calendar_create(lv_scr_act()); - lv_obj_set_size(calendar, 320, 240); + lv_obj_set_size(calendar, 480, 272); lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 0); lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL); diff --git a/APP_Framework/Framework/connection/4g/adapter_4g.c b/APP_Framework/Framework/connection/4g/adapter_4g.c index 9877e10b2..80b76b682 100644 --- a/APP_Framework/Framework/connection/4g/adapter_4g.c +++ b/APP_Framework/Framework/connection/4g/adapter_4g.c @@ -89,7 +89,7 @@ int Adapter4GTest(void) struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_4G_NAME); #ifdef ADAPTER_EC200T - //Using Hang Xiao server to test 4G Socket connection + /* Using Public TCP server to test 4G Socket connection */ uint8 server_addr[64] = "120.76.100.197"; uint8 server_port[64] = "10002"; diff --git a/APP_Framework/Framework/connection/bluetooth/Make.defs b/APP_Framework/Framework/connection/bluetooth/Make.defs new file mode 100644 index 000000000..630d914f0 --- /dev/null +++ b/APP_Framework/Framework/connection/bluetooth/Make.defs @@ -0,0 +1,7 @@ +############################################################################ +# APP_Framework/Framework/connection/bluetooth/Make.defs +############################################################################ +ifneq ($(CONFIG_CONNECTION_ADAPTER_BLUETOOTH),) +CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/connection/bluetooth +endif +include $(wildcard $(APPDIR)/../../../APP_Framework/Framework/connection/bluetooth/*/Make.defs) diff --git a/APP_Framework/Framework/connection/bluetooth/Makefile b/APP_Framework/Framework/connection/bluetooth/Makefile index bb367019f..bc7d736cd 100644 --- a/APP_Framework/Framework/connection/bluetooth/Makefile +++ b/APP_Framework/Framework/connection/bluetooth/Makefile @@ -1,7 +1,17 @@ -SRC_FILES := adapter_bluetooth.c +include $(KERNEL_ROOT)/.config +ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) + include $(APPDIR)/Make.defs + CSRCS += adapter_bluetooth.c + include $(APPDIR)/Application.mk -ifeq ($(CONFIG_ADAPTER_HC08),y) - SRC_DIR += hc08 endif -include $(KERNEL_ROOT)/compiler.mk +ifeq ($(CONFIG_ADD_XIZI_FETURES),y) + SRC_FILES := adapter_bluetooth.c + + ifeq ($(CONFIG_ADAPTER_HC08),y) + SRC_DIR += hc08 + endif + + include $(KERNEL_ROOT)/compiler.mk +endif diff --git a/APP_Framework/Framework/connection/bluetooth/hc08/Kconfig b/APP_Framework/Framework/connection/bluetooth/hc08/Kconfig index 8b17e83dd..6e1f3f0fe 100644 --- a/APP_Framework/Framework/connection/bluetooth/hc08/Kconfig +++ b/APP_Framework/Framework/connection/bluetooth/hc08/Kconfig @@ -33,6 +33,25 @@ endif if ADD_NUTTX_FETURES + config ADAPTER_HC08_WORK_ROLE + string "HC08 work role M(MASTER) or S(SLAVER)" + default "M" + + config ADAPTER_HC08_DRIVER_EXTUART + bool "Using extra uart to support bluetooth" + default y + + config ADAPTER_HC08_DRIVER + string "HC08 device uart driver path" + default "/dev/ttyS2" + depends on !ADAPTER_HC08_DRIVER_EXTUART + + if ADAPTER_HC08_DRIVER_EXTUART + config ADAPTER_HC08_DRIVER + string "HC08 device extra uart driver path" + default "/dev/extuart_dev2" + endif + endif if ADD_RTTHREAD_FETURES diff --git a/APP_Framework/Framework/connection/bluetooth/hc08/Make.defs b/APP_Framework/Framework/connection/bluetooth/hc08/Make.defs new file mode 100644 index 000000000..b66a351fb --- /dev/null +++ b/APP_Framework/Framework/connection/bluetooth/hc08/Make.defs @@ -0,0 +1,6 @@ +############################################################################ +# APP_Framework/Framework/connection/bluetooth/hc08/Make.defs +############################################################################ +ifneq ($(CONFIG_ADAPTER_HC08),) +CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/connection/bluetooth/hc08 +endif diff --git a/APP_Framework/Framework/connection/bluetooth/hc08/Makefile b/APP_Framework/Framework/connection/bluetooth/hc08/Makefile index 60932ced2..e437a114f 100644 --- a/APP_Framework/Framework/connection/bluetooth/hc08/Makefile +++ b/APP_Framework/Framework/connection/bluetooth/hc08/Makefile @@ -1,3 +1,13 @@ -SRC_FILES := hc08.c +include $(KERNEL_ROOT)/.config +ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) + include $(APPDIR)/Make.defs + CSRCS += hc08.c + include $(APPDIR)/Application.mk -include $(KERNEL_ROOT)/compiler.mk +endif + +ifeq ($(CONFIG_ADD_XIZI_FETURES),y) + SRC_FILES := hc08.c + include $(KERNEL_ROOT)/compiler.mk + +endif diff --git a/APP_Framework/Framework/connection/bluetooth/hc08/hc08.c b/APP_Framework/Framework/connection/bluetooth/hc08/hc08.c index be7ba9e2a..f261d3ba5 100644 --- a/APP_Framework/Framework/connection/bluetooth/hc08/hc08.c +++ b/APP_Framework/Framework/connection/bluetooth/hc08/hc08.c @@ -21,20 +21,20 @@ #include #include -#define HC08_DETECT_CMD "AT" -#define HC08_DEFAULT_CMD "AT+DEFAULT" -#define HC08_RESET_CMD "AT+RESET" -#define HC08_CLEAR_CMD "AT+CLEAR" -#define HC08_GET_DEVICE_INFO "AT+RX" +#define HC08_DETECT_CMD "AT" +#define HC08_DEFAULT_CMD "AT+DEFAULT" +#define HC08_RESET_CMD "AT+RESET" +#define HC08_CLEAR_CMD "AT+CLEAR" +#define HC08_GET_DEVICE_INFO "AT+RX" -#define HC08_GET_BAUDRATE_CMD "AT+BAUD=?" -#define HC08_SET_BAUDRATE_CMD "AT+BAUD=%u" -#define HC08_GET_CONNECTABLE "AT+CONT=?" -#define HC08_SET_CONNECTABLE "AT+CONT=%s" -#define HC08_GET_ROLE_CMD "AT+ROLE=?" -#define HC08_SET_ROLE_CMD "AT+ROLE=%s" -#define HC08_GET_ADDR_CMD "AT+ADDR=?" -#define HC08_SET_ADDR_CMD "AT+ADDR=%s" +#define HC08_GET_BAUDRATE_CMD "AT+BAUD=?" +#define HC08_SET_BAUDRATE_CMD "AT+BAUD=%u" +#define HC08_GET_CONNECTABLE "AT+CONT=?" +#define HC08_SET_CONNECTABLE "AT+CONT=%s" +#define HC08_GET_ROLE_CMD "AT+ROLE=?" +#define HC08_SET_ROLE_CMD "AT+ROLE=%s" +#define HC08_GET_ADDR_CMD "AT+ADDR=?" +#define HC08_SET_ADDR_CMD "AT+ADDR=%s" #define HC08_GET_NAME_CMD "AT+NAME=%s" #define HC08_SET_NAME_CMD "AT+NAME=?" #define HC08_GET_LUUID_CMD "AT+LUUID=?" @@ -44,10 +44,10 @@ #define HC08_GET_TUUID_CMD "AT+TUUID=?" #define HC08_SET_TUUID_CMD "AT+TUUID=%u" -#define HC08_OK_RESP "OK" +#define HC08_OK_RESP "OK" -#define HC08_CMD_STR_DEFAULT_SIZE 64 -#define HC08_RESP_DEFAULT_SIZE 64 +#define HC08_CMD_STR_DEFAULT_SIZE 64 +#define HC08_RESP_DEFAULT_SIZE 64 enum Hc08AtCmd { @@ -275,6 +275,41 @@ static int Hc08Close(struct Adapter *adapter) return 0; } +#ifdef ADD_NUTTX_FETURES +static int Hc08Ioctl(struct Adapter *adapter, int cmd, void *args) +{ + if (OPE_INT != cmd) { + printf("Hc08Ioctl only support OPE_INT, do not support %d\n", cmd); + return -1; + } + + uint32_t baud_rate = *((uint32_t *)args); + + PrivIoctl(adapter->fd, OPE_INT, baud_rate); + + //Step1 : detect hc08 serial function + if (Hc08AtConfigure(adapter->agent, HC08_AT_CMD_DETECT, NULL, NULL) < 0) { + return -1; + } + + //Step2 : set hc08 device serial baud, hc08_set_baud send "AT+BAUD=%s" + if (Hc08AtConfigure(adapter->agent, HC08_AT_CMD_SET_BAUDRATE, args, NULL) < 0) { + return -1; + } + + PrivTaskDelay(200); + + //Step3 : show hc08 device info, hc08_get send "AT+RX" response device info + char device_info[HC08_RESP_DEFAULT_SIZE * 2] = {0}; + if (Hc08AtConfigure(adapter->agent, HC08_AT_CMD_GET_DEVICE_INFO, NULL, device_info) < 0) { + return -1; + } + + ADAPTER_DEBUG("Hc08 ioctl done\n"); + + return 0; +} +#else static int Hc08Ioctl(struct Adapter *adapter, int cmd, void *args) { if (OPE_INT != cmd) { @@ -346,6 +381,7 @@ static int Hc08Ioctl(struct Adapter *adapter, int cmd, void *args) return 0; } +#endif static int Hc08SetAddr(struct Adapter *adapter, const char *ip, const char *gateway, const char *netmask) { @@ -411,7 +447,7 @@ static int Hc08Send(struct Adapter *adapter, const void *buf, size_t len) EntmSend(adapter->agent, (const char *)buf, len); } else { printf("Hc08Send can not find agent\n"); - } + } return 0; } @@ -421,7 +457,7 @@ static int Hc08Recv(struct Adapter *adapter, void *buf, size_t len) return EntmRecv(adapter->agent, (char *)buf, len, 40); } else { printf("Hc08Recv can not find agent\n"); - } + } return -1; } diff --git a/APP_Framework/Framework/connection/lora/Make.defs b/APP_Framework/Framework/connection/lora/Make.defs index 59f79c833..342ad9396 100644 --- a/APP_Framework/Framework/connection/lora/Make.defs +++ b/APP_Framework/Framework/connection/lora/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # APP_Framework/Framework/connection/lora/Make.defs ############################################################################ -ifneq ($(CONFIG_ADAPTER_SX1278),) +ifneq ($(CONFIG_CONNECTION_ADAPTER_LORA),) CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/connection/lora endif include $(wildcard $(APPDIR)/../../../APP_Framework/Framework/connection/lora/*/Make.defs) diff --git a/APP_Framework/Framework/connection/lora/adapter_lora.c b/APP_Framework/Framework/connection/lora/adapter_lora.c index 5a5f268e4..0051bb487 100644 --- a/APP_Framework/Framework/connection/lora/adapter_lora.c +++ b/APP_Framework/Framework/connection/lora/adapter_lora.c @@ -50,6 +50,8 @@ extern AdapterProductInfoType E220Attach(struct Adapter *adapter); #define ADAPTER_LORA_RECEIVE_ERROR_CNT 1 +#define DEFAULT_SEM_TIMEOUT 10 + //need to change status if the lora client wants to quit the net when timeout or a certain event //eg.can also use sem to trigger quit function static int g_adapter_lora_quit_flag = 0; @@ -453,7 +455,10 @@ static int LoraClientDataAnalyze(struct Adapter *adapter, void *send_buf, int le int ret = 0; uint8_t client_id = adapter->net_role_id; - ret = PrivSemaphoreObtainWait(&adapter->sem, NULL); + struct timespec abstime; + abstime.tv_sec = DEFAULT_SEM_TIMEOUT; + + ret = PrivSemaphoreObtainWait(&adapter->sem, &abstime); if (0 == ret) { //only handle this client_id information from gateway if ((client_recv_data_format[client_id - 1].client_id == adapter->net_role_id) && @@ -681,6 +686,8 @@ static void *LoraReceiveTask(void *parameter) void LoraGatewayProcess(struct Adapter *lora_adapter, struct LoraGatewayParam *gateway) { int i, ret = 0; + struct timespec abstime; + abstime.tv_sec = DEFAULT_SEM_TIMEOUT; #ifdef GATEWAY_CMD_MODE for (i = 0; i < gateway->client_num; i ++) { @@ -692,7 +699,7 @@ void LoraGatewayProcess(struct Adapter *lora_adapter, struct LoraGatewayParam *g continue; } - ret = PrivSemaphoreObtainWait(&gateway_recv_data_sem, NULL); + ret = PrivSemaphoreObtainWait(&gateway_recv_data_sem, &abstime); if (0 == ret) { printf("LoraGatewayProcess receive client %d data done\n", gateway->client_id[i]); } diff --git a/APP_Framework/Framework/connection/lora/e220/Kconfig b/APP_Framework/Framework/connection/lora/e220/Kconfig index 050a8ea9b..b03aee0cc 100644 --- a/APP_Framework/Framework/connection/lora/e220/Kconfig +++ b/APP_Framework/Framework/connection/lora/e220/Kconfig @@ -37,6 +37,30 @@ endif if ADD_NUTTX_FETURES + config ADAPTER_E220_M0_PATH + string "E220 M0 pin device" + default "/dev/gpout0" + + config ADAPTER_E220_M1_PATH + string "E220 M1 pin device" + default "/dev/gpout1" + + config ADAPTER_E220_DRIVER_EXTUART + bool "Using extra uart to support lora" + default y + + config ADAPTER_E220_DRIVER + string "E220 device uart driver path" + default "/dev/ttyS3" + depends on !ADAPTER_E220_DRIVER_EXTUART + + if ADAPTER_E220_DRIVER_EXTUART + config ADAPTER_E220_DRIVER + string "E220 device extra uart driver path" + default "/dev/extuart_dev3" + + endif + endif if ADD_RTTHREAD_FETURES diff --git a/APP_Framework/Framework/connection/lora/e220/Make.defs b/APP_Framework/Framework/connection/lora/e220/Make.defs new file mode 100644 index 000000000..f6847eeda --- /dev/null +++ b/APP_Framework/Framework/connection/lora/e220/Make.defs @@ -0,0 +1,6 @@ +############################################################################ +# APP_Framework/Framework/connection/lora/e220/Make.defs +############################################################################ +ifneq ($(CONFIG_ADAPTER_E220),) +CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/connection/lora/e220 +endif diff --git a/APP_Framework/Framework/connection/lora/e220/Makefile b/APP_Framework/Framework/connection/lora/e220/Makefile index 734805688..71d5454a0 100644 --- a/APP_Framework/Framework/connection/lora/e220/Makefile +++ b/APP_Framework/Framework/connection/lora/e220/Makefile @@ -1,3 +1,13 @@ -SRC_FILES := e220.c +include $(KERNEL_ROOT)/.config +ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) + include $(APPDIR)/Make.defs + CSRCS += e220.c + include $(APPDIR)/Application.mk -include $(KERNEL_ROOT)/compiler.mk +endif + +ifeq ($(CONFIG_ADD_XIZI_FETURES),y) + SRC_FILES := e220.c + include $(KERNEL_ROOT)/compiler.mk + +endif \ No newline at end of file diff --git a/APP_Framework/Framework/connection/lora/e220/e220.c b/APP_Framework/Framework/connection/lora/e220/e220.c index 0d9d530ea..880ba9e48 100644 --- a/APP_Framework/Framework/connection/lora/e220/e220.c +++ b/APP_Framework/Framework/connection/lora/e220/e220.c @@ -21,7 +21,7 @@ #include #define E220_GATEWAY_ADDRESS 0xFFFF -#define E220_CHANNEL 0x04 +#define E220_CHANNEL 0x05 #ifdef AS_LORA_GATEWAY_ROLE #define E220_ADDRESS E220_GATEWAY_ADDRESS @@ -46,6 +46,60 @@ enum E220LoraMode * @param mode Lora working mode * @return NULL */ +#ifdef ADD_NUTTX_FETURES +static void E220LoraModeConfig(enum E220LoraMode mode) +{ + int m0_fd, m1_fd; + + //delay 1s , wait AUX ready + PrivTaskDelay(1000); + m0_fd = PrivOpen(ADAPTER_E220_M0_PATH, O_RDWR); + if (m0_fd < 0) { + printf("open %s error\n", ADAPTER_E220_M0_PATH); + return; + } + + m1_fd = PrivOpen(ADAPTER_E220_M1_PATH, O_RDWR); + if (m1_fd < 0) { + printf("open %s error\n", ADAPTER_E220_M1_PATH); + return; + } + + //Both M0 and M1 GPIO are outputs mode, set M0 and M1 high or low + switch (mode) + { + case DATA_TRANSFER_MODE: + PrivIoctl(m1_fd, GPIOC_WRITE, (unsigned long)GPIO_LOW); + PrivIoctl(m0_fd, GPIOC_WRITE, (unsigned long)GPIO_LOW); + break; + + case WOR_SEND_MODE: + PrivIoctl(m1_fd, GPIOC_WRITE, (unsigned long)GPIO_LOW); + PrivIoctl(m0_fd, GPIOC_WRITE, (unsigned long)GPIO_HIGH); + break; + + case WOR_RECEIVE_MODE: + PrivIoctl(m1_fd, GPIOC_WRITE, (unsigned long)GPIO_HIGH); + + PrivIoctl(m0_fd, GPIOC_WRITE,(unsigned long)GPIO_LOW); + break; + + case CONFIGURE_MODE_MODE: + PrivIoctl(m1_fd, GPIOC_WRITE, (unsigned long)GPIO_HIGH); + PrivIoctl(m0_fd, GPIOC_WRITE, (unsigned long)GPIO_HIGH); + break; + + default: + break; + } + + PrivClose(m0_fd); + PrivClose(m1_fd); + + //delay 20ms , wait mode switch done + PrivTaskDelay(20); +} +#else static void E220LoraModeConfig(enum E220LoraMode mode) { //delay 1s , wait AUX ready @@ -126,6 +180,7 @@ static void E220LoraModeConfig(enum E220LoraMode mode) //delay 20ms , wait mode switch done PrivTaskDelay(20); } +#endif /** * @description: Switch baud rate to register bit @@ -263,6 +318,25 @@ static int E220GetRegisterParam(uint8 *buf) * @param adapter - Lora device pointer * @return success: 0, failure: -1 */ +#ifdef ADD_NUTTX_FETURES +static int E220Open(struct Adapter *adapter) +{ + /*step1: open e220 uart port*/ + adapter->fd = PrivOpen(ADAPTER_E220_DRIVER, O_RDWR); + if (adapter->fd < 0) { + printf("E220Open get uart %s fd error\n", ADAPTER_E220_DRIVER); + return -1; + } + + PrivIoctl(adapter->fd, OPE_INT, (unsigned long)BAUD_RATE_9600); + E220SetRegisterParam(adapter, E220_ADDRESS, E220_CHANNEL, E220_UART_BAUD_RATE); + PrivIoctl(adapter->fd, OPE_INT, (unsigned long)E220_UART_BAUD_RATE); + + ADAPTER_DEBUG("E220Open done\n"); + + return 0; +} +#else static int E220Open(struct Adapter *adapter) { /*step1: open e220 uart port*/ @@ -316,6 +390,7 @@ static int E220Open(struct Adapter *adapter) return 0; } +#endif /** * @description: Close E220 uart function @@ -520,6 +595,7 @@ static void LoraRead(void *parameter) } } +#ifdef ADD_XIZI_FETURES static void LoraTest(void) { int ret; @@ -554,3 +630,40 @@ static void LoraSend(int argc, char *argv[]) } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), LoraSend, LoraSend, lora send message); +#endif + +#ifdef ADD_NUTTX_FETURES +void E220LoraReceive(void) +{ + int ret; + pthread_t thread; + pthread_attr_t attr = PTHREAD_ATTR_INITIALIZER; + attr.priority = 80; + attr.stacksize = 2048; + + LoraOpen(); + + ret = PrivTaskCreate(&thread, &attr, (void*)LoraRead, NULL); + if (ret < 0) { + printf("task lora read create failed, status=%d\n", ret); + return; + } +} +void E220LoraSend(int argc, char *argv[]) +{ + struct Adapter *adapter = AdapterDeviceFindByName(ADAPTER_LORA_NAME); + if (NULL == adapter) { + printf("LoraRead find lora adapter error\n"); + return; + } + + if (argc == 2) { + char Msg[256] = {0}; + strncpy(Msg, argv[1], 256); + + E220Open(adapter); + E220Send(adapter, Msg, strlen(Msg)); + E220Close(adapter); + } +} +#endif diff --git a/APP_Framework/Framework/connection/wifi/Make.defs b/APP_Framework/Framework/connection/wifi/Make.defs new file mode 100755 index 000000000..cf51e4a1d --- /dev/null +++ b/APP_Framework/Framework/connection/wifi/Make.defs @@ -0,0 +1,7 @@ +############################################################################ +# APP_Framework/Framework/connection/zigbee/Make.defs +############################################################################ +ifneq ($(CONFIG_CONNECTION_ADAPTER_WIFI),) +CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/connection/wifi +endif +include $(wildcard $(APPDIR)/../../../APP_Framework/Framework/connection/wifi/*/Make.defs) diff --git a/APP_Framework/Framework/connection/wifi/Makefile b/APP_Framework/Framework/connection/wifi/Makefile index 2930fd977..cfa6cac9f 100644 --- a/APP_Framework/Framework/connection/wifi/Makefile +++ b/APP_Framework/Framework/connection/wifi/Makefile @@ -1,3 +1,12 @@ +include $(KERNEL_ROOT)/.config +ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) + include $(APPDIR)/Make.defs + CSRCS += adapter_wifi.c + include $(APPDIR)/Application.mk + +endif + +ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_FILES := adapter_wifi.c ifeq ($(CONFIG_ADAPTER_HFA21_WIFI),y) @@ -9,3 +18,4 @@ ifeq ($(CONFIG_ADAPTER_ESP07S_WIFI),y) endif include $(KERNEL_ROOT)/compiler.mk +endif diff --git a/APP_Framework/Framework/connection/wifi/adapter_wifi.c b/APP_Framework/Framework/connection/wifi/adapter_wifi.c index 039f96598..fe5461d71 100644 --- a/APP_Framework/Framework/connection/wifi/adapter_wifi.c +++ b/APP_Framework/Framework/connection/wifi/adapter_wifi.c @@ -100,6 +100,7 @@ int AdapterWifiInit(void) } /******************wifi TEST*********************/ +#ifdef ADD_XIZI_FETURES int AdapterWifiTest(void) { char cmd[64]; @@ -107,29 +108,28 @@ int AdapterWifiTest(void) struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME); - #ifdef ADAPTER_HFA21_DRIVER_EXT_PORT static BusType ch438_pin; ch438_pin = PinBusInitGet(); - struct PinParam pin_cfg; - int ret = 0; + struct PinParam pin_cfg; + int ret = 0; - struct BusConfigureInfo configure_info; - configure_info.configure_cmd = OPE_CFG; - configure_info.private_data = (void *)&pin_cfg; + struct BusConfigureInfo configure_info; + configure_info.configure_cmd = OPE_CFG; + configure_info.private_data = (void *)&pin_cfg; pin_cfg.cmd = GPIO_CONFIG_MODE; pin_cfg.pin = 22; pin_cfg.mode = GPIO_CFG_OUTPUT; - ret = BusDrvConfigure(ch438_pin->owner_driver, &configure_info); + ret = BusDrvConfigure(ch438_pin->owner_driver, &configure_info); struct PinStat pin_stat; - struct BusBlockWriteParam write_param; - struct BusBlockReadParam read_param; - write_param.buffer = (void *)&pin_stat; - - pin_stat.val = GPIO_HIGH; + struct BusBlockWriteParam write_param; + struct BusBlockReadParam read_param; + write_param.buffer = (void *)&pin_stat; + + pin_stat.val = GPIO_HIGH; pin_stat.pin = 22; BusDevWriteData(ch438_pin->owner_haldev, &write_param); @@ -155,7 +155,6 @@ int AdapterWifiTest(void) PrivClose(pin_fd); #endif - AdapterDeviceOpen(adapter); // AdapterDeviceControl(adapter, OPE_INT, &baud_rate); @@ -182,8 +181,8 @@ int AdapterWifiTest(void) AdapterDeviceRecv(adapter, wifi_recv_msg, 128); PrivTaskDelay(1000); } - } +#endif #ifdef ADD_RTTHREAD_FETURES MSH_CMD_EXPORT(AdapterWifiTest,a wifi adpter sample); @@ -195,8 +194,7 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHE int wifiopen(void) { struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME); - - AdapterDeviceOpen(adapter); + return AdapterDeviceOpen(adapter); } #ifdef ADD_XIZI_FETURES SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0)|SHELL_CMD_DISABLE_RETURN, wifiopen, wifiopen, open adapter wifi ); @@ -204,8 +202,7 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHE int wificlose(void) { struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME); - - AdapterDeviceClose(adapter); + return AdapterDeviceClose(adapter); } #ifdef ADD_XIZI_FETURES SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0)|SHELL_CMD_DISABLE_RETURN, wificlose, wificlose, close adapter wifi ); @@ -215,12 +212,12 @@ int wifisetup(int argc, char *argv[]) struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME); struct WifiParam param; memset(¶m,0,sizeof(struct WifiParam)); - strncpy(param.wifi_ssid, argv[1], strlen(argv[1])); - strncpy(param.wifi_pwd, argv[2], strlen(argv[2])); + strncpy((char *)param.wifi_ssid, argv[1], strlen(argv[1])); + strncpy((char *)param.wifi_pwd, argv[2], strlen(argv[2])); adapter->adapter_param = ¶m; - AdapterDeviceSetUp(adapter); + return AdapterDeviceSetUp(adapter); } #ifdef ADD_XIZI_FETURES SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(3)|SHELL_CMD_DISABLE_RETURN, wifisetup, wifisetup, setup adapter wifi ); @@ -234,7 +231,7 @@ int wifiaddrset(int argc, char *argv[]) AdapterDeviceSetAddr(adapter, ip, gateway, netmask); AdapterDevicePing(adapter, "36.152.44.95");///< ping www.baidu.com - AdapterDeviceNetstat(adapter); + return AdapterDeviceNetstat(adapter); } #ifdef ADD_XIZI_FETURES SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(4)|SHELL_CMD_DISABLE_RETURN, wifiaddrset, wifiaddrset, addrset adapter wifi); @@ -243,7 +240,7 @@ int wifiping(int argc, char *argv[]) { struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME); printf("ping %s\n",argv[1]); - AdapterDevicePing(adapter, argv[1]); + return AdapterDevicePing(adapter, argv[1]); } #ifdef ADD_XIZI_FETURES SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(3), wifiping, wifiping, wifiping adapter ); @@ -264,7 +261,7 @@ int wificonnect(int argc, char *argv[]) adapter->socket.protocal = SOCKET_PROTOCOL_UDP; } - AdapterDeviceConnect(adapter, net_role, ip, port, ip_type); + return AdapterDeviceConnect(adapter, net_role, ip, port, ip_type); } #ifdef ADD_XIZI_FETURES SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(4)|SHELL_CMD_DISABLE_RETURN, wificonnect, wificonnect, wificonnect adapter); @@ -279,6 +276,7 @@ int wifisend(int argc, char *argv[]) AdapterDeviceSend(adapter, wifi_msg, len); PrivTaskDelay(1000); } + return 0; } #ifdef ADD_XIZI_FETURES SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(3)|SHELL_CMD_DISABLE_RETURN, wifisend, wifisend, wifisend adapter wifi information); @@ -297,3 +295,117 @@ int wifirecv(int argc, char *argv[]) #ifdef ADD_XIZI_FETURES SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(3)|SHELL_CMD_DISABLE_RETURN, wifirecv, wifirecv, wifirecv adapter wifi information); #endif + +#ifdef ADD_NUTTX_FETURES + +enum +{ + APT_WIFI_PARAM_IP, + APT_WIFI_PARAM_PORT, + APT_WIFI_PARAM_SSID, + APT_WIFI_PARAM_PWD, + APT_WIFI_PARAM_GW, + APT_WIFI_PARAM_SERVER, + APT_WIFI_PARAM_MASK, + APT_WIFI_PARAM_PING, + APT_WIFI_PARAM_NUM +}; + +#define APT_WIFI_PARAM_LEN 20 + +char wifi_param[APT_WIFI_PARAM_NUM][APT_WIFI_PARAM_LEN] = {0}; + +#define CHECK_RET(__func) \ +ret = __func; \ +if(ret != 0){ \ + printf("%s %d failed\n", __func__, __LINE__); \ + AdapterDeviceClose(adapter); \ + return ret; \ +}; + +void AdapterWifiGetParam(int argc, char *argv[]) +{ + int i, j; + char *param_str[] = {"ip", "port", "ssid", "pwd", "gw", "server", "mask", "ping"}; + char *default_str[] = + {"192.168.137.34", "12345", "test", "tttttttt", "192.168.137.71", "192.168.137.1", "255.255.255.0", "220.181.38.251"}; + + for(i = 0; i < APT_WIFI_PARAM_NUM; i ++) + { + memset(wifi_param[i], 0, APT_WIFI_PARAM_LEN); + strcpy(wifi_param[i], default_str[i]); + } + + for(i = 0; i < argc; i ++) + { + for(j = 0; j < APT_WIFI_PARAM_NUM; j ++) + { + if(strncmp(argv[i], param_str[j], strlen(param_str[j])) == 0) + { + printf("wifi %d: %s\n", j, argv[i] + strlen(param_str[j]) + 1); + strcpy(wifi_param[j], argv[i] + strlen(param_str[j]) + 1); + } + } + } + + printf("--- wifi parameter ---\n"); + for(i = 0; i < APT_WIFI_PARAM_NUM; i ++) + { + printf("%7.7s = %s\n", param_str[i], wifi_param[i]); + } + printf("----------------------\n"); +} + + +int AdapterWifiTest(int argc, char *argv[]) +{ + int i, ret; + + struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME); + AdapterWifiGetParam(argc, argv); + + enum NetRoleType net_role = CLIENT; + enum IpType ip_type = IPV4; + struct WifiParam param; + memset(¶m, 0, sizeof(struct WifiParam)); + strncpy((char *)param.wifi_ssid, wifi_param[APT_WIFI_PARAM_SSID], strlen(wifi_param[APT_WIFI_PARAM_SSID])); + strncpy((char *)param.wifi_pwd, wifi_param[APT_WIFI_PARAM_PWD], strlen(wifi_param[APT_WIFI_PARAM_PWD])); + + adapter->adapter_param = ¶m; + + CHECK_RET(AdapterDeviceOpen(adapter)); + CHECK_RET(AdapterDeviceSetUp(adapter)); + + CHECK_RET(AdapterDeviceSetAddr(adapter, wifi_param[APT_WIFI_PARAM_IP], wifi_param[APT_WIFI_PARAM_GW], + wifi_param[APT_WIFI_PARAM_MASK])); + + CHECK_RET(AdapterDeviceNetstat(adapter)); + + adapter->socket.protocal = SOCKET_PROTOCOL_TCP; + CHECK_RET(AdapterDeviceConnect(adapter, net_role, wifi_param[APT_WIFI_PARAM_SERVER], + wifi_param[APT_WIFI_PARAM_PORT], ip_type)); + + const char *wifi_msg = "Wifi Test"; + for(i = 0; i < 10; i++) + { + AdapterDeviceSend(adapter, wifi_msg, strlen(wifi_msg)); + PrivTaskDelay(4000); + } + + char wifi_recv_msg[128]; + for(i = 0; i < 10; i ++) + { + AdapterDeviceRecv(adapter, wifi_recv_msg, 128); + PrivTaskDelay(1000); + } + +// printf("ping %s\n", wifi_param[APT_WIFI_PARAM_PING]); +// +// CHECK_RET(AdapterDevicePing(adapter, wifi_param[APT_WIFI_PARAM_PING])); +// AdapterDeviceDisconnect(adapter, NULL); + ret = AdapterDeviceClose(adapter); + return ret; +} + +#endif + diff --git a/APP_Framework/Framework/connection/wifi/esp07s_wifi/Kconfig b/APP_Framework/Framework/connection/wifi/esp07s_wifi/Kconfig index a54223b9b..4a28b44a7 100755 --- a/APP_Framework/Framework/connection/wifi/esp07s_wifi/Kconfig +++ b/APP_Framework/Framework/connection/wifi/esp07s_wifi/Kconfig @@ -10,10 +10,10 @@ if ADD_XIZI_FETURES config ADAPTER_ESP07S_DRIVER string "ESP07S device uart driver path" - default "/dev/uart2_dev2" + default "/dev/ttyS2" depends on !ADAPTER_ESP07S_DRIVER_EXTUART - if ADAPTER_ESP07S_DRIVER_EXTUART + if ADAPTER_ESP07S_DRIVER_EXTUART config ADAPTER_ESP07S_DRIVER string "ESP07S device extra uart driver path" default "/dev/extuart_dev6" @@ -25,7 +25,24 @@ if ADD_XIZI_FETURES endif if ADD_NUTTX_FETURES + config ADAPTER_ESP07S_DRIVER_EXTUART + bool "Using extra uart to support wifi" + default n + config ADAPTER_ESP07S_DRIVER + string "ESP07S device uart driver path" + default "/dev/uart2_dev2" + depends on !ADAPTER_ESP07S_DRIVER_EXTUART + + if ADAPTER_ESP07S_DRIVER_EXTUART + config ADAPTER_ESP07S_DRIVER + string "ESP07S device extra uart driver path" + default "/dev/extuart_dev6" + + config ADAPTER_ESP07S_DRIVER_EXT_PORT + int "if ESP07S device using extuart, choose port" + default "6" + endif endif if ADD_RTTHREAD_FETURES diff --git a/APP_Framework/Framework/connection/wifi/esp07s_wifi/Make.defs b/APP_Framework/Framework/connection/wifi/esp07s_wifi/Make.defs new file mode 100755 index 000000000..400550a50 --- /dev/null +++ b/APP_Framework/Framework/connection/wifi/esp07s_wifi/Make.defs @@ -0,0 +1,6 @@ +############################################################################ +# APP_Framework/Framework/connection/zigbee/e18/Make.defs +############################################################################ +ifneq ($(CONFIG_ADAPTER_ESP07S_WIFI),) +CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/connection/wifi/esp07s_wifi +endif diff --git a/APP_Framework/Framework/connection/wifi/esp07s_wifi/Makefile b/APP_Framework/Framework/connection/wifi/esp07s_wifi/Makefile index e0ce0a8ac..53493604e 100755 --- a/APP_Framework/Framework/connection/wifi/esp07s_wifi/Makefile +++ b/APP_Framework/Framework/connection/wifi/esp07s_wifi/Makefile @@ -1,3 +1,13 @@ +include $(KERNEL_ROOT)/.config +ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) + include $(APPDIR)/Make.defs + CSRCS += esp07s_wifi.c + include $(APPDIR)/Application.mk + +endif + +ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_FILES := esp07s_wifi.c include $(KERNEL_ROOT)/compiler.mk +endif diff --git a/APP_Framework/Framework/connection/wifi/esp07s_wifi/esp07s_wifi.c b/APP_Framework/Framework/connection/wifi/esp07s_wifi/esp07s_wifi.c index b634f7d6e..36c943b73 100755 --- a/APP_Framework/Framework/connection/wifi/esp07s_wifi/esp07s_wifi.c +++ b/APP_Framework/Framework/connection/wifi/esp07s_wifi/esp07s_wifi.c @@ -25,6 +25,11 @@ #define LEN_PARA_BUF 128 +#ifdef ADD_NUTTX_FETURES +#define EOK 0 +#define x_err_t int +#endif + static int Esp07sWifiSetDown(struct Adapter *adapter_at); /** @@ -116,7 +121,7 @@ static int Esp07sWifiOpen(struct Adapter *adapter) AtSetReplyEndChar(adapter->agent,'O','K'); - ADAPTER_DEBUG("Esp07sWifi open done\n"); + ADAPTER_DEBUG("Esp07sWifi open done\n"); return 0; } @@ -196,13 +201,13 @@ static int Esp07sWifiSetUp(struct Adapter *adapter) } PrivTaskDelay(2000); /* config as softAP+station mode */ - ret = AtCmdConfigAndCheck(agent, "AT+CWMODE=3\r\n", "OK"); + ret = AtCmdConfigAndCheck(agent, "AT+CWMODE=3\r\n", "OK"); if(ret < 0) { printf("%s %d cmd[AT+CWMODE=3] config failed!\n",__func__,__LINE__); return -1; } PrivTaskDelay(2000); - /* connect the router */ + /* connect the router */ memset(cmd,0,sizeof(cmd)); strncpy(cmd,"AT+CWJAP=",strlen("AT+CWJAP=")); strncat(cmd,"\"",1); @@ -222,7 +227,7 @@ static int Esp07sWifiSetUp(struct Adapter *adapter) return -1; } - /* check the wifi ip address */ + /* check the wifi ip address */ ATReplyType reply = CreateATReply(256); if (NULL == reply) { printf("%s %d at_create_resp failed!\n",__func__,__LINE__); @@ -291,7 +296,7 @@ static int Esp07sWifiSetAddr(struct Adapter *adapter, const char *ip, const char strncat(cmd,"\"",1); strcat(cmd,"\r\n"); - ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK"); + ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK"); if(ret < 0) { printf("%s %d cmd[%s] config ip failed!\n",__func__,__LINE__,cmd); return -1; @@ -339,7 +344,7 @@ static int Esp07sWifiNetstat(struct Adapter *adapter) int ret = 0; char *result = NULL; - /* check the wifi ip address */ + /* check the wifi ip address */ ATReplyType reply = CreateATReply(256); if (NULL == reply) { printf("%s %d at_create_resp failed!\n",__func__,__LINE__); @@ -359,7 +364,7 @@ static int Esp07sWifiNetstat(struct Adapter *adapter) goto __exit; } printf("[%s]\n", result); - + __exit: DeleteATReply(reply); @@ -380,7 +385,7 @@ static int Esp07sWifiConnect(struct Adapter *adapter, enum NetRoleType net_role, int ret = EOK; char cmd[LEN_PARA_BUF]; struct ATAgent *agent = adapter->agent; - + memset(cmd,0,sizeof(cmd)); if(adapter->socket.protocal == SOCKET_PROTOCOL_TCP && net_role == CLIENT) //esp07s as tcp client to connect server { @@ -397,13 +402,13 @@ static int Esp07sWifiConnect(struct Adapter *adapter, enum NetRoleType net_role, strncat(cmd, port, strlen(port)); strcat(cmd,"\r\n"); - ret = AtCmdConfigAndCheck(agent, cmd, "OK"); + ret = AtCmdConfigAndCheck(agent, cmd, "OK"); if(ret < 0) { printf("%s %d tcp connect [%s] failed!\n",__func__,__LINE__,ip); return -1; } - } - else if(adapter->socket.protocal == SOCKET_PROTOCOL_UDP) + } + else if(adapter->socket.protocal == SOCKET_PROTOCOL_UDP) { //e.g. AT+CIPSTART="UDP","192.168.3.116",8080,2233,0 UDP protocol, server IP, port,local port,udp mode strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART=")); @@ -422,7 +427,7 @@ static int Esp07sWifiConnect(struct Adapter *adapter, enum NetRoleType net_role, strncat(cmd, "0", 1); ///< udp transparent transmission mode must be 0 strcat(cmd,"\r\n"); - ret = AtCmdConfigAndCheck(agent, cmd, "OK"); + ret = AtCmdConfigAndCheck(agent, cmd, "OK"); if(ret < 0) { printf("%s %d udp connect [%s] failed!\n",__func__,__LINE__,ip); return -1; @@ -455,17 +460,17 @@ static int Esp07sWifiDisconnect(struct Adapter *adapter) memset(cmd,0,sizeof(cmd)); /* step1: stop transparent transmission mode */ - ATOrderSend(agent, REPLY_TIME_OUT, NULL, "+++\r\n"); + ATOrderSend(agent, REPLY_TIME_OUT, NULL, "+++\r\n"); /* step2: exit transparent transmission mode */ - ret = AtCmdConfigAndCheck(agent, "AT+CIPMODE=0\r\n", "OK"); + ret = AtCmdConfigAndCheck(agent, "AT+CIPMODE=0\r\n", "OK"); if(ret < 0) { printf("%s %d cmd[AT+CIPMODE=0] exit failed!\n",__func__,__LINE__); return -1; } /* step3: disconnect */ - ret = AtCmdConfigAndCheck(agent, "AT+CIPCLOSE\r\n", "OK"); + ret = AtCmdConfigAndCheck(agent, "AT+CIPCLOSE\r\n", "OK"); if(ret < 0) { printf("%s %d cmd [AT+CIPCLOSE] disconnect failed!\n",__func__,__LINE__); return -1; @@ -490,7 +495,7 @@ static int Esp07sWifiIoctl(struct Adapter *adapter, int cmd, void *args) case CONFIG_WIFI_RESTORE: /* resore wifi */ ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+RESTORE\r\n"); break; - case CONFIG_WIFI_BAUDRATE: + case CONFIG_WIFI_BAUDRATE: /* step1: config mcu uart*/ baud_rate = *((uint32_t *)args); @@ -525,14 +530,14 @@ static int Esp07sWifiIoctl(struct Adapter *adapter, int cmd, void *args) strncat(at_cmd, ",", 1); strncat(at_cmd, "8", 1); strncat(at_cmd, ",", 1); - strncat(at_cmd, "1", 1); + strncat(at_cmd, "1", 1); strncat(at_cmd, ",", 1); strncat(at_cmd, "0", 1); strncat(at_cmd, ",", 1); strncat(at_cmd, "3", 1); strcat(at_cmd,"\r\n"); - ret = AtCmdConfigAndCheck(adapter->agent, at_cmd, "OK"); + ret = AtCmdConfigAndCheck(adapter->agent, at_cmd, "OK"); if(ret < 0) { printf("%s %d cmd [%s] config uart failed!\n",__func__,__LINE__,at_cmd); ret = -1; @@ -541,7 +546,7 @@ static int Esp07sWifiIoctl(struct Adapter *adapter, int cmd, void *args) break; default: ret = -1; - break; + break; } return ret; @@ -572,7 +577,7 @@ static const struct IpProtocolDone esp07s_wifi_done = AdapterProductInfoType Esp07sWifiAttach(struct Adapter *adapter) { struct AdapterProductInfo *product_info = PrivMalloc(sizeof(struct AdapterProductInfo)); - if (!product_info) + if (!product_info) { printf("Esp07sWifiAttach Attach malloc product_info error\n"); PrivFree(product_info); @@ -584,4 +589,4 @@ AdapterProductInfoType Esp07sWifiAttach(struct Adapter *adapter) product_info->model_done = (void *)&esp07s_wifi_done; return product_info; -} \ No newline at end of file +} diff --git a/APP_Framework/Framework/connection/zigbee/e18/Kconfig b/APP_Framework/Framework/connection/zigbee/e18/Kconfig index 643d07acb..06bdec8c7 100644 --- a/APP_Framework/Framework/connection/zigbee/e18/Kconfig +++ b/APP_Framework/Framework/connection/zigbee/e18/Kconfig @@ -1,8 +1,8 @@ config ADAPTER_ZIGBEE_E18 string "E18 adapter name" default "e18" - -choice + +choice prompt "E18 adapter select net role type " default AS_END_DEVICE_ROLE @@ -11,7 +11,7 @@ choice config AS_ROUTER_ROLE bool "config as a router" - + config AS_END_DEVICE_ROLE bool "config as an end device" endchoice @@ -22,8 +22,8 @@ if ADD_XIZI_FETURES int "E18 MODE pin number" default "61" - config ADAPTER_BC28_PIN_DRIVER - string "BC28 device pin driver path" + config ADAPTER_E18_PIN_DRIVER + string "E18 device pin driver path" default "/dev/pin_dev" config ADAPTER_E18_DRIVER_EXTUART @@ -35,7 +35,7 @@ if ADD_XIZI_FETURES default "/dev/uart2_dev2" depends on !ADAPTER_E18_DRIVER_EXTUART - if ADAPTER_E18_DRIVER_EXTUART + if ADAPTER_E18_DRIVER_EXTUART config ADAPTER_E18_DRIVER string "E18 device extra uart driver path" default "/dev/extuart_dev0" @@ -47,11 +47,31 @@ if ADD_XIZI_FETURES endif if ADD_NUTTX_FETURES + config ADAPTER_E18_MODEPIN + int "E18 MODE pin number" + default "61" + + config ADAPTER_E18_PIN_DRIVER + string "E18 device pin driver path" + default "/dev/pin_dev" + config ADAPTER_E18_DRIVER string "E18 device uart driver path" default "/dev/ttyS1" + depends on !ADAPTER_E18_DRIVER_EXTUART ---help--- If USART1 is selected, then fill in /dev/ttyS1 here. + + if ADAPTER_E18_DRIVER_EXTUART + config ADAPTER_E18_DRIVER + string "E18 device extra uart driver path" + default "/dev/extuart_dev1" + + config ADAPTER_E18_DRIVER_EXT_PORT + int "if E18 device using extuart, choose port" + default "1" + endif + endif if ADD_RTTHREAD_FETURES diff --git a/APP_Framework/Framework/connection/zigbee/e18/e18.c b/APP_Framework/Framework/connection/zigbee/e18/e18.c index bd8d5ef92..6638a988b 100644 --- a/APP_Framework/Framework/connection/zigbee/e18/e18.c +++ b/APP_Framework/Framework/connection/zigbee/e18/e18.c @@ -45,7 +45,7 @@ static int E18HardwareModeGet() int ret = 0; int pin_fd; - pin_fd = PrivOpen(ADAPTER_BC28_PIN_DRIVER, O_RDWR); + pin_fd = PrivOpen(ADAPTER_E18_PIN_DRIVER, O_RDWR); struct PinStat pin_stat; pin_stat.pin = ADAPTER_E18_MODEPIN; @@ -175,7 +175,7 @@ static int E18NetworkModeConfig(struct Adapter *adapter) } out: - if(E18_AS_HEX_MODE == mode){ + if(E18_AS_AT_MODE == mode){ AtCmdConfigAndCheck(adapter->agent, cmd_exit, "+OK"); } @@ -203,7 +203,9 @@ static int E18NetRoleConfig(struct Adapter *adapter) goto out; } } - + + //wait 2second + PrivTaskDelay(2000); switch (adapter->net_role) { @@ -240,7 +242,7 @@ static int E18NetRoleConfig(struct Adapter *adapter) } out: - if(E18_AS_HEX_MODE == mode) { + if(E18_AS_AT_MODE == mode) { AtCmdConfigAndCheck(adapter->agent, cmd_exit, "+OK"); } @@ -382,7 +384,7 @@ static int E18Join(struct Adapter *adapter, unsigned char *priv_net_group) // } if(!ret){ - if(E18_AS_HEX_MODE == mode) { + if(E18_AS_AT_MODE == mode) { ret = AtCmdConfigAndCheck(adapter->agent, cmd_exit, "+OK"); if(ret < 0) { printf("%s %d cmd[%s] config failed!\n",__func__,__LINE__,cmd_exit); diff --git a/APP_Framework/Framework/transform_layer/nuttx/transform.c b/APP_Framework/Framework/transform_layer/nuttx/transform.c index 45d8d30ec..d01176541 100644 --- a/APP_Framework/Framework/transform_layer/nuttx/transform.c +++ b/APP_Framework/Framework/transform_layer/nuttx/transform.c @@ -55,17 +55,19 @@ int PrivSemaphoreDelete(sem_t *sem) int PrivSemaphoreObtainWait(sem_t *sem, const struct timespec *abstime) { + /* if the timeout is not set, it will be blocked all the time. */ + if(!abstime) + { + return sem_wait(sem); + } + + /* if the timeout time is set, it will be executed downward after the timeout, and will not be blocked. */ struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); timeout.tv_sec += abstime->tv_sec; return sem_timedwait(sem, &timeout); } -int PrivSemaphoreObtainWaitForever(sem_t *sem) -{ - return sem_wait(sem); -} - int PrivSemaphoreObtainNoWait(sem_t *sem) { return sem_trywait(sem); @@ -133,40 +135,9 @@ int PrivWrite(int fd, const void *buf, size_t len) return write(fd, buf, len); } -static int PrivSerialIoctl(int fd, int cmd, void *args) +int PrivIoctl(int fd, int cmd, unsigned long args) { - struct SerialDataCfg *serial_cfg = (struct SerialDataCfg *)args; - return ioctl(fd, cmd, serial_cfg); -} - -static int PrivPinIoctl(int fd, int cmd, void *args) -{ - struct PinParam *pin_cfg = (struct PinParam *)args; - - return ioctl(fd, cmd, pin_cfg); -} - -int PrivIoctl(int fd, int cmd, void *args) -{ - int ret = 0; - struct PrivIoctlCfg *ioctl_cfg = (struct PrivIoctlCfg *)args; - - switch (ioctl_cfg->ioctl_driver_type) - { - case SERIAL_TYPE: - ret = PrivSerialIoctl(fd, cmd, ioctl_cfg->args); - break; - case PIN_TYPE: - ret = PrivPinIoctl(fd, cmd, ioctl_cfg->args); - break; - case I2C_TYPE: - ret = ioctl(fd, cmd, ioctl_cfg->args); - break; - default: - break; - } - - return ret; + return ioctl(fd, cmd, args); } /********************memory api************/ diff --git a/APP_Framework/Framework/transform_layer/nuttx/transform.h b/APP_Framework/Framework/transform_layer/nuttx/transform.h index 1cf6b83fc..71b4f48e7 100644 --- a/APP_Framework/Framework/transform_layer/nuttx/transform.h +++ b/APP_Framework/Framework/transform_layer/nuttx/transform.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include typedef uint8_t uint8; typedef uint16_t uint16; @@ -43,22 +45,23 @@ typedef int64_t int64; extern "C" { #endif -#define OPE_INT 0x0000 -#define OPE_CFG 0x0001 +#define OPE_INT 0x0000 +#define OPE_CFG 0x0001 + +#define NAME_NUM_MAX 32 -#define NAME_NUM_MAX 32 /*********************GPIO define*********************/ #define GPIO_LOW 0x00 #define GPIO_HIGH 0x01 -#define GPIO_CFG_OUTPUT 0x00 -#define GPIO_CFG_INPUT 0x01 -#define GPIO_CFG_INPUT_PULLUP 0x02 +#define GPIO_CFG_OUTPUT 0x00 +#define GPIO_CFG_INPUT 0x01 +#define GPIO_CFG_INPUT_PULLUP 0x02 #define GPIO_CFG_INPUT_PULLDOWN 0x03 -#define GPIO_CFG_OUTPUT_OD 0x04 +#define GPIO_CFG_OUTPUT_OD 0x04 -#define GPIO_CONFIG_MODE 0xffffffff +#define GPIO_CONFIG_MODE 0xffffffff /********************SERIAL define*******************/ #define BAUD_RATE_2400 2400 @@ -172,15 +175,11 @@ int PrivMutexDelete(pthread_mutex_t *p_mutex); int PrivMutexObtain(pthread_mutex_t *p_mutex); int PrivMutexAbandon(pthread_mutex_t *p_mutex); - - - /*********************semaphore**********************/ int PrivSemaphoreCreate(sem_t *sem, int pshared, unsigned int value); int PrivSemaphoreDelete(sem_t *sem); int PrivSemaphoreObtainWait(sem_t *sem, const struct timespec *abstime); -int PrivSemaphoreObtainWaitForever(sem_t *sem); int PrivSemaphoreObtainNoWait(sem_t *sem); int PrivSemaphoreAbandon(sem_t *sem); int32_t PrivSemaphoreSetValue(int32_t sem, uint16_t val); @@ -201,7 +200,7 @@ int PrivOpen(const char *path, int flags); int PrivRead(int fd, void *buf, size_t len); int PrivWrite(int fd, const void *buf, size_t len); int PrivClose(int fd); -int PrivIoctl(int fd, int cmd, void *args); +int PrivIoctl(int fd, int cmd, unsigned long args); /*********************memory***********************/ diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.h b/APP_Framework/Framework/transform_layer/xizi/transform.h index 2b071dca2..784e1a5b7 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.h +++ b/APP_Framework/Framework/transform_layer/xizi/transform.h @@ -183,10 +183,21 @@ typedef struct LcdStringParam string_info; }LcdWriteParam; +typedef struct +{ + uint16_t x; + uint16_t y; + uint16_t press; +}TouchDataParam; + #define PRIV_SYSTICK_GET (CurrentTicksGain()) #define PRIV_LCD_DEV "/dev/lcd_dev" #define MY_DISP_HOR_RES BSP_LCD_Y_MAX #define MY_DISP_VER_RES BSP_LCD_X_MAX + +#define PRIV_TOUCH_DEV "/dev/touch_dev" +#define MY_INDEV_X BSP_LCD_Y_MAX +#define MY_INDEV_Y BSP_LCD_X_MAX /**********************mutex**************************/ int PrivMutexCreate(pthread_mutex_t *p_mutex, const pthread_mutexattr_t *attr); diff --git a/APP_Framework/lib/lvgl/Kconfig b/APP_Framework/lib/lvgl/Kconfig index f83f24654..856f00324 100644 --- a/APP_Framework/lib/lvgl/Kconfig +++ b/APP_Framework/lib/lvgl/Kconfig @@ -1,7 +1,13 @@ # Kconfig file for LVGL v8.0 menuconfig LIB_LV bool "Enable LittleVGL " -default n + default n + + menu "LVGL configuration" + config LV_CONF_MINIMAL + bool "LVGL minimal configuration." + default n + endmenu if 0 menu "LVGL configuration" diff --git a/APP_Framework/lib/lvgl/examples/porting/lv_port_disp_template.c b/APP_Framework/lib/lvgl/examples/porting/lv_port_disp_template.c index acfe70894..314783c4e 100644 --- a/APP_Framework/lib/lvgl/examples/porting/lv_port_disp_template.c +++ b/APP_Framework/lib/lvgl/examples/porting/lv_port_disp_template.c @@ -81,9 +81,9 @@ void lv_port_disp_init(void) /* Example for 2) */ static lv_disp_draw_buf_t draw_buf_dsc_2; - static lv_color_t buf_2_1[MY_DISP_HOR_RES *70]; /*A buffer for 10 rows*/ - static lv_color_t buf_2_2[MY_DISP_HOR_RES * 70]; /*An other buffer for 10 rows*/ - lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 70); /*Initialize the display buffer*/ + static lv_color_t buf_2_1[MY_DISP_HOR_RES *10]; /*A buffer for 10 rows*/ + static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10]; /*An other buffer for 10 rows*/ + lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10); /*Initialize the display buffer*/ /* Example for 3) also set disp_drv.full_refresh = 1 below*/ // static lv_disp_draw_buf_t draw_buf_dsc_3; diff --git a/APP_Framework/lib/lvgl/examples/porting/lv_port_indev_template.c b/APP_Framework/lib/lvgl/examples/porting/lv_port_indev_template.c index 2b7931479..fa75751d2 100644 --- a/APP_Framework/lib/lvgl/examples/porting/lv_port_indev_template.c +++ b/APP_Framework/lib/lvgl/examples/porting/lv_port_indev_template.c @@ -12,9 +12,18 @@ #include "lv_port_indev_template.h" #include "../../lvgl.h" +static int touch_fd = 0; +static TouchDataParam touch_data; /********************* * DEFINES *********************/ +#define LV_USE_INDEV_TOUCHPAD 0x1u +#define LV_USE_INDEV_MOUSE 0x2u +#define LV_USE_INDEV_KEYPAD 0x4u +#define LV_USE_INDEV_ENCODER 0x8u +#define LV_USE_INDEV_BUTTUN 0x10u + +#define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD ///< modify this DEFINE to enable the indev device. e.g #define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD | LV_USE_INDEV_KEYPAD /********************** * TYPEDEFS @@ -23,38 +32,61 @@ /********************** * STATIC PROTOTYPES **********************/ - +#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD static void touchpad_init(void); static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static bool touchpad_is_pressed(void); static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y); +#endif +#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE static void mouse_init(void); static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static bool mouse_is_pressed(void); static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y); +#endif +#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD static void keypad_init(void); static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static uint32_t keypad_get_key(void); +#endif +#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER static void encoder_init(void); static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static void encoder_handler(void); +#endif +#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN static void button_init(void); static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static int8_t button_get_pressed_id(void); static bool button_is_pressed(uint8_t id); +#endif /********************** * STATIC VARIABLES **********************/ +#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD lv_indev_t * indev_touchpad; +#endif + +#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE lv_indev_t * indev_mouse; +#endif + +#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD lv_indev_t * indev_keypad; +#endif + +#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER lv_indev_t * indev_encoder; +#endif + +#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN lv_indev_t * indev_button; +#endif static int32_t encoder_diff; static lv_indev_state_t encoder_state; @@ -82,7 +114,7 @@ void lv_port_indev_init(void) */ static lv_indev_drv_t indev_drv; - +#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD /*------------------ * Touchpad * -----------------*/ @@ -95,7 +127,9 @@ void lv_port_indev_init(void) indev_drv.type = LV_INDEV_TYPE_POINTER; indev_drv.read_cb = touchpad_read; indev_touchpad = lv_indev_drv_register(&indev_drv); +#endif +#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE /*------------------ * Mouse * -----------------*/ @@ -113,7 +147,9 @@ void lv_port_indev_init(void) lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act()); lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME); lv_indev_set_cursor(indev_mouse, mouse_cursor); +#endif +#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD /*------------------ * Keypad * -----------------*/ @@ -131,7 +167,11 @@ void lv_port_indev_init(void) *add objects to the group with `lv_group_add_obj(group, obj)` *and assign this input device to group to navigate in it: *`lv_indev_set_group(indev_keypad, group);`*/ +#endif + + +#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER /*------------------ * Encoder * -----------------*/ @@ -149,7 +189,9 @@ void lv_port_indev_init(void) *add objects to the group with `lv_group_add_obj(group, obj)` *and assign this input device to group to navigate in it: *`lv_indev_set_group(indev_encoder, group);`*/ +#endif +#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN /*------------------ * Button * -----------------*/ @@ -169,12 +211,13 @@ void lv_port_indev_init(void) {40, 100}, /*Button 1 -> x:40; y:100*/ }; lv_indev_set_button_points(indev_button, btn_points); +#endif } /********************** * STATIC FUNCTIONS **********************/ - +#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD /*------------------ * Touchpad * -----------------*/ @@ -182,6 +225,13 @@ void lv_port_indev_init(void) /*Initialize your touchpad*/ static void touchpad_init(void) { + touch_fd = PrivOpen(PRIV_TOUCH_DEV,O_RDWR); + if(touch_fd >= 0) { + printf("touch fd = %d\n",touch_fd); + } else { + printf("open %s touch fd = %d failed.\n",PRIV_TOUCH_DEV,touch_fd); + } + /*Your code comes here*/ } @@ -207,8 +257,16 @@ static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) /*Return true is the touchpad is pressed*/ static bool touchpad_is_pressed(void) { + int ret; /*Your code comes here*/ - + memset(&touch_data, 0 ,sizeof(TouchDataParam)); + ret = PrivRead(touch_fd, &touch_data, 1); + if(ret && touch_data.x >= 0 && touch_data.x < MY_INDEV_X && touch_data.y >= 0 && touch_data.y < MY_INDEV_Y) + { + // printf("touch x %d touch y %d\n",touch_data.x,touch_data.y); + return true; + } + return false; } @@ -217,10 +275,12 @@ static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y) { /*Your code comes here*/ - (*x) = 0; - (*y) = 0; + (*x) = touch_data.x; + (*y) = touch_data.y; } +#endif +#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE /*------------------ * Mouse * -----------------*/ @@ -261,7 +321,11 @@ static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y) (*x) = 0; (*y) = 0; } +#endif + + +#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD /*------------------ * Keypad * -----------------*/ @@ -319,7 +383,11 @@ static uint32_t keypad_get_key(void) return 0; } +#endif + + +#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER /*------------------ * Encoder * -----------------*/ @@ -346,7 +414,9 @@ static void encoder_handler(void) encoder_diff += 0; encoder_state = LV_INDEV_STATE_REL; } +#endif +#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN /*------------------ * Button * -----------------*/ @@ -402,7 +472,7 @@ static bool button_is_pressed(uint8_t id) return false; } - +#endif #else /*Enable this file at the top*/ /*This dummy typedef exists purely to silence -Wpedantic.*/ diff --git a/APP_Framework/lib/lvgl/lv_conf.h b/APP_Framework/lib/lvgl/lv_conf.h index 46d5bf401..506b9a3ff 100644 --- a/APP_Framework/lib/lvgl/lv_conf.h +++ b/APP_Framework/lib/lvgl/lv_conf.h @@ -410,48 +410,111 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/ *================*/ /*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/ - -#define LV_USE_ARC 1 - -#define LV_USE_ANIMIMG 1 - -#define LV_USE_BAR 1 - -#define LV_USE_BTN 1 - -#define LV_USE_BTNMATRIX 1 - -#define LV_USE_CANVAS 1 - -#define LV_USE_CHECKBOX 1 - -#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/ - -#define LV_USE_IMG 1 /*Requires: lv_label*/ - -#define LV_USE_LABEL 1 -#if LV_USE_LABEL -# define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/ -# define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/ +#ifndef LV_CONF_MINIMAL + #define LV_USE_ARC 1 +# else + #define LV_USE_ARC 0 #endif -#define LV_USE_LINE 1 - -#define LV_USE_ROLLER 1 /*Requires: lv_label*/ -#if LV_USE_ROLLER -# define LV_ROLLER_INF_PAGES 7 /*Number of extra "pages" when the roller is infinite*/ +#ifndef LV_CONF_MINIMAL + #define LV_USE_ANIMIMG 1 +# else + #define LV_USE_ANIMIMG 0 #endif -#define LV_USE_SLIDER 1 /*Requires: lv_bar*/ - -#define LV_USE_SWITCH 1 - -#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/ -#if LV_USE_TEXTAREA != 0 -# define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ +#ifndef LV_CONF_MINIMAL + #define LV_USE_BAR 1 +# else + #define LV_USE_BAR 0 #endif -#define LV_USE_TABLE 1 +#ifndef LV_CONF_MINIMAL + #define LV_USE_BTN 1 +# else + #define LV_USE_BTN 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_BTNMATRIX 1 +# else + #define LV_USE_BTNMATRIX 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_CANVAS 1 +# else + #define LV_USE_CANVAS 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_CHECKBOX 1 +# else + #define LV_USE_CHECKBOX 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_DROPDOWN 1 /*Requires: lv_label*/ +# else + #define LV_USE_DROPDOWN 0 /*Requires: lv_label*/ +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_IMG 1 /*Requires: lv_label*/ +# else + #define LV_USE_IMG 0 /*Requires: lv_label*/ +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_LABEL 1 + #if LV_USE_LABEL + # define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/ + # define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/ + #endif +# else + #define LV_USE_LABEL 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_LINE 1 +# else + #define LV_USE_LINE 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_ROLLER 1 /*Requires: lv_label*/ + #if LV_USE_ROLLER + # define LV_ROLLER_INF_PAGES 7 /*Number of extra "pages" when the roller is infinite*/ + #endif +# else + #define LV_USE_ROLLER 0 /*Requires: lv_label*/ +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_SLIDER 1 /*Requires: lv_bar*/ +# else + #define LV_USE_SLIDER 0 /*Requires: lv_bar*/ +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_SWITCH 1 +# else + #define LV_USE_SWITCH 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_TEXTAREA 1 /*Requires: lv_label*/ + #if LV_USE_TEXTAREA != 0 + # define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ + #endif +# else + #define LV_USE_TEXTAREA 0 /*Requires: lv_label*/ +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_TABLE 1 +# else + #define LV_USE_TABLE 0 +#endif /*================== * EXTRA COMPONENTS @@ -460,72 +523,138 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/ /*----------- * Widgets *----------*/ -#define LV_USE_CALENDAR 1 -#if LV_USE_CALENDAR -# define LV_CALENDAR_WEEK_STARTS_MONDAY 0 -# if LV_CALENDAR_WEEK_STARTS_MONDAY -# define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"} -# else -# define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"} -# endif +#ifndef LV_CONF_MINIMAL + #define LV_USE_CALENDAR 1 + #if LV_USE_CALENDAR + # define LV_CALENDAR_WEEK_STARTS_MONDAY 0 + # if LV_CALENDAR_WEEK_STARTS_MONDAY + # define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"} + # else + # define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"} + # endif -# define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} -# define LV_USE_CALENDAR_HEADER_ARROW 1 -# define LV_USE_CALENDAR_HEADER_DROPDOWN 1 -#endif /*LV_USE_CALENDAR*/ - -#define LV_USE_CHART 1 - -#define LV_USE_COLORWHEEL 1 - -#define LV_USE_IMGBTN 1 - -#define LV_USE_KEYBOARD 1 - -#define LV_USE_LED 1 - -#define LV_USE_LIST 1 - -#define LV_USE_METER 1 - -#define LV_USE_MSGBOX 1 - -#define LV_USE_SPINBOX 1 - -#define LV_USE_SPINNER 1 - -#define LV_USE_TABVIEW 1 - -#define LV_USE_TILEVIEW 1 - -#define LV_USE_WIN 1 - -#define LV_USE_SPAN 1 -#if LV_USE_SPAN -/*A line text can contain maximum num of span descriptor */ -# define LV_SPAN_SNIPPET_STACK_SIZE 64 + # define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} + # define LV_USE_CALENDAR_HEADER_ARROW 1 + # define LV_USE_CALENDAR_HEADER_DROPDOWN 1 + #endif /*LV_USE_CALENDAR*/ +# else + #define LV_USE_CALENDAR 0 #endif +#ifndef LV_CONF_MINIMAL + #define LV_USE_CHART 1 +# else + #define LV_USE_CHART 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_COLORWHEEL 1 +# else + #define LV_USE_COLORWHEEL 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_IMGBTN 1 +# else + #define LV_USE_IMGBTN 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_KEYBOARD 1 +# else + #define LV_USE_KEYBOARD 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_LED 1 +# else + #define LV_USE_LED 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_LIST 1 +# else + #define LV_USE_LIST 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_METER 1 +# else + #define LV_USE_METER 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_MSGBOX 1 +# else + #define LV_USE_MSGBOX 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_SPINBOX 1 +# else + #define LV_USE_SPINBOX 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_SPINNER 1 +# else + #define LV_USE_SPINNER 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_TABVIEW 1 +# else + #define LV_USE_TABVIEW 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_TILEVIEW 1 +# else + #define LV_USE_TILEVIEW 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_WIN 1 +# else + #define LV_USE_WIN 0 +#endif + +#ifndef LV_CONF_MINIMAL + #define LV_USE_SPAN 1 + #if LV_USE_SPAN + /*A line text can contain maximum num of span descriptor */ + # define LV_SPAN_SNIPPET_STACK_SIZE 64 + #endif +# else + #define LV_USE_SPAN 0 +#endif /*----------- * Themes *----------*/ +#ifndef LV_CONF_MINIMAL + /*A simple, impressive and very complete theme*/ + #define LV_USE_THEME_DEFAULT 1 + #if LV_USE_THEME_DEFAULT -/*A simple, impressive and very complete theme*/ -#define LV_USE_THEME_DEFAULT 1 -#if LV_USE_THEME_DEFAULT + /*0: Light mode; 1: Dark mode*/ + # define LV_THEME_DEFAULT_DARK 0 -/*0: Light mode; 1: Dark mode*/ -# define LV_THEME_DEFAULT_DARK 0 + /*1: Enable grow on press*/ + # define LV_THEME_DEFAULT_GROW 1 -/*1: Enable grow on press*/ -# define LV_THEME_DEFAULT_GROW 1 - -/*Default transition time in [ms]*/ -# define LV_THEME_DEFAULT_TRANSITION_TIME 80 -#endif /*LV_USE_THEME_DEFAULT*/ + /*Default transition time in [ms]*/ + # define LV_THEME_DEFAULT_TRANSITION_TIME 80 + #endif /*LV_USE_THEME_DEFAULT*/ +# else + #define LV_USE_THEME_DEFAULT 0 +#endif /*A very simple theme that is a good starting point for a custom theme*/ - #define LV_USE_THEME_BASIC 1 +#ifndef LV_CONF_MINIMAL + #define LV_USE_THEME_BASIC 1 + # else + #define LV_USE_THEME_BASIC 0 +#endif /*A theme designed for monochrome displays*/ #define LV_USE_THEME_MONO 1 @@ -535,11 +664,18 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/ *----------*/ /*A layout similar to Flexbox in CSS.*/ -#define LV_USE_FLEX 1 +#ifndef LV_CONF_MINIMAL + #define LV_USE_FLEX 1 +# else + #define LV_USE_FLEX 0 +#endif /*A layout similar to Grid in CSS.*/ -#define LV_USE_GRID 1 - +#ifndef LV_CONF_MINIMAL + #define LV_USE_GRID 1 +# else + #define LV_USE_GRID 0 +#endif /*--------------------- * 3rd party libraries *--------------------*/ @@ -588,16 +724,22 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/ *----------*/ /*1: Enable API to take snapshot for object*/ -#define LV_USE_SNAPSHOT 1 - +#ifndef LV_CONF_MINIMAL + #define LV_USE_SNAPSHOT 1 +# else + #define LV_USE_SNAPSHOT 0 +#endif /*================== * EXAMPLES *==================*/ /*Enable the examples to be built with the library*/ -#define LV_BUILD_EXAMPLES 1 - +#ifndef LV_CONF_MINIMAL + #define LV_BUILD_EXAMPLES 1 +# else + #define LV_BUILD_EXAMPLES 0 +#endif /*--END OF LV_CONF_H--*/ #endif /*LV_CONF_H*/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/Kconfig index e9b8024af..e729e70d3 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/Kconfig @@ -6,82 +6,200 @@ if ARCH_BOARD_XIDATONG choice - prompt "Boot Flash" - default XIDATONG_QSPI_FLASH + prompt "Boot Flash" + default XIDATONG_QSPI_FLASH config XIDATONG_HYPER_FLASH - bool "HYPER Flash" + bool "HYPER Flash" config XIDATONG_QSPI_FLASH - bool "QSPI Flash" + bool "QSPI Flash" endchoice # Boot Flash config XIDATONG_SDRAM - bool "Enable SDRAM" - default y - select IMXRT_SEMC_INIT_DONE - ---help--- - Activate DCD configuration of SDRAM + bool "Enable SDRAM" + default y + select IMXRT_SEMC_INIT_DONE + ---help--- + Activate DCD configuration of SDRAM config XIDATONG_SDIO_AUTOMOUNT - bool "SD card automounter" - default n - depends on FS_AUTOMOUNTER && IMXRT_USDHC + bool "SD card automounter" + default n + depends on FS_AUTOMOUNTER && IMXRT_USDHC if XIDATONG_SDIO_AUTOMOUNT config XIDATONG_SDIO_AUTOMOUNT_FSTYPE - string "SD card file system type" - default "vfat" + string "SD card file system type" + default "vfat" config XIDATONG_SDIO_AUTOMOUNT_BLKDEV - string "SD card block device" - default "/dev/mmcsd0" + string "SD card block device" + default "/dev/mmcsd0" config XIDATONG_SDIO_AUTOMOUNT_MOUNTPOINT - string "SD card mount point" - default "/mnt/sdcard" + string "SD card mount point" + default "/mnt/sdcard" config XIDATONG_SDIO_AUTOMOUNT_DDELAY - int "SD card debounce delay (milliseconds)" - default 1000 + int "SD card debounce delay (milliseconds)" + default 1000 config XIDATONG_SDIO_AUTOMOUNT_UDELAY - int "SD card unmount retry delay (milliseconds)" - default 2000 + int "SD card unmount retry delay (milliseconds)" + default 2000 endif # XIDATONG_SDIO_AUTOMOUNT config XIDATONG_USB_AUTOMOUNT - bool "USB Mass Storage automounter" - default n - depends on USBHOST_MSC && USBHOST_MSC_NOTIFIER + bool "USB Mass Storage automounter" + default n + depends on USBHOST_MSC && USBHOST_MSC_NOTIFIER if XIDATONG_USB_AUTOMOUNT config XIDATONG_USB_AUTOMOUNT_FSTYPE - string "USB file system type" - default "vfat" + string "USB file system type" + default "vfat" config XIDATONG_USB_AUTOMOUNT_BLKDEV - string "USB block device prefix" - default "/dev/sd" + string "USB block device prefix" + default "/dev/sd" config XIDATONG_USB_AUTOMOUNT_MOUNTPOINT - string "USB mount point prefix" - default "/mnt/usb" + string "USB mount point prefix" + default "/mnt/usb" config XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV - int "Number of block devices to monitor." - range 1 26 - default 4 + int "Number of block devices to monitor." + range 1 26 + default 4 config XIDATONG_USB_AUTOMOUNT_UDELAY - int "USB unmount retry delay (milliseconds)" - default 2000 + int "USB unmount retry delay (milliseconds)" + default 2000 endif # XIDATONG_USB_AUTOMOUNT +menuconfig BSP_USING_CH438 + bool "Using CH438 device" + default n -endif +if BSP_USING_CH438 +config CH438_EXTUART0 + bool "Using Ch438 Port 0" + default n + +menu "Ch438 Port 0 Configuration" + depends on CH438_EXTUART0 + + config CH438_EXTUART0_BAUD + int "Ch438 Port 0 Baud Rate." + default 115200 + ---help--- + The configured BAUD of the CH438 EXTUART0. +endmenu + +config CH438_EXTUART1 + bool "Using Ch438 Port 1" + default n + +menu "Ch438 Port 1 Configuration" + depends on CH438_EXTUART1 + + config CH438_EXTUART1_BAUD + int "Ch438 Port 1 Baud Rate." + default 115200 + ---help--- + The configured BAUD of the CH438 EXTUART1. +endmenu + +config CH438_EXTUART2 + bool "Using Ch438 Port 2" + default n + +menu "Ch438 Port 2 Configuration" + depends on CH438_EXTUART2 + + config CH438_EXTUART2_BAUD + int "Ch438 Port 2 Baud Rate." + default 115200 + ---help--- + The configured BAUD of the CH438 EXTUART2. +endmenu + +config CH438_EXTUART3 + bool "Using Ch438 Port 3" + default n + +menu "Ch438 Port 3 Configuration" + depends on CH438_EXTUART3 + + config CH438_EXTUART3_BAUD + int "Ch438 Port 3 Baud Rate." + default 115200 + ---help--- + The configured BAUD of the CH438 EXTUART3. +endmenu + +config CH438_EXTUART4 + bool "Using Ch438 Port 4" + default n + +menu "Ch438 Port 4 Configuration" + depends on CH438_EXTUART4 + + config CH438_EXTUART4_BAUD + int "Ch438 Port 4 Baud Rate." + default 115200 + ---help--- + The configured BAUD of the CH438 EXTUART4. +endmenu + +config CH438_EXTUART5 + bool "Using Ch438 Port 5" + default n + +menu "Ch438 Port 5 Configuration" + depends on CH438_EXTUART5 + + config CH438_EXTUART5_BAUD + int "Ch438 Port 5 Baud Rate." + default 115200 + ---help--- + The configured BAUD of the CH438 EXTUART5. +endmenu + +config CH438_EXTUART6 + bool "Using Ch438 Port 6" + default n + +menu "Ch438 Port 6 Configuration" + depends on CH438_EXTUART6 + + config CH438_EXTUART6_BAUD + int "Ch438 Port 6 Baud Rate." + default 115200 + ---help--- + The configured BAUD of the CH438 EXTUART6. +endmenu + +config CH438_EXTUART7 + bool "Using Ch438 Port 7" + default n + +menu "Ch438 Port 7 Configuration" + depends on CH438_EXTUART7 + + config CH438_EXTUART7_BAUD + int "Ch438 Port 7 Baud Rate." + default 115200 + ---help--- + The configured BAUD of the CH438 EXTUART7. +endmenu + +endif # BSP_USING_CH438 + +endif # ARCH_BOARD_XIDATONG diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/4gnsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/4gnsh/defconfig index baf142aa9..6239ffa42 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/4gnsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/4gnsh/defconfig @@ -22,7 +22,8 @@ CONFIG_BOARD_LOOPSPERMSEC=104926 CONFIG_BUILTIN=y CONFIG_CLOCK_MONOTONIC=y CONFIG_EXAMPLES_HELLO=y -CONFIG_FS_PROCFS=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_IMXRT_LPUART1=y CONFIG_INTELHEX_BINARY=y @@ -63,4 +64,5 @@ CONFIG_READLINE_TABCOMPLETION=y CONFIG_FS_ROMFS=y CONFIG_NSH_ROMFSETC=y CONFIG_NSH_ARCHROMFS=y +CONFIG_BOARDCTL_RESET=y CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/btnsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/btnsh/defconfig new file mode 100644 index 000000000..fff76d485 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/btnsh/defconfig @@ -0,0 +1,65 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_ADD_NUTTX_FETURES=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="xidatong" +CONFIG_ARCH_BOARD_XIDATONG=y +CONFIG_ARCH_CHIP="imxrt" +CONFIG_ARCH_CHIP_IMXRT=y +CONFIG_ARCH_CHIP_MIMXRT1052CVL5B=y +CONFIG_ARCH_INTERRUPTSTACK=10240 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARD_LOOPSPERMSEC=104926 +CONFIG_BUILTIN=y +CONFIG_CLOCK_MONOTONIC=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_IMXRT_LPUART1=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LPUART1_SERIAL_CONSOLE=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_RAM_SIZE=524288 +CONFIG_RAM_START=0x20200000 +CONFIG_RAW_BINARY=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=14 +CONFIG_START_MONTH=3 +CONFIG_SYSTEM_NSH=y +CONFIG_DEV_GPIO=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=100 +CONFIG_READLINE_CMD_HISTORY_LINELEN=120 +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_FS_ROMFS=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ARCHROMFS=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BSP_USING_CH438=y +CONFIG_CH438_EXTUART2=y +CONFIG_CH438_EXTUART2_BAUD=9600 +CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y +CONFIG_CONNECTION_FRAMEWORK_DEBUG=y +CONFIG_CONNECTION_ADAPTER_BLUETOOTH=y +CONFIG_ADAPTER_HC08=y +CONFIG_ADAPTER_BLUETOOTH_HC08="hc08" +CONFIG_ADAPTER_HC08_WORK_ROLE="M" +CONFIG_ADAPTER_HC08_DRIVER_EXTUART=y +CONFIG_ADAPTER_HC08_DRIVER="/dev/extuart_dev2" +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/knsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/knsh/defconfig index 03eb965cc..ed458a723 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/knsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/knsh/defconfig @@ -23,7 +23,8 @@ CONFIG_ARMV7M_USEBASEPRI=y CONFIG_ARM_MPU=y CONFIG_BOARD_LOOPSPERMSEC=104926 CONFIG_BUILD_PROTECTED=y -CONFIG_FS_PROCFS=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_IMXRT_LPUART1=y CONFIG_INTELHEX_BINARY=y @@ -52,4 +53,5 @@ CONFIG_READLINE_TABCOMPLETION=y CONFIG_FS_ROMFS=y CONFIG_NSH_ROMFSETC=y CONFIG_NSH_ARCHROMFS=y +CONFIG_BOARDCTL_RESET=y CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/lcdnsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/lcdnsh/defconfig new file mode 100755 index 000000000..7083d8a39 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/lcdnsh/defconfig @@ -0,0 +1,109 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_ADD_NUTTX_FETURES=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="xidatong" +CONFIG_ARCH_BOARD_XIDATONG=y +CONFIG_ARCH_CHIP="imxrt" +CONFIG_ARCH_CHIP_IMXRT=y +CONFIG_ARCH_CHIP_MIMXRT1052CVL5B=y +CONFIG_ARCH_INTERRUPTSTACK=10240 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARD_LOOPSPERMSEC=104926 +CONFIG_BUILTIN=y +CONFIG_CLOCK_MONOTONIC=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_IMXRT_LPUART1=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LPUART1_SERIAL_CONSOLE=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_RAM_SIZE=524288 +CONFIG_RAM_START=0x20200000 +CONFIG_RAW_BINARY=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=14 +CONFIG_START_MONTH=3 +CONFIG_SYSTEM_NSH=y +CONFIG_DEV_GPIO=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=100 +CONFIG_READLINE_CMD_HISTORY_LINELEN=120 +CONFIG_READLINE_TABCOMPLETION=y + +CONFIG_USER_ENTRYPOINT="nsh_main" + +CONFIG_IMXRT_LPI2C=y +CONFIG_IMXRT_LCD=y +CONFIG_IMXRT_LPI2C1=y +CONFIG_LPI2C1_BUSYIDLE=0 +CONFIG_LPI2C1_FILTSCL=0 +CONFIG_LPI2C1_FILTSDA=0 +CONFIG_IMXRT_GPIO2_16_31_IRQ=y + +CONFIG_IMXRT_LPI2C_DYNTIMEO=y +CONFIG_IMXRT_LPI2C_DYNTIMEO_USECPERBYTE=500 +CONFIG_IMXRT_LPI2C_DYNTIMEO_STARTSTOP=1000 +CONFIG_IMXRT_LPI2C_TIMEOSEC=0 +CONFIG_IMXRT_LCD_VIDEO_PLL_FREQ=92000000 +CONFIG_IMXRT_LCD_VRAMBASE=0x80000000 +CONFIG_IMXRT_LCD_REFRESH_FREQ=60 +CONFIG_IMXRT_LCD_BACKLIGHT=y +CONFIG_IMXRT_LCD_INPUT_BPP16=y +CONFIG_IMXRT_LCD_OUTPUT_16=y +CONFIG_IMXRT_LCD_BACKCOLOR=0x0 +CONFIG_IMXRT_LCD_HWIDTH=480 +CONFIG_IMXRT_LCD_HPULSE=41 +CONFIG_IMXRT_LCD_HFRONTPORCH=4 +CONFIG_IMXRT_LCD_HBACKPORCH=8 +CONFIG_IMXRT_LCD_VHEIGHT=272 +CONFIG_IMXRT_LCD_VPULSE=10 +CONFIG_IMXRT_LCD_VFRONTPORCH=4 +CONFIG_IMXRT_LCD_VBACKPORCH=2 +CONFIG_IMXRT_DATAEN_ACTIVE_HIGH=y +CONFIG_IMXRT_DATA_RISING_EDGE=y + +CONFIG_I2C=y +CONFIG_I2C_DRIVER=y +CONFIG_ARCH_HAVE_SPI_CS_CONTROL=y +CONFIG_SPI=y +CONFIG_SPI_EXCHANGE=y + +CONFIG_FB_MODULEINFO=y +CONFIG_DRIVERS_VIDEO=y +CONFIG_VIDEO_FB=y +CONFIG_INPUT=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_GT9XX=y + +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_MAX_TASKS=128 +CONFIG_FS_PROCFS_EXCLUDE_ENVIRON=y + +CONFIG_EXAMPLES_FB=y +CONFIG_EXAMPLES_FB_DEFAULTFB="/dev/fb0" +CONFIG_EXAMPLES_FB_PROGNAME="fb" +CONFIG_EXAMPLES_FB_PRIORITY=100 +CONFIG_EXAMPLES_FB_STACKSIZE=2048 + +CONFIG_EXAMPLES_TOUCHSCREEN=y +CONFIG_EXAMPLES_TOUCHSCREEN_MINOR=0 +CONFIG_EXAMPLES_TOUCHSCREEN_DEVPATH="/dev/input0" +CONFIG_EXAMPLES_TOUCHSCREEN_NSAMPLES=0 + diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/libcxxtest/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/libcxxtest/defconfig index 2737d7971..f347bad94 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/libcxxtest/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/libcxxtest/defconfig @@ -19,7 +19,8 @@ CONFIG_BOARD_LOOPSPERMSEC=20000 CONFIG_BUILTIN=y CONFIG_CLOCK_MONOTONIC=y CONFIG_C99_BOOL8=y -CONFIG_FS_PROCFS=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y CONFIG_HAVE_CXX=y CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_IMXRT_LPUART1=y @@ -51,4 +52,5 @@ CONFIG_READLINE_TABCOMPLETION=y CONFIG_FS_ROMFS=y CONFIG_NSH_ROMFSETC=y CONFIG_NSH_ARCHROMFS=y +CONFIG_BOARDCTL_RESET=y CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/loransh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/loransh/defconfig new file mode 100644 index 000000000..7d41f2298 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/loransh/defconfig @@ -0,0 +1,65 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_ADD_NUTTX_FETURES=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="xidatong" +CONFIG_ARCH_BOARD_XIDATONG=y +CONFIG_ARCH_CHIP="imxrt" +CONFIG_ARCH_CHIP_IMXRT=y +CONFIG_ARCH_CHIP_MIMXRT1052CVL5B=y +CONFIG_ARCH_INTERRUPTSTACK=10240 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARD_LOOPSPERMSEC=104926 +CONFIG_BUILTIN=y +CONFIG_CLOCK_MONOTONIC=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_IMXRT_LPUART1=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LPUART1_SERIAL_CONSOLE=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_RAM_SIZE=524288 +CONFIG_RAM_START=0x20200000 +CONFIG_RAW_BINARY=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=14 +CONFIG_START_MONTH=3 +CONFIG_SYSTEM_NSH=y +CONFIG_DEV_GPIO=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=100 +CONFIG_READLINE_CMD_HISTORY_LINELEN=120 +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_FS_ROMFS=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ARCHROMFS=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BSP_USING_CH438=y +CONFIG_CH438_EXTUART3=y +CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y +CONFIG_CONNECTION_FRAMEWORK_DEBUG=y +CONFIG_CONNECTION_ADAPTER_LORA=y +CONFIG_ADAPTER_E220=y +CONFIG_ADAPTER_LORA_E220="e220" +CONFIG_ADAPTER_E220_DRIVER_EXTUART=y +CONFIG_ADAPTER_E220_DRIVER="/dev/extuart_dev3" +CONFIG_ADAPTER_E220_M0_PATH="/dev/gpout0" +CONFIG_ADAPTER_E220_M1_PATH="/dev/gpout1" +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/netnsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/netnsh/defconfig index c0d86ffac..901df0b65 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/netnsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/netnsh/defconfig @@ -24,7 +24,8 @@ CONFIG_BUILTIN=y CONFIG_CLOCK_MONOTONIC=y CONFIG_ETH0_PHY_LAN8720=y CONFIG_IMXRT_ENET_PHYINIT=y -CONFIG_FS_PROCFS=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_IMXRT_ENET=y CONFIG_IMXRT_LPUART1=y @@ -74,4 +75,5 @@ CONFIG_READLINE_TABCOMPLETION=y CONFIG_FS_ROMFS=y CONFIG_NSH_ROMFSETC=y CONFIG_NSH_ARCHROMFS=y +CONFIG_BOARDCTL_RESET=y CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/nsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/nsh/defconfig index 1eab6804c..a03e3c01f 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/nsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/nsh/defconfig @@ -22,7 +22,8 @@ CONFIG_BOARD_LOOPSPERMSEC=104926 CONFIG_BUILTIN=y CONFIG_CLOCK_MONOTONIC=y CONFIG_EXAMPLES_HELLO=y -CONFIG_FS_PROCFS=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_IMXRT_LPUART1=y CONFIG_INTELHEX_BINARY=y @@ -49,4 +50,5 @@ CONFIG_READLINE_TABCOMPLETION=y CONFIG_FS_ROMFS=y CONFIG_NSH_ROMFSETC=y CONFIG_NSH_ARCHROMFS=y +CONFIG_BOARDCTL_RESET=y CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/sdionsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/sdionsh/defconfig index 3cad4773c..8f33ec725 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/sdionsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/sdionsh/defconfig @@ -24,11 +24,11 @@ CONFIG_FAT_LCNAMES=y CONFIG_CLOCK_MONOTONIC=y CONFIG_FAT_LFN=y CONFIG_FS_FAT=y -CONFIG_FS_PROCFS=y CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_EXAMPLES_HELLO=y -CONFIG_IMXRT_GPIO2_16_31_IRQ=y CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO2_16_31_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y CONFIG_DEV_GPIO=y CONFIG_IMXRT_LPUART1=y CONFIG_IMXRT_USDHC1=y @@ -45,7 +45,7 @@ CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_CMDOPT_DD_STATS=y CONFIG_NSH_DISABLE_IFUPDOWN=y -CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_FILEIOSIZE=32768 CONFIG_NSH_LINELEN=64 CONFIG_NSH_READLINE=y CONFIG_RAM_SIZE=524288 @@ -63,12 +63,11 @@ CONFIG_START_MONTH=3 CONFIG_SYSTEM_CLE_CMD_HISTORY=y CONFIG_SYSTEM_COLOR_CLE=y CONFIG_FS_AUTOMOUNTER=y +CONFIG_XIDATONG_SDIO_AUTOMOUNT=y CONFIG_SYSTEM_NSH=y CONFIG_READLINE_CMD_HISTORY=y CONFIG_READLINE_CMD_HISTORY_LEN=100 CONFIG_READLINE_CMD_HISTORY_LINELEN=120 CONFIG_READLINE_TABCOMPLETION=y -CONFIG_FS_ROMFS=y -CONFIG_NSH_ROMFSETC=y -CONFIG_NSH_ARCHROMFS=y +CONFIG_BOARDCTL_RESET=y CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/usbnsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/usbnsh/defconfig index be725e890..0b3687f87 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/usbnsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/usbnsh/defconfig @@ -24,9 +24,10 @@ CONFIG_FAT_LCNAMES=y CONFIG_CLOCK_MONOTONIC=y CONFIG_FAT_LFN=y CONFIG_FS_FAT=y -CONFIG_FS_PROCFS=y CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_EXAMPLES_HELLO=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y CONFIG_IMXRT_LPUART1=y CONFIG_INTELHEX_BINARY=y CONFIG_IOB_NBUFFERS=24 @@ -38,7 +39,7 @@ CONFIG_NSH_ARCHINIT=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_CMDOPT_DD_STATS=y CONFIG_NSH_DISABLE_IFUPDOWN=y -CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_FILEIOSIZE=32768 CONFIG_NSH_LINELEN=64 CONFIG_NSH_READLINE=y CONFIG_RAM_SIZE=524288 @@ -61,12 +62,11 @@ CONFIG_USBDEV=y CONFIG_USBHOST=y CONFIG_USBHOST_MSC=y CONFIG_USBHOST_MSC_NOTIFIER=y +CONFIG_XIDATONG_USB_AUTOMOUNT=y CONFIG_DEV_GPIO=y CONFIG_READLINE_CMD_HISTORY=y CONFIG_READLINE_CMD_HISTORY_LEN=100 CONFIG_READLINE_CMD_HISTORY_LINELEN=120 CONFIG_READLINE_TABCOMPLETION=y -CONFIG_FS_ROMFS=y -CONFIG_NSH_ROMFSETC=y -CONFIG_NSH_ARCHROMFS=y +CONFIG_BOARDCTL_RESET=y CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/wifinsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/wifinsh/defconfig new file mode 100755 index 000000000..9f77feaf2 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/wifinsh/defconfig @@ -0,0 +1,61 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_ADD_NUTTX_FETURES=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="xidatong" +CONFIG_ARCH_BOARD_XIDATONG=y +CONFIG_ARCH_CHIP="imxrt" +CONFIG_ARCH_CHIP_IMXRT=y +CONFIG_ARCH_CHIP_MIMXRT1052CVL5B=y +CONFIG_ARCH_INTERRUPTSTACK=10240 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARD_LOOPSPERMSEC=104926 +CONFIG_BUILTIN=y +CONFIG_CLOCK_MONOTONIC=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_IMXRT_LPUART1=y +CONFIG_IMXRT_LPUART2=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LPUART1_SERIAL_CONSOLE=y +CONFIG_LPUART2_SERIALDRIVER=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_RAM_SIZE=524288 +CONFIG_RAM_START=0x20200000 +CONFIG_RAW_BINARY=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=14 +CONFIG_START_MONTH=3 +CONFIG_SYSTEM_NSH=y +CONFIG_DEV_GPIO=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=100 +CONFIG_READLINE_CMD_HISTORY_LINELEN=120 +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_FS_ROMFS=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ARCHROMFS=y +CONFIG_BOARDCTL_RESET=y +CONFIG_CONNECTION_FRAMEWORK_DEBUG=y +CONFIG_CONNECTION_ADAPTER_WIFI=y +CONFIG_ADAPTER_ESP07S_WIFI=y +CONFIG_ADAPTER_WIFI_ESP07S="esp07s_wifi" +CONFIG_ADAPTER_ESP07S_DRIVER="/dev/ttyS2" +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/zbnsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/zbnsh/defconfig new file mode 100755 index 000000000..deb156dfa --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/zbnsh/defconfig @@ -0,0 +1,64 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +CONFIG_ADD_NUTTX_FETURES=y +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="xidatong" +CONFIG_ARCH_BOARD_XIDATONG=y +CONFIG_ARCH_CHIP="imxrt" +CONFIG_ARCH_CHIP_IMXRT=y +CONFIG_ARCH_CHIP_MIMXRT1052CVL5B=y +CONFIG_ARCH_INTERRUPTSTACK=10240 +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARD_LOOPSPERMSEC=104926 +CONFIG_BUILTIN=y +CONFIG_CLOCK_MONOTONIC=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_IMXRT_LPUART1=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LPUART1_SERIAL_CONSOLE=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_RAM_SIZE=524288 +CONFIG_RAM_START=0x20200000 +CONFIG_RAW_BINARY=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=14 +CONFIG_START_MONTH=3 +CONFIG_SYSTEM_NSH=y +CONFIG_DEV_GPIO=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=100 +CONFIG_READLINE_CMD_HISTORY_LINELEN=120 +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_FS_ROMFS=y +CONFIG_NSH_ROMFSETC=y +CONFIG_NSH_ARCHROMFS=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BSP_USING_CH438=y +CONFIG_CH438_EXTUART1=y +CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y +CONFIG_CONNECTION_FRAMEWORK_DEBUG=y +CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y +CONFIG_CONNECTION_ADAPTER_ZIGBEE=y +CONFIG_ADAPTER_E18=y +CONFIG_ADAPTER_ZIGBEE_E18="e18" +CONFIG_AS_END_DEVICE_ROLE=y +CONFIG_ADAPTER_E18_DRIVER="/dev/extuart_dev1" +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/Makefile index 6ab31a006..528b9f1cc 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/Makefile +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/Makefile @@ -32,6 +32,10 @@ else ifeq ($(CONFIG_BOARD_LATE_INITIALIZE),y) CSRCS += imxrt_bringup.c endif +ifeq ($(CONFIG_BOARDCTL_RESET),y) +CSRCS += imxrt_reset.c +endif + ifeq ($(CONFIG_ARCH_LEDS),y) CSRCS += imxrt_autoleds.c else @@ -78,4 +82,12 @@ ifeq ($(CONFIG_XIDATONG_SDIO_AUTOMOUNT),y) CSRCS += imxrt_mmcsd_automount.c endif +ifeq ($(CONFIG_INPUT_GT9XX),y) +CSRCS += imxrt_gt9xx.c +endif + +ifeq ($(CONFIG_BSP_USING_CH438),y) +CSRCS += imxrt_ch438.c ch438_demo.c +endif + include $(TOPDIR)/boards/Board.mk diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/ch438_demo.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/ch438_demo.c new file mode 100644 index 000000000..c3b574e18 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/ch438_demo.c @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file ch438_demo.c + * @brief imxrt board sd card automount + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.04.26 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include "imxrt_ch438.h" +#include +#include + +void CH438Demo(void) +{ + int fd,m0fd,m1fd; + int i; + char sendbuffer1[4] = {0xC0,0x04,0x01,0x09}; + char sendbuffer2[6] = {0xC0,0x00,0x03,0x12,0x34,0x61}; + char sendbuffer3[3] = {0xC1,0x04,0x01}; + char sendbuffer4[3] = {0xC1,0x00,0x03}; + char buffer[256]; + int readlen; + + fd = open("/dev/extuart_dev3", O_RDWR); + ioctl(fd, OPE_INT, (unsigned long)9600); + m0fd = open("/dev/gpout0", O_RDWR); + m1fd = open("/dev/gpout1", O_RDWR); + ioctl(m0fd, GPIOC_WRITE, (unsigned long)1); + ioctl(m1fd, GPIOC_WRITE, (unsigned long)1); + sleep(1); + + write(fd, sendbuffer1,4); + sleep(1); + readlen = read(fd, buffer, 256); + printf("readlen1 = %d\n", readlen); + for(i = 0;i< readlen; ++i) + { + printf("0x%x\n", buffer[i]); + } + + write(fd, sendbuffer2,6); + sleep(1); + readlen = read(fd, buffer, 256); + printf("readlen1 = %d\n", readlen); + for(i = 0;i< readlen; ++i) + { + printf("0x%x\n", buffer[i]); + } + + write(fd, sendbuffer3,3); + sleep(1); + readlen = read(fd, buffer, 256); + printf("readlen1 = %d\n", readlen); + for(i = 0;i< readlen; ++i) + { + printf("0x%x\n", buffer[i]); + } + + write(fd, sendbuffer4,3); + sleep(1); + readlen = read(fd, buffer, 256); + printf("readlen1 = %d\n", readlen); + for(i = 0;i< readlen; ++i) + { + printf("0x%x\n", buffer[i]); + } + + close(fd); + +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_bringup.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_bringup.c index 2aab9d081..18922681b 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_bringup.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_bringup.c @@ -47,6 +47,14 @@ # include #endif +#ifdef CONFIG_BSP_USING_CH438 +# include "imxrt_ch438.h" +#endif + +#ifdef CONFIG_INPUT_GT9XX +#include "imxrt_gt9xx.h" +#endif + #include "xidatong.h" #include /* Must always be included last */ @@ -148,7 +156,6 @@ int imxrt_bringup(void) if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to start USB host services: %d\n", ret); - return ret; } #endif @@ -167,7 +174,6 @@ int imxrt_bringup(void) if (ret < 0) { syslog(LOG_ERR, "Failed to initialize GPIO Driver: %d\n", ret); - return ret; } #endif @@ -181,6 +187,23 @@ int imxrt_bringup(void) } #endif +#ifdef CONFIG_BSP_USING_CH438 + board_ch438_initialize(); +#endif + +#ifdef CONFIG_INPUT_GT9XX + /* Initialize the GT9XX touchscreen driver */ + + ret = imxrt_gt9xx_register(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: imxrt_ft5x06_register() failed: %d\n", ret); + } + + syslog(LOG_NOTICE, "Start initialize %d ok ...\n", ret); + +#endif + UNUSED(ret); return OK; } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_ch438.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_ch438.c new file mode 100644 index 000000000..2b651eedd --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_ch438.c @@ -0,0 +1,891 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imxrt_ch438.c + * @brief imxrt board sd card automount + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.04.26 + */ + +#include "imxrt_ch438.h" + +#define CH438PORTNUM 8 +#define CH438_BUFFSIZE 256 +#define CH438_INCREMENT MSEC2TICK(33) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +static FAR void getInterruptStatus(FAR void *arg); +static void CH438SetOutput(void); +static void CH438SetInput(void); +static uint8_t ReadCH438Data(uint8_t addr); +static void WriteCH438Data(uint8_t addr, const uint8_t dat); +static void WriteCH438Block(uint8_t mAddr, uint8_t mLen, const uint8_t *mBuf); +static void Ch438UartSend(uint8_t ext_uart_no, const uint8_t *Data, uint16_t Num); +uint8_t CH438UARTRcv(uint8_t ext_uart_no, uint8_t *buf, size_t size); +static void ImxrtCH438Init(void); +static void CH438PortInit(uint8_t ext_uart_no, uint32_t baud_rate); +static int ImxrtCh438WriteData(uint8_t ext_uart_no, const uint8_t *write_buffer, size_t size); +static size_t ImxrtCh438ReadData(uint8_t ext_uart_no, size_t size); +static void Ch438InitDefault(void); + +static int ch438_open(FAR struct file *filep); +static int ch438_close(FAR struct file *filep); +static ssize_t ch438_read(FAR struct file *filep, FAR char *buffer, size_t buflen); +static ssize_t ch438_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); +static int ch438_ioctl(FAR struct file *filep, int cmd, unsigned long arg); +static int ch438_register(FAR const char *devpath, uint8_t ext_uart_no); + +/**************************************************************************** + * Private type + ****************************************************************************/ +struct ch438_dev_s +{ + sem_t devsem; /* ch438 port devsem */ + uint8_t port; /* ch438 port number*/ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/*mutex of corresponding port*/ +static pthread_mutex_t mutex[CH438PORTNUM] = +{ + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER +}; + +/* Condition variable of corresponding port */ +static pthread_cond_t cond[CH438PORTNUM] = +{ + PTHREAD_COND_INITIALIZER, + PTHREAD_COND_INITIALIZER, + PTHREAD_COND_INITIALIZER, + PTHREAD_COND_INITIALIZER, + PTHREAD_COND_INITIALIZER, + PTHREAD_COND_INITIALIZER, + PTHREAD_COND_INITIALIZER, + PTHREAD_COND_INITIALIZER +}; + +/* This array shows whether the current serial port is selected */ +static bool const g_uart_selected[CH438PORTNUM] = +{ +#ifdef CONFIG_CH438_EXTUART0 + [0] = true, +#endif +#ifdef CONFIG_CH438_EXTUART1 + [1] = true, +#endif +#ifdef CONFIG_CH438_EXTUART2 + [2] = true, +#endif +#ifdef CONFIG_CH438_EXTUART3 + [3] = true, +#endif +#ifdef CONFIG_CH438_EXTUART4 + [4] = true, +#endif +#ifdef CONFIG_CH438_EXTUART5 + [5] = true, +#endif +#ifdef CONFIG_CH438_EXTUART6 + [6] = true, +#endif +#ifdef CONFIG_CH438_EXTUART7 + [7] = true, +#endif +}; + +/* ch438 Callback work queue structure */ +static struct work_s g_ch438irqwork; + +/* there is data available on the corresponding port */ +static volatile bool done[CH438PORTNUM] = {false,false,false,false,false,false,false,false}; + +/* Eight port data buffer */ +static uint8_t buff[CH438PORTNUM][CH438_BUFFSIZE]; + +/* the value of interrupt number of SSR register */ +static uint8_t Interruptnum[CH438PORTNUM] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,}; + +/* Offset address of serial port number */ +static uint8_t offsetadd[CH438PORTNUM] = {0x00,0x10,0x20,0x30,0x08,0x18,0x28,0x38,}; + +/* port open status global variable */ +static volatile bool g_ch438open[CH438PORTNUM] = {false,false,false,false,false,false,false,false}; + +/* Ch438 POSIX interface */ +static const struct file_operations g_ch438fops = +{ + ch438_open, + ch438_close, + ch438_read, + ch438_write, + NULL, + ch438_ioctl, + NULL +}; + +/**************************************************************************** + * Name: getInterruptStatus + * + * Description: + * thread task getInterruptStatus + * + ****************************************************************************/ +static FAR void getInterruptStatus(FAR void *arg) +{ + uint8_t i; + uint8_t gInterruptStatus; /* Interrupt register status */ + + gInterruptStatus = ReadCH438Data(REG_SSR_ADDR); + + if(gInterruptStatus) + { + for(i = 0; i < CH438PORTNUM; i++) + { + if(g_uart_selected[i] && (gInterruptStatus & Interruptnum[i])) + { + pthread_mutex_lock(&mutex[i]); + done[i] = true; + pthread_cond_signal(&cond[i]); + pthread_mutex_unlock(&mutex[i]); + } + } + } + + work_queue(HPWORK, &g_ch438irqwork, getInterruptStatus, NULL, CH438_INCREMENT); +} + +/**************************************************************************** + * Name: CH438SetOutput + * + * Description: + * Configure pin mode to output + * + ****************************************************************************/ +static void CH438SetOutput(void) +{ + imxrt_config_gpio(CH438_D0_PIN_OUT); + imxrt_config_gpio(CH438_D1_PIN_OUT); + imxrt_config_gpio(CH438_D2_PIN_OUT); + imxrt_config_gpio(CH438_D3_PIN_OUT); + imxrt_config_gpio(CH438_D4_PIN_OUT); + imxrt_config_gpio(CH438_D5_PIN_OUT); + imxrt_config_gpio(CH438_D6_PIN_OUT); + imxrt_config_gpio(CH438_D7_PIN_OUT); +} + +/**************************************************************************** + * Name: CH438SetInput + * + * Description: + * Configure pin mode to input + * + ****************************************************************************/ +static void CH438SetInput(void) +{ + imxrt_config_gpio(CH438_D0_PIN_INPUT); + imxrt_config_gpio(CH438_D1_PIN_INPUT); + imxrt_config_gpio(CH438_D2_PIN_INPUT); + imxrt_config_gpio(CH438_D3_PIN_INPUT); + imxrt_config_gpio(CH438_D4_PIN_INPUT); + imxrt_config_gpio(CH438_D5_PIN_INPUT); + imxrt_config_gpio(CH438_D6_PIN_INPUT); + imxrt_config_gpio(CH438_D7_PIN_INPUT); +} + +/**************************************************************************** + * Name: ReadCH438Data + * + * Description: + * Read data from ch438 address + * + ****************************************************************************/ +static uint8_t ReadCH438Data(uint8_t addr) +{ + uint8_t dat = 0; + imxrt_gpio_write(CH438_NWR_PIN, true); + imxrt_gpio_write(CH438_NRD_PIN, true); + imxrt_gpio_write(CH438_ALE_PIN, true); + + CH438SetOutput(); + up_udelay(1); + + if(addr &0x80) imxrt_gpio_write(CH438_D7_PIN_OUT, true); else imxrt_gpio_write(CH438_D7_PIN_OUT, false); + if(addr &0x40) imxrt_gpio_write(CH438_D6_PIN_OUT, true); else imxrt_gpio_write(CH438_D6_PIN_OUT, false); + if(addr &0x20) imxrt_gpio_write(CH438_D5_PIN_OUT, true); else imxrt_gpio_write(CH438_D5_PIN_OUT, false); + if(addr &0x10) imxrt_gpio_write(CH438_D4_PIN_OUT, true); else imxrt_gpio_write(CH438_D4_PIN_OUT, false); + if(addr &0x08) imxrt_gpio_write(CH438_D3_PIN_OUT, true); else imxrt_gpio_write(CH438_D3_PIN_OUT, false); + if(addr &0x04) imxrt_gpio_write(CH438_D2_PIN_OUT, true); else imxrt_gpio_write(CH438_D2_PIN_OUT, false); + if(addr &0x02) imxrt_gpio_write(CH438_D1_PIN_OUT, true); else imxrt_gpio_write(CH438_D1_PIN_OUT, false); + if(addr &0x01) imxrt_gpio_write(CH438_D0_PIN_OUT, true); else imxrt_gpio_write(CH438_D0_PIN_OUT, false); + + up_udelay(1); + + imxrt_gpio_write(CH438_ALE_PIN, false); + up_udelay(1); + + CH438SetInput(); + up_udelay(1); + + imxrt_gpio_write(CH438_NRD_PIN, false); + up_udelay(1); + + if (imxrt_gpio_read(CH438_D7_PIN_INPUT)) dat |= 0x80; + if (imxrt_gpio_read(CH438_D6_PIN_INPUT)) dat |= 0x40; + if (imxrt_gpio_read(CH438_D5_PIN_INPUT)) dat |= 0x20; + if (imxrt_gpio_read(CH438_D4_PIN_INPUT)) dat |= 0x10; + if (imxrt_gpio_read(CH438_D3_PIN_INPUT)) dat |= 0x08; + if (imxrt_gpio_read(CH438_D2_PIN_INPUT)) dat |= 0x04; + if (imxrt_gpio_read(CH438_D1_PIN_INPUT)) dat |= 0x02; + if (imxrt_gpio_read(CH438_D0_PIN_INPUT)) dat |= 0x01; + + imxrt_gpio_write(CH438_NRD_PIN, true); + imxrt_gpio_write(CH438_ALE_PIN, true); + up_udelay(1); + + return dat; +} + +/**************************************************************************** + * Name: WriteCH438Data + * + * Description: + * write data to ch438 address + * + ****************************************************************************/ +static void WriteCH438Data(uint8_t addr, const uint8_t dat) +{ + imxrt_gpio_write(CH438_ALE_PIN, true); + imxrt_gpio_write(CH438_NRD_PIN, true); + imxrt_gpio_write(CH438_NWR_PIN, true); + + CH438SetOutput(); + up_udelay(1); + + if(addr &0x80) imxrt_gpio_write(CH438_D7_PIN_OUT, true); else imxrt_gpio_write(CH438_D7_PIN_OUT, false); + if(addr &0x40) imxrt_gpio_write(CH438_D6_PIN_OUT, true); else imxrt_gpio_write(CH438_D6_PIN_OUT, false); + if(addr &0x20) imxrt_gpio_write(CH438_D5_PIN_OUT, true); else imxrt_gpio_write(CH438_D5_PIN_OUT, false); + if(addr &0x10) imxrt_gpio_write(CH438_D4_PIN_OUT, true); else imxrt_gpio_write(CH438_D4_PIN_OUT, false); + if(addr &0x08) imxrt_gpio_write(CH438_D3_PIN_OUT, true); else imxrt_gpio_write(CH438_D3_PIN_OUT, false); + if(addr &0x04) imxrt_gpio_write(CH438_D2_PIN_OUT, true); else imxrt_gpio_write(CH438_D2_PIN_OUT, false); + if(addr &0x02) imxrt_gpio_write(CH438_D1_PIN_OUT, true); else imxrt_gpio_write(CH438_D1_PIN_OUT, false); + if(addr &0x01) imxrt_gpio_write(CH438_D0_PIN_OUT, true); else imxrt_gpio_write(CH438_D0_PIN_OUT, false); + + up_udelay(1); + + imxrt_gpio_write(CH438_ALE_PIN, false); + up_udelay(1); + + if(dat &0x80) imxrt_gpio_write(CH438_D7_PIN_OUT, true); else imxrt_gpio_write(CH438_D7_PIN_OUT, false); + if(dat &0x40) imxrt_gpio_write(CH438_D6_PIN_OUT, true); else imxrt_gpio_write(CH438_D6_PIN_OUT, false); + if(dat &0x20) imxrt_gpio_write(CH438_D5_PIN_OUT, true); else imxrt_gpio_write(CH438_D5_PIN_OUT, false); + if(dat &0x10) imxrt_gpio_write(CH438_D4_PIN_OUT, true); else imxrt_gpio_write(CH438_D4_PIN_OUT, false); + if(dat &0x08) imxrt_gpio_write(CH438_D3_PIN_OUT, true); else imxrt_gpio_write(CH438_D3_PIN_OUT, false); + if(dat &0x04) imxrt_gpio_write(CH438_D2_PIN_OUT, true); else imxrt_gpio_write(CH438_D2_PIN_OUT, false); + if(dat &0x02) imxrt_gpio_write(CH438_D1_PIN_OUT, true); else imxrt_gpio_write(CH438_D1_PIN_OUT, false); + if(dat &0x01) imxrt_gpio_write(CH438_D0_PIN_OUT, true); else imxrt_gpio_write(CH438_D0_PIN_OUT, false); + + up_udelay(1); + + imxrt_gpio_write(CH438_NWR_PIN, false); + up_udelay(1); + + imxrt_gpio_write(CH438_NWR_PIN, true); + imxrt_gpio_write(CH438_ALE_PIN, true); + up_udelay(1); + + CH438SetInput(); + + return; +} + +/**************************************************************************** + * Name: WriteCH438Block + * + * Description: + * Write data block from ch438 address + * + ****************************************************************************/ +static void WriteCH438Block(uint8_t mAddr, uint8_t mLen, const uint8_t *mBuf) +{ + while(mLen--) + WriteCH438Data(mAddr, *mBuf++); +} + +/**************************************************************************** + * Name: CH438UARTSend + * + * Description: + * Enable FIFO mode, which is used for ch438 serial port to send multi byte data, + * with a maximum of 128 bytes of data sent at a time + * + ****************************************************************************/ +static void Ch438UartSend(uint8_t ext_uart_no, const uint8_t *Data, uint16_t Num) +{ + uint8_t REG_LSR_ADDR,REG_THR_ADDR; + REG_LSR_ADDR = offsetadd[ext_uart_no] | REG_LSR0_ADDR; + REG_THR_ADDR = offsetadd[ext_uart_no] | REG_THR0_ADDR; + + while(1) + { + while((ReadCH438Data(REG_LSR_ADDR) & BIT_LSR_TEMT) == 0); /* wait for sending data done, THR and TSR is NULL */ + if(Num <= 128) + { + WriteCH438Block(REG_THR_ADDR, Num, Data); + break; + } + else + { + WriteCH438Block(REG_THR_ADDR, 128, Data); + Num -= 128; + Data += 128; + } + } +} + +/**************************************************************************** + * Name: CH438UARTRcv + * + * Description: + * Disable FIFO mode for ch438 serial port to receive multi byte data + * + ****************************************************************************/ +uint8_t CH438UARTRcv(uint8_t ext_uart_no, uint8_t *buf, size_t size) +{ + uint8_t rcv_num = 0; + uint8_t dat = 0; + uint8_t REG_LSR_ADDR,REG_RBR_ADDR; + uint8_t *read_buffer; + size_t buffer_index = 0; + + read_buffer = buf; + + REG_LSR_ADDR = offsetadd[ext_uart_no] | REG_LSR0_ADDR; + REG_RBR_ADDR = offsetadd[ext_uart_no] | REG_RBR0_ADDR; + + /* Wait for the data to be ready */ + while ((ReadCH438Data(REG_LSR_ADDR) & BIT_LSR_DATARDY) == 0); + + while (((ReadCH438Data(REG_LSR_ADDR) & BIT_LSR_DATARDY) == 0x01) && (size != 0)) + { + dat = ReadCH438Data(REG_RBR_ADDR); + *read_buffer = dat; + read_buffer++; + buffer_index++; + if (255 == buffer_index) { + buffer_index = 0; + read_buffer = buf; + } + + ++rcv_num; + --size; + } + + return rcv_num; +} + +/**************************************************************************** + * Name: ImxrtCH438Init + * + * Description: + * ch438 initialization + * + ****************************************************************************/ +static void ImxrtCH438Init(void) +{ + CH438SetOutput(); + imxrt_config_gpio(CH438_NWR_PIN); + imxrt_config_gpio(CH438_NRD_PIN); + imxrt_config_gpio(CH438_ALE_PIN); + + imxrt_gpio_write(CH438_NWR_PIN,true); + imxrt_gpio_write(CH438_NRD_PIN,true); + imxrt_gpio_write(CH438_ALE_PIN,true); +} + +/**************************************************************************** + * Name: CH438PortInit + * + * Description: + * ch438 port initialization + * + ****************************************************************************/ +static void CH438PortInit(uint8_t ext_uart_no, uint32_t baud_rate) +{ + uint32_t div; + uint8_t DLL,DLM,dlab; + uint8_t REG_LCR_ADDR; + uint8_t REG_DLL_ADDR; + uint8_t REG_DLM_ADDR; + uint8_t REG_IER_ADDR; + uint8_t REG_MCR_ADDR; + uint8_t REG_FCR_ADDR; + + REG_LCR_ADDR = offsetadd[ext_uart_no] | REG_LCR0_ADDR; + REG_DLL_ADDR = offsetadd[ext_uart_no] | REG_DLL0_ADDR; + REG_DLM_ADDR = offsetadd[ext_uart_no] | REG_DLM0_ADDR; + REG_IER_ADDR = offsetadd[ext_uart_no] | REG_IER0_ADDR; + REG_MCR_ADDR = offsetadd[ext_uart_no] | REG_MCR0_ADDR; + REG_FCR_ADDR = offsetadd[ext_uart_no] | REG_FCR0_ADDR; + + /* reset the uart */ + WriteCH438Data(REG_IER_ADDR, BIT_IER_RESET); + up_mdelay(50); + + dlab = ReadCH438Data(REG_IER_ADDR); + dlab &= 0xDF; + WriteCH438Data(REG_IER_ADDR, dlab); + + /* set LCR register DLAB bit 1 */ + dlab = ReadCH438Data(REG_LCR_ADDR); + dlab |= 0x80; + WriteCH438Data(REG_LCR_ADDR, dlab); + + div = (Fpclk >> 4) / baud_rate; + DLM = div >> 8; + DLL = div & 0xff; + + /* set bps */ + WriteCH438Data(REG_DLL_ADDR, DLL); + WriteCH438Data(REG_DLM_ADDR, DLM); + + /* set FIFO mode, 112 bytes */ + WriteCH438Data(REG_FCR_ADDR, BIT_FCR_RECVTG1 | BIT_FCR_RECVTG0 | BIT_FCR_FIFOEN); + + /* 8 bit word size, 1 bit stop bit, no crc */ + WriteCH438Data(REG_LCR_ADDR, BIT_LCR_WORDSZ1 | BIT_LCR_WORDSZ0); + + /* enable interrupt */ + WriteCH438Data(REG_IER_ADDR, BIT_IER_IERECV); + + /* allow interrupt output, DTR and RTS is 1 */ + WriteCH438Data(REG_MCR_ADDR, BIT_MCR_OUT2); + + /* release the data in FIFO */ + WriteCH438Data(REG_FCR_ADDR, ReadCH438Data(REG_FCR_ADDR)| BIT_FCR_TFIFORST); +} + +/**************************************************************************** + * Name: ImxrtCh438ReadData + * + * Description: + * Read data from ch438 port + * + ****************************************************************************/ +static int ImxrtCh438WriteData(uint8_t ext_uart_no, const uint8_t *write_buffer, size_t size) +{ + int write_len, write_len_continue; + int i, write_index; + DEBUGASSERT(write_buffer != NULL); + + write_len = size; + write_len_continue = size; + + if(write_len > 256) + { + if(0 == write_len % 256) + { + write_index = write_len / 256; + for(i = 0; i < write_index; i ++) + { + Ch438UartSend(ext_uart_no, write_buffer + i * 256, 256); + } + } + else + { + write_index = 0; + while(write_len_continue > 256) + { + Ch438UartSend(ext_uart_no, write_buffer + write_index * 256, 256); + write_index++; + write_len_continue = write_len - write_index * 256; + } + Ch438UartSend(ext_uart_no, write_buffer + write_index * 256, write_len_continue); + } + } + else + { + Ch438UartSend(ext_uart_no, write_buffer, write_len); + } + + return OK; +} + +/**************************************************************************** + * Name: ImxrtCh438ReadData + * + * Description: + * Read data from ch438 port + * + ****************************************************************************/ +static size_t ImxrtCh438ReadData(uint8_t ext_uart_no, size_t size) +{ + size_t RevLen = 0; + uint8_t InterruptStatus; + uint8_t REG_IIR_ADDR; + uint8_t REG_LSR_ADDR; + uint8_t REG_MSR_ADDR; + + pthread_mutex_lock(&mutex[ext_uart_no]); + while(done[ext_uart_no] == false) + pthread_cond_wait(&cond[ext_uart_no], &mutex[ext_uart_no]); + if(done[ext_uart_no] == true) + { + REG_IIR_ADDR = offsetadd[ext_uart_no] | REG_IIR0_ADDR; + REG_LSR_ADDR = offsetadd[ext_uart_no] | REG_LSR0_ADDR; + REG_MSR_ADDR = offsetadd[ext_uart_no] | REG_MSR0_ADDR; + /* Read the interrupt status of the serial port */ + InterruptStatus = ReadCH438Data(REG_IIR_ADDR) & 0x0f; + ch438info("InterruptStatus is %d\n", InterruptStatus); + + switch(InterruptStatus) + { + case INT_NOINT: /* no interrupt */ + break; + case INT_THR_EMPTY: /* the transmit hold register is not interrupted */ + break; + case INT_RCV_OVERTIME: /* receive data timeout interrupt */ + case INT_RCV_SUCCESS: /* receive data available interrupt */ + RevLen = CH438UARTRcv(ext_uart_no, buff[ext_uart_no], size); + break; + case INT_RCV_LINES: /* receive line status interrupt */ + ReadCH438Data(REG_LSR_ADDR); + break; + case INT_MODEM_CHANGE: /* modem input change interrupt */ + ReadCH438Data(REG_MSR_ADDR); + break; + default: + break; + } + done[ext_uart_no] = false; + } + pthread_mutex_unlock(&mutex[ext_uart_no]); + + return RevLen; +} + +/**************************************************************************** + * Name: Ch438InitDefault + * + * Description: + * Ch438 default initialization function + * + ****************************************************************************/ +static void Ch438InitDefault(void) +{ + int ret = 0; + int i; + + /* Initialize the mutex */ + for(i = 0; i < CH438PORTNUM; i++) + { + if(!g_uart_selected[i]) + { + continue; + } + + ret = pthread_mutex_init(&mutex[i], NULL); + if(ret != 0) + { + ch438err("pthread_mutex_init failed, status=%d\n", ret); + } + } + + /* Initialize the condition variable */ + for(i = 0; i < CH438PORTNUM; i++) + { + if(!g_uart_selected[i]) + { + continue; + } + + ret = pthread_cond_init(&cond[i], NULL); + if(ret != 0) + { + ch438err("pthread_cond_init failed, status=%d\n", ret); + } + } + + ImxrtCH438Init(); + +/* If a port is checked, the port will be initialized. Otherwise, the interrupt of the port will be disabled. */ + +#ifdef CONFIG_CH438_EXTUART0 + CH438PortInit(0, CONFIG_CH438_EXTUART0_BAUD); +#else + WriteCH438Data(REG_IER0_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART1 + CH438PortInit(1, CONFIG_CH438_EXTUART1_BAUD); +#else + WriteCH438Data(REG_IER1_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART2 + CH438PortInit(2, CONFIG_CH438_EXTUART2_BAUD); +#else + WriteCH438Data(REG_IER2_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART3 + CH438PortInit(3, CONFIG_CH438_EXTUART3_BAUD); +#else + WriteCH438Data(REG_IER3_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART4 + CH438PortInit(4, CONFIG_CH438_EXTUART4_BAUD); +#else + WriteCH438Data(REG_IER4_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART5 + CH438PortInit(5, CONFIG_CH438_EXTUART5_BAUD); +#else + WriteCH438Data(REG_IER5_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART6 + CH438PortInit(6, CONFIG_CH438_EXTUART6_BAUD); +#else + WriteCH438Data(REG_IER6_ADDR, 0x00); +#endif + +#ifdef CONFIG_CH438_EXTUART7 + CH438PortInit(7, CONFIG_CH438_EXTUART7_BAUD); +#else + WriteCH438Data(REG_IER7_ADDR, 0x00); +#endif + + up_mdelay(10); + + work_queue(HPWORK, &g_ch438irqwork, getInterruptStatus, NULL, CH438_INCREMENT); +} + +/**************************************************************************** + * Name: ch438_open + ****************************************************************************/ +static int ch438_open(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ch438_dev_s *priv = inode->i_private; + uint8_t port = priv->port; + int ret = OK; + + DEBUGASSERT(port >= 0 && port < CH438PORTNUM); + + ret = nxsem_wait_uninterruptible(&priv->devsem); + if (ret < 0) + { + return ret; + } + + if(g_ch438open[port]) + { + ch438err("ERROR: ch438 port %d is opened!\n",port); + return -EBUSY; + } + g_ch438open[port] = true; + + nxsem_post(&priv->devsem); + + return ret; +} + +/**************************************************************************** + * Name: ch438_close + ****************************************************************************/ +static int ch438_close(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ch438_dev_s *priv = inode->i_private; + uint8_t port = priv->port; + int ret = OK; + + DEBUGASSERT(port >= 0 && port < CH438PORTNUM); + + ret = nxsem_wait_uninterruptible(&priv->devsem); + if (ret < 0) + { + return ret; + } + + if(!g_ch438open[port]) + { + ch438err("ERROR: ch438 port %d is closed!\n",port); + return -EBUSY; + } + g_ch438open[port] = false; + + nxsem_post(&priv->devsem); + return ret; +} + +/**************************************************************************** + * Name: ch438_read + ****************************************************************************/ +static ssize_t ch438_read(FAR struct file *filep, FAR char *buffer, size_t buflen) +{ + size_t length = 0; + FAR struct inode *inode = filep->f_inode; + FAR struct ch438_dev_s *priv = inode->i_private; + uint8_t port = priv->port; + + DEBUGASSERT(port >= 0 && port < CH438PORTNUM); + + length = ImxrtCh438ReadData(port, buflen); + memcpy(buffer, buff[port], length); + + if(length > buflen) + { + length = buflen; + } + + return length; +} + +/**************************************************************************** + * Name: ch438_write + ****************************************************************************/ +static ssize_t ch438_write(FAR struct file *filep, FAR const char *buffer, size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ch438_dev_s *priv = inode->i_private; + uint8_t port = priv->port; + + DEBUGASSERT(port >= 0 && port < CH438PORTNUM); + + ImxrtCh438WriteData(port, (const uint8_t *)buffer, buflen); + + return buflen; +} + +/**************************************************************************** + * Name: ch438_ioctl + ****************************************************************************/ +static int ch438_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ch438_dev_s *priv = inode->i_private; + uint8_t port = priv->port; + int ret = OK; + + DEBUGASSERT(port >= 0 && port < CH438PORTNUM); + + switch(cmd) + { + case OPE_INT: + case OPE_CFG: + CH438PortInit(port, (uint32_t)arg); + break; + + default: + ch438info("Unrecognized cmd: %d\n", cmd); + ret = -ENOTTY; + break; + } + return ret; +} + + +/**************************************************************************** + * Name: ch438_register + * + * Description: + * Register /dev/ext_uartN + * + ****************************************************************************/ +static int ch438_register(FAR const char *devpath, uint8_t port) +{ + FAR struct ch438_dev_s *priv; + int ret = 0; + + /* port number check */ + DEBUGASSERT(port >= 0 && port < CH438PORTNUM); + + priv = (FAR struct ch438_dev_s *)kmm_malloc(sizeof(struct ch438_dev_s)); + if(priv == NULL) + { + ch438err("ERROR: Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->port = port; + nxsem_init(&priv->devsem, 0, 1); + + /* Register the character driver */ + ret = register_driver(devpath, &g_ch438fops, 0666, priv); + if(ret < 0) + { + kmm_free(priv); + } + + return ret; +} + +/**************************************************************************** + * Name: board_ch438_initialize + * + * Description: + * ch438 initialize + * + ****************************************************************************/ +void board_ch438_initialize(void) +{ + Ch438InitDefault(); + +#ifdef CONFIG_CH438_EXTUART0 + ch438_register("/dev/extuart_dev0", 0); +#endif + +#ifdef CONFIG_CH438_EXTUART1 + ch438_register("/dev/extuart_dev1", 1); +#endif + +#ifdef CONFIG_CH438_EXTUART2 + ch438_register("/dev/extuart_dev2", 2); +#endif + +#ifdef CONFIG_CH438_EXTUART3 + ch438_register("/dev/extuart_dev3", 3); +#endif + +#ifdef CONFIG_CH438_EXTUART4 + ch438_register("/dev/extuart_dev4", 4); +#endif + +#ifdef CONFIG_CH438_EXTUART5 + ch438_register("/dev/extuart_dev5", 5); +#endif + +#ifdef CONFIG_CH438_EXTUART6 + ch438_register("/dev/extuart_dev6", 6); +#endif + +#ifdef CONFIG_CH438_EXTUART7 + ch438_register("/dev/extuart_dev7", 7); +#endif +} \ No newline at end of file diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_ch438.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_ch438.h new file mode 100644 index 000000000..866bdde0a --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_ch438.h @@ -0,0 +1,369 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imxrt_ch438.h + * @brief imxrt board sd card automount + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.04.26 + */ + +#ifndef __BOARDS_ARM_IMXRT_XIDATONG_SRC_IMXRT_CH438_H +#define __BOARDS_ARM_IMXRT_XIDATONG_SRC_IMXRT_CH438_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "arm_arch.h" + +#include "imxrt_config.h" +#include "imxrt_irq.h" +#include "imxrt_gpio.h" +#include "xidatong.h" + +/******************************************************************************************/ + +/* chip definition */ +/* CH438serial port0 register address */ + +#define REG_RBR0_ADDR 0x00 /* serial port0receive buffer register address */ +#define REG_THR0_ADDR 0x00 /* serial port0send hold register address */ +#define REG_IER0_ADDR 0x01 /* serial port0interrupt enable register address */ +#define REG_IIR0_ADDR 0x02 /* serial port0interrupt identifies register address */ +#define REG_FCR0_ADDR 0x02 /* serial port0FIFO controls register address */ +#define REG_LCR0_ADDR 0x03 /* serial port0circuit control register address */ +#define REG_MCR0_ADDR 0x04 /* serial port0MODEM controls register address */ +#define REG_LSR0_ADDR 0x05 /* serial port0line status register address */ +#define REG_MSR0_ADDR 0x06 /* serial port0address of MODEM status register */ +#define REG_SCR0_ADDR 0x07 /* serial port0the user can define the register address */ +#define REG_DLL0_ADDR 0x00 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM0_ADDR 0x01 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port1 register address */ + +#define REG_RBR1_ADDR 0x10 /* serial port1receive buffer register address */ +#define REG_THR1_ADDR 0x10 /* serial port1send hold register address */ +#define REG_IER1_ADDR 0x11 /* serial port1interrupt enable register address */ +#define REG_IIR1_ADDR 0x12 /* serial port1interrupt identifies register address */ +#define REG_FCR1_ADDR 0x12 /* serial port1FIFO controls register address */ +#define REG_LCR1_ADDR 0x13 /* serial port1circuit control register address */ +#define REG_MCR1_ADDR 0x14 /* serial port1MODEM controls register address */ +#define REG_LSR1_ADDR 0x15 /* serial port1line status register address */ +#define REG_MSR1_ADDR 0x16 /* serial port1address of MODEM status register */ +#define REG_SCR1_ADDR 0x17 /* serial port1the user can define the register address */ +#define REG_DLL1_ADDR 0x10 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM1_ADDR 0x11 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port2 register address */ + +#define REG_RBR2_ADDR 0x20 /* serial port2receive buffer register address */ +#define REG_THR2_ADDR 0x20 /* serial port2send hold register address */ +#define REG_IER2_ADDR 0x21 /* serial port2interrupt enable register address */ +#define REG_IIR2_ADDR 0x22 /* serial port2interrupt identifies register address */ +#define REG_FCR2_ADDR 0x22 /* serial port2FIFO controls register address */ +#define REG_LCR2_ADDR 0x23 /* serial port2circuit control register address */ +#define REG_MCR2_ADDR 0x24 /* serial port2MODEM controls register address */ +#define REG_LSR2_ADDR 0x25 /* serial port2line status register address */ +#define REG_MSR2_ADDR 0x26 /* serial port2address of MODEM status register */ +#define REG_SCR2_ADDR 0x27 /* serial port2the user can define the register address */ +#define REG_DLL2_ADDR 0x20 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM2_ADDR 0x21 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port3 register address */ + +#define REG_RBR3_ADDR 0x30 /* serial port3receive buffer register address */ +#define REG_THR3_ADDR 0x30 /* serial port3send hold register address */ +#define REG_IER3_ADDR 0x31 /* serial port3interrupt enable register address */ +#define REG_IIR3_ADDR 0x32 /* serial port3interrupt identifies register address */ +#define REG_FCR3_ADDR 0x32 /* serial port3FIFO controls register address */ +#define REG_LCR3_ADDR 0x33 /* serial port3circuit control register address */ +#define REG_MCR3_ADDR 0x34 /* serial port3MODEM controls register address */ +#define REG_LSR3_ADDR 0x35 /* serial port3line status register address */ +#define REG_MSR3_ADDR 0x36 /* serial port3address of MODEM status register */ +#define REG_SCR3_ADDR 0x37 /* serial port3the user can define the register address */ +#define REG_DLL3_ADDR 0x30 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM3_ADDR 0x31 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port4 register address */ + +#define REG_RBR4_ADDR 0x08 /* serial port4receive buffer register address */ +#define REG_THR4_ADDR 0x08 /* serial port4send hold register address */ +#define REG_IER4_ADDR 0x09 /* serial port4interrupt enable register address */ +#define REG_IIR4_ADDR 0x0A /* serial port4interrupt identifies register address */ +#define REG_FCR4_ADDR 0x0A /* serial port4FIFO controls register address */ +#define REG_LCR4_ADDR 0x0B /* serial port4circuit control register address */ +#define REG_MCR4_ADDR 0x0C /* serial port4MODEM controls register address */ +#define REG_LSR4_ADDR 0x0D /* serial port4line status register address */ +#define REG_MSR4_ADDR 0x0E /* serial port4address of MODEM status register */ +#define REG_SCR4_ADDR 0x0F /* serial port4the user can define the register address */ +#define REG_DLL4_ADDR 0x08 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM4_ADDR 0x09 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port5 register address */ + +#define REG_RBR5_ADDR 0x18 /* serial port5receive buffer register address */ +#define REG_THR5_ADDR 0x18 /* serial port5send hold register address */ +#define REG_IER5_ADDR 0x19 /* serial port5interrupt enable register address */ +#define REG_IIR5_ADDR 0x1A /* serial port5interrupt identifies register address */ +#define REG_FCR5_ADDR 0x1A /* serial port5FIFO controls register address */ +#define REG_LCR5_ADDR 0x1B /* serial port5circuit control register address */ +#define REG_MCR5_ADDR 0x1C /* serial port5MODEM controls register address */ +#define REG_LSR5_ADDR 0x1D /* serial port5line status register address */ +#define REG_MSR5_ADDR 0x1E /* serial port5address of MODEM status register */ +#define REG_SCR5_ADDR 0x1F /* serial port5the user can define the register address */ +#define REG_DLL5_ADDR 0x18 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM5_ADDR 0x19 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port6 register address */ + +#define REG_RBR6_ADDR 0x28 /* serial port6receive buffer register address */ +#define REG_THR6_ADDR 0x28 /* serial port6send hold register address */ +#define REG_IER6_ADDR 0x29 /* serial port6interrupt enable register address */ +#define REG_IIR6_ADDR 0x2A /* serial port6interrupt identifies register address */ +#define REG_FCR6_ADDR 0x2A /* serial port6FIFO controls register address */ +#define REG_LCR6_ADDR 0x2B /* serial port6circuit control register address */ +#define REG_MCR6_ADDR 0x2C /* serial port6MODEM controls register address */ +#define REG_LSR6_ADDR 0x2D /* serial port6line status register address */ +#define REG_MSR6_ADDR 0x2E /* serial port6address of MODEM status register */ +#define REG_SCR6_ADDR 0x2F /* serial port6the user can define the register address */ +#define REG_DLL6_ADDR 0x28 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM6_ADDR 0x29 /* Baud rate divisor latch high 8-bit byte address */ + + +/* CH438serial port7 register address */ + +#define REG_RBR7_ADDR 0x38 /* serial port7receive buffer register address */ +#define REG_THR7_ADDR 0x38 /* serial port7send hold register address */ +#define REG_IER7_ADDR 0x39 /* serial port7interrupt enable register address */ +#define REG_IIR7_ADDR 0x3A /* serial port7interrupt identifies register address */ +#define REG_FCR7_ADDR 0x3A /* serial port7FIFO controls register address */ +#define REG_LCR7_ADDR 0x3B /* serial port7circuit control register address */ +#define REG_MCR7_ADDR 0x3C /* serial port7MODEM controls register address */ +#define REG_LSR7_ADDR 0x3D /* serial port7line status register address */ +#define REG_MSR7_ADDR 0x3E /* serial port7address of MODEM status register */ +#define REG_SCR7_ADDR 0x3F /* serial port7the user can define the register address */ +#define REG_DLL7_ADDR 0x38 /* Baud rate divisor latch low 8-bit byte address */ +#define REG_DLM7_ADDR 0x39 /* Baud rate divisor latch high 8-bit byte address */ + + +#define REG_SSR_ADDR 0x4F /* pecial status register address */ + + +/* IER register bit */ + +#define BIT_IER_RESET 0x80 /* The bit is 1 soft reset serial port */ +#define BIT_IER_LOWPOWER 0x40 /* The bit is 1 close serial port internal reference clock */ +#define BIT_IER_SLP 0x20 /* serial port0 is SLP, 1 close clock vibrator */ +#define BIT_IER1_CK2X 0x20 /* serial port1 is CK2X, 1 force the external clock signal after 2 times as internal */ +#define BIT_IER_IEMODEM 0x08 /* The bit is 1 allows MODEM input status to interrupt */ +#define BIT_IER_IELINES 0x04 /* The bit is 1 allow receiving line status to be interrupted */ +#define BIT_IER_IETHRE 0x02 /* The bit is 1 allows the send hold register to break in mid-air */ +#define BIT_IER_IERECV 0x01 /* The bit is 1 allows receiving data interrupts */ + +/* IIR register bit */ + +#define BIT_IIR_FIFOENS1 0x80 +#define BIT_IIR_FIFOENS0 0x40 /* The two is 1 said use FIFO */ + +/* Interrupt type: 0001 has no interrupt, 0110 receiving line status is interrupted, 0100 receiving data can be interrupted, +1100 received data timeout interrupt, 0010THR register air interrupt, 0000MODEM input change interrupt */ +#define BIT_IIR_IID3 0x08 +#define BIT_IIR_IID2 0x04 +#define BIT_IIR_IID1 0x02 +#define BIT_IIR_NOINT 0x01 + +/* FCR register bit */ + +/* Trigger point: 00 corresponds to 1 byte, 01 corresponds to 16 bytes, 10 corresponds to 64 bytes, 11 corresponds to 112 bytes */ +#define BIT_FCR_RECVTG1 0x80 /* Set the trigger point for FIFO interruption and automatic hardware flow control */ +#define BIT_FCR_RECVTG0 0x40 /* Set the trigger point for FIFO interruption and automatic hardware flow control */ + +#define BIT_FCR_TFIFORST 0x04 /* The bit is 1 empty the data sent in FIFO */ +#define BIT_FCR_RFIFORST 0x02 /* The bit is 1 empty the data sent in FIFO */ +#define BIT_FCR_FIFOEN 0x01 /* The bit is 1 use FIFO, 0 disable FIFO */ + +/* LCR register bit */ + +#define BIT_LCR_DLAB 0x80 /* To access DLL, DLM, 0 to access RBR/THR/IER */ +#define BIT_LCR_BREAKEN 0x40 /* 1 forces a BREAK line interval*/ + +/* Set the check format: when PAREN is 1, 00 odd check, 01 even check, 10 MARK (set 1), 11 blank (SPACE, clear 0) */ +#define BIT_LCR_PARMODE1 0x20 /* Sets the parity bit format */ +#define BIT_LCR_PARMODE0 0x10 /* Sets the parity bit format */ + +#define BIT_LCR_PAREN 0x08 /* A value of 1 allows you to generate and receive parity bits when sending */ +#define BIT_LCR_STOPBIT 0x04 /* If is 1, then two stop bits, is 0, a stop bit */ + +/* Set word length: 00 for 5 data bits, 01 for 6 data bits, 10 for 7 data bits and 11 for 8 data bits */ +#define BIT_LCR_WORDSZ1 0x02 /* Set the word length length */ +#define BIT_LCR_WORDSZ0 0x01 + +/* MCR register bit */ + +#define BIT_MCR_AFE 0x20 /* For 1 allows automatic flow control of CTS and RTS hardware */ +#define BIT_MCR_LOOP 0x10 /* Is the test mode of 1 enabling internal loop */ +#define BIT_MCR_OUT2 0x08 /* 1 Allows an interrupt request for the serial port output */ +#define BIT_MCR_OUT1 0x04 /* The MODEM control bit defined for the user */ +#define BIT_MCR_RTS 0x02 /* The bit is 1 RTS pin output effective */ +#define BIT_MCR_DTR 0x01 /* The bit is 1 DTR pin output effective */ + +/* LSR register bit */ + +#define BIT_LSR_RFIFOERR 0x80 /* 1 said There is at least one error in receiving FIFO */ +#define BIT_LSR_TEMT 0x40 /* 1 said THR and TSR are empty */ +#define BIT_LSR_THRE 0x20 /* 1 said THR is empty*/ +#define BIT_LSR_BREAKINT 0x10 /* The bit is 1 said the BREAK line interval was detected*/ +#define BIT_LSR_FRAMEERR 0x08 /* The bit is 1 said error reading data frame */ +#define BIT_LSR_PARERR 0x04 /* The bit is 1 said parity error */ +#define BIT_LSR_OVERR 0x02 /* 1 said receive FIFO buffer overflow */ +#define BIT_LSR_DATARDY 0x01 /* The bit is 1 said receive data received in FIFO */ + +/* MSR register bit */ + +#define BIT_MSR_DCD 0x80 /* The bit is 1 said DCD pin effective */ +#define BIT_MSR_RI 0x40 /* The bit is 1 said RI pin effective */ +#define BIT_MSR_DSR 0x20 /* The bit is 1 said DSR pin effective */ +#define BIT_MSR_CTS 0x10 /* The bit is 1 said CTS pin effective */ +#define BIT_MSR_DDCD 0x08 /* The bit is 1 said DCD pin The input state has changed */ +#define BIT_MSR_TERI 0x04 /* The bit is 1 said RI pin The input state has changed */ +#define BIT_MSR_DDSR 0x02 /* The bit is 1 said DSR pin The input state has changed */ +#define BIT_MSR_DCTS 0x01 /* The bit is 1 said CTS pin The input state has changed */ + +/* Interrupt status code */ + +#define INT_NOINT 0x01 /* There is no interruption */ +#define INT_THR_EMPTY 0x02 /* THR empty interruption */ +#define INT_RCV_OVERTIME 0x0C /* Receive timeout interrupt */ +#define INT_RCV_SUCCESS 0x04 /* Interrupts are available to receive data */ +#define INT_RCV_LINES 0x06 /* Receiving line status interrupted */ +#define INT_MODEM_CHANGE 0x00 /* MODEM input changes interrupt */ + +#define CH438_IIR_FIFOS_ENABLED 0xC0 /* use FIFO */ + + +#define Fpclk 1843200 /* Define the internal clock frequency*/ + + +// #define IOMUX_CH438OUT_DEFAULT +#define CH438_D0_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT1 | GPIO_PIN25) +#define CH438_D1_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT1 | GPIO_PIN24) +#define CH438_D2_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT1 | GPIO_PIN20) +#define CH438_D3_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT1 | GPIO_PIN21) +#define CH438_D4_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT1 | GPIO_PIN31) +#define CH438_D5_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT1 | GPIO_PIN28) +#define CH438_D6_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT1 | GPIO_PIN30) +#define CH438_D7_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT1 | GPIO_PIN29) +#define CH438_NWR_PIN (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT3 | GPIO_PIN4) +#define CH438_NRD_PIN (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT3 | GPIO_PIN5) +#define CH438_ALE_PIN (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \ + GPIO_PORT3 | GPIO_PIN2) +#define CH438_INT_PIN (GPIO_INTERRUPT | GPIO_INT_FALLINGEDGE | IOMUX_SW_DEFAULT | \ + GPIO_PORT3 | GPIO_PIN3) + +#define CH438_D0_PIN_INPUT (GPIO_INPUT | \ + GPIO_PORT1 | GPIO_PIN25) +#define CH438_D1_PIN_INPUT (GPIO_INPUT | \ + GPIO_PORT1 | GPIO_PIN24) +#define CH438_D2_PIN_INPUT (GPIO_INPUT | \ + GPIO_PORT1 | GPIO_PIN20) +#define CH438_D3_PIN_INPUT (GPIO_INPUT | \ + GPIO_PORT1 | GPIO_PIN21) +#define CH438_D4_PIN_INPUT (GPIO_INPUT | \ + GPIO_PORT1 | GPIO_PIN31) +#define CH438_D5_PIN_INPUT (GPIO_INPUT | \ + GPIO_PORT1 | GPIO_PIN28) +#define CH438_D6_PIN_INPUT (GPIO_INPUT | \ + GPIO_PORT1 | GPIO_PIN30) +#define CH438_D7_PIN_INPUT (GPIO_INPUT | \ + GPIO_PORT1 | GPIO_PIN29) + +/* ch438 debug */ +#ifdef CONFIG_DEBUG_CH438_ERROR +# define ch438err _err +#else +# define ch438err _none +#endif + +#ifdef CONFIG_DEBUG_CH438_WARN +# define ch438warn _warn +#else +# define ch438warn _none +#endif + +#ifdef CONFIG_DEBUG_CH438_INFO +# define ch438info _info +#else +# define ch438info _none +#endif + + +/* ioctl cmd */ +#define OPE_INT 0x0000 +#define OPE_CFG 0x0001 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ +#ifdef CONFIG_BSP_USING_CH438 +void board_ch438_initialize(void); +#endif + +#endif /* __BOARDS_ARM_IMXRT_XIDATONG_SRC_IMXRT_CH438_H */ + diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_gt9xx.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_gt9xx.c new file mode 100755 index 000000000..427f79a9c --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_gt9xx.c @@ -0,0 +1,328 @@ +/**************************************************************************** + * boards/arm/imxrt/xidatong/src/imxrt_gt9xx.c + * + * Copyright 2019 ElFaro LAB S.L. All rights reserved. + * Author: Fabio Balzano + * + * Based on boards/arm/lpc54xx/lpcxpresso-lpc54628/src/lpc54_ft5x06.c + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file imxrt_gt9xx.c + * @brief gt9xx touch driver refer to imxrt_ft5x06.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.5.31 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "imxrt_config.h" +#include "imxrt_gpio.h" +#include "imxrt_lpi2c.h" + +#include "arch/chip/irq.h" +#include "imxrt_iomuxc.h" + +#define gt_print printf + +#define GT9XX_I2C_ADDRESS 0x5D + +#define GPIO_GT9XX_INTR IMXRT_IRQ_GPIO2_30 + +#define IOMUX_GT9XX_RST (IOMUX_PULL_NONE | IOMUX_CMOS_OUTPUT | \ + IOMUX_DRIVE_40OHM | IOMUX_SPEED_MEDIUM | \ + IOMUX_SLEW_SLOW) + +#define GPIO_GT9XX_CTRSTN (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | \ + GPIO_PORT2 | GPIO_PIN30 | IOMUX_GT9XX_RST) + +#define GPIO_GT9XX_CTINTN (GPIO_INTERRUPT | GPIO_INT_RISINGEDGE | \ + IOMUX_SW_DEFAULT | GPIO_PORT2 | GPIO_PIN30 ) + +#ifdef CONFIG_INPUT_GT9XX + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define GT9XX_FREQUENCY 400000 + +/**************************************************************************** + * Private Function Ptototypes + ****************************************************************************/ + +#ifndef CONFIG_GT9XX_POLLMODE +static int imxrt_gt9xx_attach(FAR const struct gt9xx_config_s *config, + xcpt_t isr, FAR void *arg); +static void imxrt_gt9xx_enable(FAR const struct gt9xx_config_s *config, + bool enable); +static void imxrt_gt9xx_clear(FAR const struct gt9xx_config_s *config); +#endif + +static void imxrt_gt9xx_wakeup(FAR const struct gt9xx_config_s *config); +static void imxrt_gt9xx_nreset(FAR const struct gt9xx_config_s *config, + bool state); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct gt9xx_config_s g_gt9xx_config = +{ + .address = GT9XX_I2C_ADDRESS, + .frequency = GT9XX_FREQUENCY, +#ifndef CONFIG_GT9XX_POLLMODE + .attach = imxrt_gt9xx_attach, + .enable = imxrt_gt9xx_enable, + .clear = imxrt_gt9xx_clear, +#endif + .wakeup = imxrt_gt9xx_wakeup, + .nreset = imxrt_gt9xx_nreset +}; + +#ifndef CONFIG_GT9XX_POLLMODE +static uint8_t g_gt9xx_irq; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_gt9xx_attach + * + * Description: + * Attach an GT9XX interrupt handler to a GPIO interrupt + * + ****************************************************************************/ + +#ifndef CONFIG_GT9XX_POLLMODE +static int imxrt_gt9xx_attach(FAR const struct gt9xx_config_s *config, + xcpt_t isr, FAR void *arg) +{ + return irq_attach(g_gt9xx_irq, isr, arg); +} +#endif + +/**************************************************************************** + * Name: imxrt_gt9xx_enable + * + * Description: + * Enable or disable a GPIO interrupt + * + ****************************************************************************/ + +#ifndef CONFIG_GT9XX_POLLMODE +static void imxrt_gt9xx_enable(FAR const struct gt9xx_config_s *config, + bool enable) +{ + if (enable) + { + up_enable_irq(g_gt9xx_irq); + } + else + { + up_disable_irq(g_gt9xx_irq); + } +} +#endif + +/**************************************************************************** + * Name: imxrt_gt9xx_clear + * + * Description: + * Acknowledge/clear any pending GPIO interrupt + * + ****************************************************************************/ + +#ifndef CONFIG_GT9XX_POLLMODE +static void imxrt_gt9xx_clear(FAR const struct gt9xx_config_s *config) +{ + imxrt_gpioirq_disable(g_gt9xx_irq); +} +#endif + +/**************************************************************************** + * Name: imxrt_gt9xx_wakeup + * + * Description: + * Issue WAKE interrupt to GT9XX to change the GT9XX from Hibernate to + * Active mode. + * + ****************************************************************************/ + +static void imxrt_gt9xx_wakeup(FAR const struct gt9xx_config_s *config) +{ + /* We do not have access to the WAKE pin in the implementation */ +} + +/**************************************************************************** + * Name: imxrt_gt9xx_nreset + * + * Description: + * Control the chip reset pin (active low) + * + ****************************************************************************/ + +static void imxrt_gt9xx_nreset(FAR const struct gt9xx_config_s *config, + bool nstate) +{ + imxrt_gpio_write(GPIO_GT9XX_CTRSTN, nstate); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_MASK (0x7U) +#define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_SHIFT (0U) + +#define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(x) (((uint32_t)(((uint32_t)(x)) << IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_SHIFT)) & IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_MASK) +#define IOMUXC_SW_MUX_CTL_PAD_SION_MASK (0x10U) +#define IOMUXC_SW_MUX_CTL_PAD_SION_SHIFT (4U) + +#define IOMUXC_SW_MUX_CTL_PAD_SION(x) (((uint32_t)(((uint32_t)(x)) << IOMUXC_SW_MUX_CTL_PAD_SION_SHIFT)) & IOMUXC_SW_MUX_CTL_PAD_SION_MASK) + +#define IOMUXC_GPIO_B1_14_GPIO2_IO30 0x401F81B4U, 0x5U, 0, 0, 0x401F83A4U + +static inline void IOMUXC_SetPinMux(uint32_t muxRegister, + uint32_t muxMode, + uint32_t inputRegister, + uint32_t inputDaisy, + uint32_t configRegister, + uint32_t inputOnfield) +{ + *((volatile uint32_t *)muxRegister) = + IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode) | IOMUXC_SW_MUX_CTL_PAD_SION(inputOnfield); + + if (inputRegister) + { + *((volatile uint32_t *)inputRegister) = inputDaisy; + } +} + +static inline void IOMUXC_SetPinConfig(uint32_t muxRegister, + uint32_t muxMode, + uint32_t inputRegister, + uint32_t inputDaisy, + uint32_t configRegister, + uint32_t configValue) +{ + if (configRegister) + { + *((volatile uint32_t *)configRegister) = configValue; + } +} + +void imxrt_config_gt9xx_pins(void) +{ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_14_GPIO2_IO30, /* WAKEUP is configured as GPIO5_IO00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_14_GPIO2_IO30, + 0x10B0u); +} + +/**************************************************************************** + * Name: imxrt_gt9xx_register + * + * Description: + * Register the GT9XX touch panel driver + * + ****************************************************************************/ + +int imxrt_gt9xx_register(void) +{ + FAR struct i2c_master_s *i2c; + int ret; + + /* Initialize CTRSTN pin */ + imxrt_config_gpio(GPIO_GT9XX_CTRSTN); + imxrt_gpio_write(GPIO_GT9XX_CTRSTN, false); + +#ifndef CONFIG_GT9XX_POLLMODE + int irq; + + /* Initialize GPIO interrupt pin. */ + imxrt_config_gpio(GPIO_GT9XX_CTINTN); + + irq = GPIO_GT9XX_INTR; + DEBUGASSERT(irq > 0 && irq < UINT8_MAX); + g_gt9xx_irq = (uint8_t)irq; + + /* Make sure that the interrupt is disabled at the NVIC */ + imxrt_gpioirq_disable(irq); + up_disable_irq(irq); +#endif + + /* Take the GT9XX out of reset */ + + /* The GT9XX is on LPI2C1. Get the handle and register the GT9XX device */ + + i2c = imxrt_i2cbus_initialize(1); + if (i2c == NULL) + { + syslog(LOG_ERR, "ERROR: Failed to get LPI2C1 interface\n"); + return -ENODEV; + } + else + { + ret = gt9xx_register(i2c, &g_gt9xx_config, 0); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register GT9XX driver: %d\n", ret); + imxrt_gpio_write(GPIO_GT9XX_CTRSTN, false); + imxrt_i2cbus_uninitialize(i2c); + return ret; + } + } + + return OK; +} + +#endif /* CONFIG_INPUT_GT9XX*/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_gt9xx.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_gt9xx.h new file mode 100755 index 000000000..073c044ba --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_gt9xx.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @file imxrt_gt9xx.h + * @brief API for imxrt gt9xx. + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.5.31 + */ + +#ifndef __IMXRT_GT9XX_H_ +#define __IMXRT_GT9XX_H_ + +int imxrt_gt9xx_register(void); + +#endif /* __IMXRT_GT9XX_H__ */ + diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_reset.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_reset.c new file mode 100644 index 000000000..91769ff54 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_reset.c @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imxrt_reset.c + * @brief imxrt board sd card automount + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.04.29 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#ifdef CONFIG_BOARDCTL_RESET + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_reset + * + * Description: + * Reset board. Support for this function is required by board-level + * logic if CONFIG_BOARDCTL_RESET is selected. + * + * Input Parameters: + * status - Status information provided with the reset event. This + * meaning of this status information is board-specific. If not + * used by a board, the value zero may be provided in calls to + * board_reset(). + * + * Returned Value: + * If this function returns, then it was not possible to power-off the + * board due to some constraints. The return value int this case is a + * board-specific reason for the failure to shutdown. + * + ****************************************************************************/ + +int board_reset(int status) +{ + up_systemreset(); + return 0; +} + +#endif /* CONFIG_BOARDCTL_RESET */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig index 3c98cda38..a482d7db1 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig @@ -587,6 +587,11 @@ config NSH_DISABLE_XD bool "Disable xd" default y if DEFAULT_SMALL default n if !DEFAULT_SMALL + +config NSH_DISABLE_CH438 + bool "Disable the ch438 demo." + default n + config NSH_DISABLE_HCHO_TB600B_WQ_HCHO1OS bool "Disable the sensor tb600b_wq_hcho1os." default n @@ -659,6 +664,22 @@ config NSH_DISABLE_ADAPTER_4GTEST bool "Disable ec200t Adapter4GTest." default n +config NSH_DISABLE_E220_LORA_RECEIVE + bool "Disable e220 Lora receive." + default n + +config NSH_DISABLE_E220_LORA_SEND + bool "Disable e220 Lora send." + default n + +config NSH_DISABLE_ADAPTER_BLUETOOTH_TEST + bool "Disable hc08 AdapterBlueToothTest." + default n + +config NSH_DISABLE_ADAPTER_WIFI_TEST + bool "Disable esp07s AdapterWIFITest." + default n + config NSH_DISABLE_K210_FFT bool "Disable the K210 fft device." default n diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h index d46be3f42..cfa6b1afc 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h @@ -22,7 +22,7 @@ * @file nsh.h * @brief nuttx source code * https://github.com/apache/incubator-nuttx-apps -* @version 10.2.0 +* @version 10.2.0 * @author AIIT XUOS Lab * @date 2022-03-17 */ @@ -1417,6 +1417,10 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb, FAR void *arg); #endif +#if defined(CONFIG_BSP_USING_CH438) && !defined(CONFIG_NSH_DISABLE_CH438) + int cmd_Ch438(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + #if defined(CONFIG_APPLICATION_SENSOR_HCHO_TB600B_WQ_HCHO1OS) && !defined(CONFIG_NSH_DISABLE_HCHO_TB600B_WQ_HCHO1OS) int cmd_Hcho1os(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif @@ -1482,7 +1486,7 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb, int cmd_recvzigbee(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif -#if defined(CONFIG_ADAPTER_SX1278) && !defined(CONFIG_NSH_DISABLE_ADAPTER_LORATEST) +#if (defined(CONFIG_ADAPTER_LORA_SX1278) || defined(CONFIG_ADAPTER_LORA_E220)) && !defined(CONFIG_NSH_DISABLE_ADAPTER_LORATEST) int cmd_AdapterLoraTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif @@ -1490,6 +1494,22 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb, int cmd_Adapter4GTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif +#if defined(CONFIG_ADAPTER_LORA_E220) && !defined(CONFIG_NSH_DISABLE_E220_LORA_RECEIVE) + int cmd_E220LoraReceive(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + +#if defined(CONFIG_ADAPTER_LORA_E220) && !defined(CONFIG_NSH_DISABLE_E220_LORA_SEND) + int cmd_E220LoraSend(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + +#if defined(CONFIG_ADAPTER_BLUETOOTH_HC08) && !defined(CONFIG_NSH_DISABLE_ADAPTER_BLUETOOTH_TEST) + int cmd_AdapterBlueToothTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + +#if defined(CONFIG_ADAPTER_ESP07S_WIFI) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) + int cmd_AdapterWifiTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + #if defined(CONFIG_K210_FFT_TEST) && !defined(CONFIG_NSH_DISABLE_K210_FFT) int cmd_fft(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c index 326eb3d75..34fb18629 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c @@ -36,7 +36,18 @@ #include "nsh.h" #include "nsh_console.h" -extern int FrameworkInit(void); +/**************************************************************************** + * Name: cmd_Ch438 + ****************************************************************************/ +#if defined(CONFIG_BSP_USING_CH438) && !defined(CONFIG_NSH_DISABLE_CH438) +extern void CH438Demo(void); +int cmd_Ch438(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + CH438Demo(); + return OK; +} +#endif /**************************************************************************** * Name: cmd_Hcho1os @@ -272,7 +283,18 @@ int cmd_recvzigbee(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } #endif -#if defined(CONFIG_ADAPTER_SX1278) && !defined(CONFIG_NSH_DISABLE_ADAPTER_LORATEST) +#if defined(CONFIG_ADAPTER_ESP07S_WIFI) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) +extern int AdapterWifiTest(int argc, char *argv[]); +int cmd_AdapterWifiTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + FrameworkInit(); + AdapterWifiTest(argc, argv); + return OK; +} +#endif + +#if (defined(CONFIG_ADAPTER_LORA_SX1278) || defined(CONFIG_ADAPTER_LORA_E220)) && !defined(CONFIG_NSH_DISABLE_ADAPTER_LORATEST) extern int AdapterLoraTest(void); int cmd_AdapterLoraTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { @@ -294,6 +316,39 @@ int cmd_Adapter4GTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } #endif +#if defined(CONFIG_ADAPTER_LORA_E220) && !defined(CONFIG_NSH_DISABLE_E220_LORA_RECEIVE) +void E220LoraReceive(void); +int cmd_E220LoraReceive(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + FrameworkInit(); + E220LoraReceive(); + return OK; +} +#endif + +#if defined(CONFIG_ADAPTER_LORA_E220) && !defined(CONFIG_NSH_DISABLE_E220_LORA_SEND) +extern void E220LoraSend(int argc, char *argv[]); +int cmd_E220LoraSend(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + FrameworkInit(); + E220LoraSend(argc,argv); + return OK; +} +#endif + +#if defined(CONFIG_ADAPTER_BLUETOOTH_HC08) && !defined(CONFIG_NSH_DISABLE_ADAPTER_BLUETOOTH_TEST) +extern int AdapterBlueToothTest(void); +int cmd_AdapterBlueToothTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + FrameworkInit(); + AdapterBlueToothTest(); + return OK; +} +#endif + #if defined(CONFIG_K210_FFT_TEST) && !defined(CONFIG_NSH_DISABLE_K210_FFT) extern void nuttx_k210_fft_test(void); int cmd_fft(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c index d44347b2d..acc04fb15 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c @@ -22,7 +22,7 @@ * @file nsh_command.c * @brief nuttx source code * https://github.com/apache/incubator-nuttx-apps -* @version 10.2.0 +* @version 10.2.0 * @author AIIT XUOS Lab * @date 2022-03-17 */ @@ -590,6 +590,10 @@ static const struct cmdmap_s g_cmdmap[] = { "xd", cmd_xd, 3, 3, " " }, #endif +#if defined(CONFIG_BSP_USING_CH438) && !defined(CONFIG_NSH_DISABLE_CH438) + { "ch438", cmd_Ch438, 1, 1, "[ch438 demo cmd.]" }, +#endif + #if defined(CONFIG_APPLICATION_SENSOR_HCHO_TB600B_WQ_HCHO1OS) && !defined(CONFIG_NSH_DISABLE_HCHO_TB600B_WQ_HCHO1OS) { "hcho1os", cmd_Hcho1os, 1, 1, "[get the concentration of formaldehyde with sensor tb600b_wq_hcho1os.]" }, #endif @@ -654,7 +658,7 @@ static const struct cmdmap_s g_cmdmap[] = { "recvzigbee", cmd_recvzigbee, 1, 1, "[receive message.]" }, #endif -#if defined(CONFIG_ADAPTER_SX1278) && !defined(CONFIG_NSH_DISABLE_ADAPTER_LORATEST) +#if (defined(CONFIG_ADAPTER_LORA_SX1278) || defined(CONFIG_ADAPTER_LORA_E220)) && !defined(CONFIG_NSH_DISABLE_ADAPTER_LORATEST) { "AdapterLoraTest", cmd_AdapterLoraTest, 1, 1, "[Lora sx128 test.]" }, #endif @@ -662,6 +666,22 @@ static const struct cmdmap_s g_cmdmap[] = { "Adapter4GTest", cmd_Adapter4GTest, 1, 1, "[4G ec200t test.]" }, #endif +#if defined(CONFIG_ADAPTER_LORA_E220) && !defined(CONFIG_NSH_DISABLE_E220_LORA_RECEIVE) + { "E220Receive", cmd_E220LoraReceive, 1, 1, "[e220 lora receive.]" }, +#endif + +#if defined(CONFIG_ADAPTER_LORA_E220) && !defined(CONFIG_NSH_DISABLE_E220_LORA_SEND) + { "E220Send", cmd_E220LoraSend, 1, 2, "[e220loraSend ]" }, +#endif + +#if defined(CONFIG_ADAPTER_BLUETOOTH_HC08) && !defined(CONFIG_NSH_DISABLE_ADAPTER_BLUETOOTH_TEST) + { "AdapterBlueToothTest", cmd_AdapterBlueToothTest, 1, 1, "[BlueTooth hc08 test.]" }, +#endif + +#if defined(CONFIG_ADAPTER_ESP07S_WIFI) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) + { "wifitest", cmd_AdapterWifiTest, 1, 8, "[WIFI test.]" }, +#endif + #if defined(CONFIG_K210_FFT_TEST) && !defined(CONFIG_NSH_DISABLE_K210_FFT) { "fft", cmd_fft, 1, 1, "[K210 fft function.]" }, #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/build.sh b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/build.sh old mode 100644 new mode 100755 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/Kconfig index d12f9651c..e7243e890 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/Kconfig @@ -1812,6 +1812,38 @@ config DEBUG_VIDEO_INFO Enable video informational output to SYSLOG. endif # DEBUG_VIDEO + +config DEBUG_CH438 + bool "CH438 Debug Features" + default n + ---help--- + Enable CH438 debug features. + +if DEBUG_CH438 + +config DEBUG_CH438_ERROR + bool "CH438 Error Output" + default n + depends on DEBUG_ERROR + ---help--- + Enable CH438 error output to SYSLOG. + +config DEBUG_CH438_WARN + bool "CH438 Warnings Output" + default n + depends on DEBUG_WARN + ---help--- + Enable CH438 warning output to SYSLOG. + +config DEBUG_CH438_INFO + bool "CH438 Informational Output" + default n + depends on DEBUG_INFO + ---help--- + Enable CH438 informational output to SYSLOG. + +endif # DEBUG_CH438 + endif # DEBUG_FEATURES config ARCH_HAVE_STACKCHECK diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/input/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/input/Kconfig new file mode 100755 index 000000000..68504001c --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/input/Kconfig @@ -0,0 +1,570 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig INPUT + bool "Input Device Support" + default n + ---help--- + This directory holds implementations of input device drivers. + This includes such things as touchscreen and keypad drivers. + See include/nuttx/input/*.h for registration information. + +if INPUT + +config INPUT_MOUSE + bool "Enable mouse support" + default n + ---help--- + Enable support for mouse devices. + +if INPUT_MOUSE + +config INPUT_MOUSE_WHEEL + bool "Enable mouse wheel support" + default n + ---help--- + Enable support for a 4-button mouse report that includes a while + position. + +endif # INPUT_MOUSE + +config INPUT_TOUCHSCREEN + bool + default n + +config INPUT_MAX11802 + bool "MAX11802 touchscreen controller" + default n + select SPI + select INPUT_TOUCHSCREEN + ---help--- + Enable support for the MAX11802 touchscreen controller + +config INPUT_TSC2007 + bool "TI TSC2007 touchscreen controller" + default n + select I2C + select INPUT_TOUCHSCREEN + ---help--- + Enable support for the TI TSC2007 touchscreen controller + +if INPUT_TSC2007 + +config TSC2007_8BIT + bool "TSC2007 8-bit Conversions" + default n + ---help--- + Use faster, but less accurate, 8-bit conversions. Default: 12-bit conversions. + +config TSC2007_MULTIPLE + bool "Multiple TSC2007 Devices" + default n + ---help--- + Can be defined to support multiple TSC2007 devices on board. + +config TSC2007_NPOLLWAITERS + int "Number TSC2007 poll waiters" + default 4 + ---help--- + Maximum number of threads that can be waiting on poll() + +endif # INPUT_TSC2007 + +config INPUT_FT5X06 + bool "FocalTech FT5x06 multi-touch, capacitive touch panel controller" + default n + select I2C + select INPUT_TOUCHSCREEN + ---help--- + Enable support for the FocalTech FT5x06 multi-touch, capacitive + touch panel controller + +config INPUT_GT9XX + bool "Goodix GT9XX touch panel controller" + default n + select I2C + select INPUT_TOUCHSCREEN + ---help--- + Enable support for the Goodix GT9XX multi-touch, capacitive + touch panel controller + +config INPUT_FT5336 + bool "FocalTech FT5336 multi-touch, capacitive touch panel controller" + default n + select I2C + select INPUT_FT5X06 + select INPUT_TOUCHSCREEN + depends on EXPERIMENTAL + ---help--- + Enable support for the FocalTech FT5x06 multi-touch, capacitive + touch panel controller + +if INPUT_FT5X06 + +config FT5X06_POLLMODE + bool "Polled mode" + default n + ---help--- + Run the FT5x06 in a non-interrupt driven polled mode. Events will + not be driven by interrupts but rather based on a timed poll. + + This is a non-optimal design both because (1) it will lead to delays + in detecting touch related events and (2) it will consume a + significant amount of CPU time to perform the polling. + +config FT5X06_SWAPXY + bool "Swap X/Y" + default n + ---help--- + Reverse the meaning of X and Y to handle different LCD orientations. + +config FT5X06_SINGLEPOINT + bool "Single point" + default n + ---help--- + Do no report multi-touch events + +if FT5X06_SINGLEPOINT + +config FT5X06_THRESHX + int "X threshold" + default 12 + ---help--- + New touch positions will only be reported when the X or Y data changes by these + thresholds. This trades reduced data rates for some loss in dragging accuracy. For + 12-bit values the raw ranges are 0-4095. So for example, if your display is + 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12 + +config FT5X06_THRESHY + int "Y threshold" + default 12 + ---help--- + New touch positions will only be reported when the X or Y data changes by these + thresholds. This trades reduced data rates for some loss in dragging accuracy. For + 12-bit values the raw ranges are 0-4095. So for example, if your display is + 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12 + +endif # FT5X06_SINGLEPOINT + +config FT5X06_NPOLLWAITERS + int "Number FT5336/FT5x06 poll waiters" + default 4 + ---help--- + Maximum number of threads that can be waiting on poll() + +endif # INPUT_FT5X06 + +config INPUT_ADS7843E + bool "TI ADS7843/TSC2046 touchscreen controller" + default n + select SPI + select INPUT_TOUCHSCREEN + ---help--- + Enable support for the TI/Burr-Brown ADS7842 touchscreen controller. I believe + that driver should be compatible with the TI/Burr-Brown TSC2046 and XPT2046 + touchscreen controllers as well. + +if INPUT_ADS7843E + +config ADS7843E_MULTIPLE + bool "Multiple ADS7843E Devices" + default n + ---help--- + Can be defined to support multiple ADS7843E devices on board. + +config ADS7843E_NPOLLWAITERS + int "Number poll waiters" + default 4 + ---help--- + Maximum number of threads that can be waiting on poll() + +config ADS7843E_SPIDEV + int "SPI bus number" + default 0 + ---help--- + Selects the SPI bus number identifying that SPI interface that + connects the ADS843E to the MCU. + +config ADS7843E_DEVMINOR + int "Input device minor number" + default 0 + ---help--- + The ADS7843E device will be registered as /dev/inputN where N is the + value provided by this setting. + +config ADS7843E_SPIMODE + int "SPI mode" + default 0 + range 0 3 + ---help--- + Controls the SPI mode. The device should work in mode 0, but + sometimes you need to experiment. + +config ADS7843E_FREQUENCY + int "SPI frequency" + default 100000 + ---help--- + Define to use a different SPI bus frequency. + +config ADS7843E_SWAPXY + bool "Swap X/Y" + default n + ---help--- + Reverse the meaning of X and Y to handle different LCD orientations. + +config ADS7843E_THRESHX + int "X threshold" + default 12 + ---help--- + New touch positions will only be reported when the X or Y data changes by these + thresholds. This trades reduced data rates for some loss in dragging accuracy. For + 12-bit values the raw ranges are 0-4095. So for example, if your display is + 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12 + +config ADS7843E_THRESHY + int "Y threshold" + default 12 + ---help--- + New touch positions will only be reported when the X or Y data changes by these + thresholds. This trades reduced data rates for some loss in dragging accuracy. For + 12-bit values the raw ranges are 0-4095. So for example, if your display is + 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12 + +endif # INPUT_ADS7843E + +config INPUT_MXT + bool "Atmel maXTouch Driver" + select INPUT_TOUCHSCREEN + default n + ---help--- + Enables support for the Atmel maXTouch driver + +if INPUT_MXT + +config MXT_THRESHX + int "X threshold" + default 5 + ---help--- + New touch positions will only be reported when the X or Y data + changes by these thresholds. This trades reduced data rates for some + loss in dragging accuracy. For 12-bit values the raw ranges are + 0-4095. So for example, if your display is 800x480, then THRESHX=5 + and THRESHY=8 would correspond to a one pixel change. Default: 5 + + NOTE: This does nothing to reduce the interrupt rate. It only + reduces the rate at which touch events are reports. + +config MXT_THRESHY + int "Y threshold" + default 8 + ---help--- + New touch positions will only be reported when the X or Y data + changes by these thresholds. This trades reduced data rates for some + loss in dragging accuracy. For 12-bit values the raw ranges are + 0-4095. So for example, if your display is 800x480, then THRESHX=5 + and THRESHY=8 would correspond to a one pixel change. Default: 8 + + NOTE: This does nothing to reduce the interrupt rate. It only + reduces the rate at which touch events are reports. + +config MXT_NPOLLWAITERS + int "Number poll waiters" + default 4 + ---help--- + Maximum number of threads that can be waiting on poll() + +config MXT_DISABLE_CONFIG_DEBUG_INFO + bool "Disable verbose debug output" + default y + depends on DEBUG_INPUT_INFO + ---help--- + The maXTouch tends to generate interrupts at a high rate during the + contact. If verbose debug is enabled in this driver, you may not + be able to get anything done because of the high debug output rate. + + This setting will allow you to keep verbose touchscreen debug output + in other modules, but to specifically suppress the debug out from + the MXT driver. Debug (non-verbose) errors will still be generated, + but the chit-chat level will be eliminated. + +endif # INPUT_MXT + +config INPUT_STMPE811 + bool "STMicro STMPE811 Driver" + default n + select INPUT_TOUCHSCREEN + ---help--- + Enables support for the STMPE811 driver + +if INPUT_STMPE811 + +choice + prompt "STMPE Interface" + default STMPE811_I2C + +config STMPE811_SPI + bool "SPI Interface" + select SPI + ---help--- + Enables support for the SPI interface (not currently supported) + +config STMPE811_I2C + bool "STMPE811 I2C Interface" + select I2C + ---help--- + Enables support for the I2C interface + +endchoice + +config STMPE811_ACTIVELOW + bool "Active Low Interrupt" + default n + ---help--- + The STMPE811 interrupt is provided by a discrete input (usually a + GPIO interrupt on most MCU architectures). This setting determines + whether the interrupt is active high (or rising edge triggered) or + active low (or falling edge triggered). Default: Active + high/rising edge. + +config STMPE811_EDGE + bool "Edge triggered Interrupt" + default n + ---help--- + The STMPE811 interrupt is provided by a discrete input (usually a + GPIO interrupt on most MCU architectures). This setting determines + whether the interrupt is edge or level triggered. Default: Level + triggered. + +config STMPE811_MULTIPLE + bool "Multiple STMPE811 Devices" + default n + ---help--- + Can be defined to support multiple STMPE811 devices on board. + +config STMPE811_NPOLLWAITERS + int "Number poll waiters" + default 4 + ---help--- + Maximum number of threads that can be waiting on poll() + +config STMPE811_TSC_DISABLE + bool "Disable STMPE811 Touchscreen Support" + default n + ---help--- + Disable driver touchscreen functionality. + +config STMPE811_SWAPXY + bool "Swap X/Y" + default n + depends on !STMPE811_TSC_DISABLE + ---help--- + Reverse the meaning of X and Y to handle different LCD orientations. + +config STMPE811_THRESHX + int "X threshold" + default 12 + depends on !STMPE811_TSC_DISABLE + ---help--- + STMPE811 touchscreen data comes in a a very high rate. New touch positions + will only be reported when the X or Y data changes by these thresholds. + This trades reduced data rates for some loss in dragging accuracy. The + STMPE811 is configure for 12-bit values the raw ranges are 0-4095. So + for example, if your display is 320x240, then THRESHX=13 and THRESHY=17 + would correspond to one pixel. Default: 12 + +config STMPE811_THRESHY + int "Y threshold" + default 12 + depends on !STMPE811_TSC_DISABLE + ---help--- + STMPE811 touchscreen data comes in a a very high rate. New touch positions + will only be reported when the X or Y data changes by these thresholds. + This trades reduced data rates for some loss in dragging accuracy. The + STMPE811 is configure for 12-bit values the raw ranges are 0-4095. So + for example, if your display is 320x240, then THRESHX=13 and THRESHY=17 + would correspond to one pixel. Default: 12 + +config STMPE811_ADC_DISABLE + bool "Disable STMPE811 ADC Support" + default y + ---help--- + Disable driver ADC functionality. + +config STMPE811_GPIO_DISABLE + bool "Disable STMPE811 GPIO Support" + default y + ---help--- + Disable driver GPIO functionality. + +config STMPE811_GPIOINT_DISABLE + bool "Disable STMPE811 GPIO Interrupt Support" + default y + depends on !STMPE811_GPIO_DISABLE + ---help--- + Disable driver GPIO interrupt functionality (ignored if GPIO functionality is + disabled). + +config STMPE811_TEMP_DISABLE + bool "Disable STMPE811 Temperature Sensor Support" + default y + ---help--- + Disable driver temperature sensor functionality. + +config STMPE811_REGDEBUG + bool "Enable Register-Level STMPE811 Debug" + default n + depends on DEBUG_FEATURES + ---help--- + Enable very low register-level debug output. + +endif # INPUT_STMPE811 + +config INPUT_CYPRESS_MBR3108 + bool "Enable Cypress MBR3108 CapSense driver" + default n + select INPUT_TOUCHSCREEN + ---help--- + Enable support for Cypress MBR3108 CapSense touch button & proximity + input sensor. + +if INPUT_CYPRESS_MBR3108 + +config INPUT_CYPRESS_MBR3108_DEBUG + bool "Enable debug support for Cypress sensor" + default n + depends on DEBUG_FEATURES + ---help--- + Enable debugging traces for MBR3108 driver + +config INPUT_CYPRESS_MBR3108_NPOLLWAITERS + int "Number of waiters to poll" + default 1 + ---help--- + Maximum number of threads that can be waiting on poll() + +endif # INPUT_CYPRESS_MBR3108 + +config INPUT_BUTTONS + bool "Button Inputs" + default n + ---help--- + Enable standard button upper half driver. + +if INPUT_BUTTONS + +config INPUT_BUTTONS_LOWER + bool "Generic Lower Half Button Driver" + default n + depends on ARCH_BUTTONS && ARCH_IRQBUTTONS + ---help--- + If the board supports the standard button interfaces as + defined in include/nuttx/board.h header file, then this + standard button lower half driver might be usable. + + In order for this generic driver to be usable: + + 1. The board implementation must provide the button + interfaces as defined in include/nuttx/board.h + 2. The board implementation must support interrupts for each + button. + + If your board does not meet these requirements, then the + button_lower.c file can still be copied to your your + board src/ directory and modified for your specific board + requirements. + +config INPUT_BUTTONS_NPOLLWAITERS + int "Max Number of Poll Waiters" + default 2 + +endif # INPUT_BUTTONS + +config INPUT_DJOYSTICK + bool "Discrete Joystick" + default n + ---help--- + Enable standard discrete joystick upper half driver. A discrete + joystick refers to a joystick that could be implemented entirely + with GPIO input pins. So up, down, left, and right are all discrete + values like buttons (as opposed to integer values like you might + obtain from an analog joystick). + +if INPUT_DJOYSTICK + +config INPUT_DJOYSTICK_NPOLLWAITERS + int "Max Number of Poll Waiters" + default 2 + +endif # INPUT_DJOYSTICK + +config INPUT_AJOYSTICK + bool "Analog Joystick" + default n + ---help--- + Enable standard analog joystick upper half driver. An analog + joystick refers to a joystick that provides position data as an + integer value that might have been obtained through Analog- + to-Digital Conversion (ADC). The analog positional data may also + be accompanied by discrete button data. + +if INPUT_AJOYSTICK + +config INPUT_AJOYSTICK_NPOLLWAITERS + int "Max Number of Poll Waiters" + default 2 + +endif # INPUT_AJOYSTICK + +config INPUT_NUNCHUCK + bool "Nintendo Wii Nunchuck Joystick (White Model)" + default n + select I2C + ---help--- + Enable a Nintendo Wii Nunchuck joystick upper half driver. The + nunchuck joystick provides position data as an integer value.The + analog positional data may also be accompanied by discrete + button data. + +if INPUT_NUNCHUCK + +config NUNCHUCK_NPOLLWAITERS + int "Max Number of Poll Waiters" + default 2 + +endif # INPUT_NUNCHUCK + +config INPUT_SPQ10KBD + bool "Solder Party Q10 BlackBerry Keyboard" + default n + select I2C + ---help--- + Enable the Solder Party Q10 BlackBerry Keyboard support. This + exposes itself as a standard keyboard at /dev/kbdN. + This keyboard exists both as a standalone module and integrated + into the Solder Party Keyboard FeatherWing. Information on this + can be found at https://www.solder.party/docs/keyboard-pmod/ + +if INPUT_SPQ10KBD + +config SPQ10KBD_DJOY + bool "Joystick Interface for Buttons" + select INPUT_DJOYSTICK + default n + +config SPQ10KBD_REGDBG + bool "Keyboard Register Debug" + default n + +config SPQ10KBD_BUFSIZE + int "Keyboard Buffer Size" + default 10 + +config SPQ10KBD_NPOLLWAITERS + int "Max Number of Poll Waiters" + default 2 + +endif # INPUT_SPQ10KBD + +endif # INPUT diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/input/Make.defs b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/input/Make.defs new file mode 100755 index 000000000..605f6ae3b --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/input/Make.defs @@ -0,0 +1,100 @@ +############################################################################ +# drivers/input/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you 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. +# +############################################################################ + +# Don't build anything if there is no support for input devices + +ifeq ($(CONFIG_INPUT),y) + +# Include the selected touchscreen drivers + +ifeq ($(CONFIG_INPUT_TSC2007),y) + CSRCS += tsc2007.c +endif + +ifeq ($(CONFIG_INPUT_FT5X06),y) + CSRCS += ft5x06.c +endif + +ifeq ($(CONFIG_INPUT_GT9XX),y) + CSRCS += gt9xx.c +endif + +ifeq ($(CONFIG_INPUT_ADS7843E),y) + CSRCS += ads7843e.c +endif + +ifeq ($(CONFIG_INPUT_MAX11802),y) + CSRCS += max11802.c +endif + +ifeq ($(CONFIG_INPUT_MXT),y) + CSRCS += mxt.c +endif + +ifeq ($(CONFIG_INPUT_STMPE811),y) + CSRCS += stmpe811_base.c +ifneq ($(CONFIG_INPUT_STMPE811_TSC_DISABLE),y) + CSRCS += stmpe811_tsc.c +endif +ifneq ($(CONFIG_INPUT_STMPE811_GPIO_DISABLE),y) + CSRCS += stmpe811_gpio.c +endif +ifneq ($(CONFIG_INPUT_STMPE811_ADC_DISABLE),y) + CSRCS += stmpe811_adc.c +endif +ifneq ($(CONFIG_INPUT_STMPE811_TEMP_DISABLE),y) + CSRCS += stmpe811_temp.c +endif +endif + +ifeq ($(CONFIG_INPUT_CYPRESS_MBR3108),y) + CSRCS += cypress_mbr3108.c +endif + +ifeq ($(CONFIG_INPUT_BUTTONS),y) + CSRCS += button_upper.c +ifeq ($(CONFIG_INPUT_BUTTONS_LOWER),y) + CSRCS += button_lower.c +endif + +endif + +ifeq ($(CONFIG_INPUT_DJOYSTICK),y) + CSRCS += djoystick.c +endif + +ifeq ($(CONFIG_INPUT_AJOYSTICK),y) + CSRCS += ajoystick.c +endif + +ifeq ($(CONFIG_INPUT_NUNCHUCK),y) + CSRCS += nunchuck.c +endif + +ifeq ($(CONFIG_INPUT_SPQ10KBD),y) + CSRCS += spq10kbd.c +endif + +# Include input device driver build support + +DEPPATH += --dep-path input +VPATH += :input +CFLAGS += ${shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)input} +endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/input/gt9xx.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/input/gt9xx.c new file mode 100755 index 000000000..6d97db654 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/input/gt9xx.c @@ -0,0 +1,1415 @@ +/**************************************************************************** + * drivers/input/gt9xx.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/* References: + * Dec. 18, 2012 + */ + +/* The FT5x06 Series ICs are single-chip capacitive touch panel controller + * ICs with a built-in 8 bit Micro-controller unit (MCU). They adopt the + * mutual capacitance approach, which supports true multi-touch capability. + * In conjunction with a mutual capacitive touch panel, the FT5x06 have + * user-friendly input functions, which can be applied on many portable + * devices, such as cellular phones, MIDs, netbook and notebook personal + * computers. + */ + +/** + * @file gt9xx.c + * @brief refer to imxrt_gt9xx.c codes. + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.5.31 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Driver support ***********************************************************/ + +/* This format is used to construct the /dev/input[n] device driver path. It + * defined here so that it will be used consistently in all places. + */ + +#define DEV_FORMAT "/dev/input%d" +#define DEV_NAMELEN 16 + +#define GT9XX_VER_LEN 8 +#define GT9XX_INF_LEN 6 +#define GT9XX_CFG_LEN 3 + +/* In polled mode, the polling rate will decrease when there is no touch + * activity. These definitions represent the maximum and the minimum + * polling rates. + */ + +#define POLL_MINDELAY MSEC2TICK(50) +#define POLL_MAXDELAY MSEC2TICK(200) +#define POLL_INCREMENT MSEC2TICK(10) + +#define gt_print printf + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes the state of one GT9xx driver instance */ + +struct gt9xx_dev_s +{ + uint8_t crefs; /* Number of times the device + * has been opened */ + uint8_t nwaiters; /* Number of threads waiting for + * GT9xx data */ + volatile bool valid; /* True: New, valid touch data + * in touchbuf[] */ +#ifdef CONFIG_GT9XX_SINGLEPOINT + uint8_t lastid; /* Last reported touch id */ + uint8_t lastevent; /* Last reported event */ + int16_t lastx; /* Last reported X position */ + int16_t lasty; /* Last reported Y position */ +#endif + sem_t devsem; /* Manages exclusive access to + * this structure */ + sem_t waitsem; /* Used to wait for the + * availability of data */ + uint32_t frequency; /* Current I2C frequency */ +#ifdef CONFIG_GT9XX_POLLMODE + uint32_t delay; /* Current poll delay */ +#endif + + FAR const struct gt9xx_config_s *config; /* Board configuration data */ + FAR struct i2c_master_s *i2c; /* Saved I2C driver instance */ + struct work_s work; /* Supports the interrupt + * handling "bottom half" */ +#ifdef CONFIG_GT9XX_POLLMODE + struct wdog_s polltimer; /* Poll timer */ +#endif + uint8_t touchbuf[GT9XX_TOUCH_DATA_LEN]; /* Raw touch data */ + + /* The following is a list if poll structures of threads waiting for + * driver events. The 'struct pollfd' reference for each open is also + * retained in the f_priv field of the 'struct file'. + */ + + struct pollfd *fds[CONFIG_GT9XX_NPOLLWAITERS]; +}; + +// support 480 * 272 +uint8_t gt9xx_cfg_data[] = { + 0x5B, 0xE0, 0x01, 0x10, 0x01, 0x0A, 0x0D, 0x00, 0x01, 0x0A, + 0x28, 0x0F, 0x5A, 0x3C, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x28, 0x09, + 0x32, 0x34, 0x0C, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x1D, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x55, 0x94, 0xC5, 0x02, 0x07, 0x00, 0x00, 0x04, + 0x8D, 0x2B, 0x00, 0x80, 0x32, 0x00, 0x75, 0x3A, 0x00, 0x6C, + 0x43, 0x00, 0x64, 0x4F, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, + 0xF0, 0x4A, 0x3A, 0xFF, 0xFF, 0x27, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, + 0x14, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x26, 0x24, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, + 0x0C, 0x0A, 0x08, 0x06, 0x04, 0x02, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x81, 0x01 +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void gt9xx_notify(FAR struct gt9xx_dev_s *priv); +static void gt9xx_data_worker(FAR void *arg); +#ifdef CONFIG_GT9XX_POLLMODE +static void gt9xx_poll_timeout(wdparm_t arg); +#else +static int gt9xx_data_interrupt(int irq, FAR void *context, FAR void *arg); +#endif +static ssize_t gt9xx_sample(FAR struct gt9xx_dev_s *priv, FAR char *buffer, + size_t len); +static ssize_t gt9xx_waitsample(FAR struct gt9xx_dev_s *priv, + FAR char *buffer, size_t len); +static int gt9xx_bringup(FAR struct gt9xx_dev_s *priv); +static void gt9xx_shutdown(FAR struct gt9xx_dev_s *priv); + +/* Character driver methods */ + +static int gt9xx_open(FAR struct file *filep); +static int gt9xx_close(FAR struct file *filep); +static ssize_t gt9xx_read(FAR struct file *filep, FAR char *buffer, + size_t len); +static int gt9xx_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +static int gt9xx_poll(FAR struct file *filep, struct pollfd *fds, + bool setup); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This the vtable that supports the character driver interface */ + +static const struct file_operations gt9xx_fops = +{ + gt9xx_open, /* open */ + gt9xx_close, /* close */ + gt9xx_read, /* read */ + NULL, /* write */ + NULL, /* seek */ + gt9xx_ioctl, /* ioctl */ + gt9xx_poll /* poll */ +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , NULL /* unlink */ +#endif +}; + +/* Maps GT9xx touch events into bit encoded representation used by NuttX */ + +static const uint8_t g_event_map[4] = +{ + (TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID), /* GT9XX_DOWN */ + (TOUCH_UP | TOUCH_ID_VALID), /* GT9XX_UP */ + (TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID), /* GT9XX_CONTACT */ + TOUCH_ID_VALID /* GT9XX_INVALID */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int gt9xx_write_reg(FAR struct gt9xx_dev_s *priv, uint8_t *reg_val, uint16_t len) +{ + FAR const struct gt9xx_config_s *config; + struct i2c_msg_s msg[2]; + int ret; + int retries = 0; + + config = priv->config; + DEBUGASSERT(config != NULL); + + msg[0].frequency = priv->frequency; + msg[0].addr = config->address; + msg[0].flags = 0; + msg[0].buffer = reg_val; + msg[0].length = len; + + while(retries < 5) + { + ret = I2C_TRANSFER(priv->i2c, msg, 1); + if(ret == 2) break; + retries ++; + } + if (ret < 0) + { + ierr("gt: [%s] failed freq %ld addr %x ret %d\n", __func__, priv->frequency, config->address, ret); + return ret; + } + return ret; +} + +static int gt9xx_read_reg(FAR struct gt9xx_dev_s *priv, uint8_t *reg_addr, uint8_t *reg_val, uint16_t len) +{ + FAR const struct gt9xx_config_s *config; + struct i2c_msg_s msg[2]; + int ret; + int retries = 0; + + config = priv->config; + DEBUGASSERT(config != NULL); + + msg[0].frequency = priv->frequency; + msg[0].addr = config->address; + msg[0].flags = 0; + msg[0].buffer = reg_addr; + msg[0].length = GT9XX_ADDR_LENGTH; + + msg[1].frequency = priv->frequency; + msg[1].addr = config->address; + msg[1].flags = I2C_M_READ; + msg[1].buffer = reg_val; + msg[1].length = len - GT9XX_ADDR_LENGTH; + while(retries < 5) + { + ret = I2C_TRANSFER(priv->i2c, msg, 2); + if(ret == 2) break; + retries ++; + } + if (ret < 0) + { + ierr("gt: [%s] failed freq %ld addr %x ret %d\n", __func__, priv->frequency, config->address, ret); + return ret; + } + return ret; +} + +/**************************************************************************** + * Name: gt9xx_write_config + ****************************************************************************/ + +static int gt9xx_write_config(FAR struct gt9xx_dev_s *priv) +{ + int i, ret = -1; + uint8_t check_sum = 0; + uint8_t offet = GT9XX_REG_CONFIG_CHKSUM - GT9XX_REG_CONFIG_DATA; + + const uint8_t* cfg_info = gt9xx_cfg_data; + uint8_t cfg_info_len = sizeof(gt9xx_cfg_data) / sizeof(gt9xx_cfg_data[0]); + + uint8_t reg_data[GT9XX_CONFIG_MAX_LENGTH + GT9XX_ADDR_LENGTH] + = {GT9XX_REG_CONFIG_DATA >> 8, GT9XX_REG_CONFIG_DATA & 0xff}; + + memset(®_data[GT9XX_ADDR_LENGTH], 0, GT9XX_CONFIG_MAX_LENGTH); + memcpy(®_data[GT9XX_ADDR_LENGTH], cfg_info, cfg_info_len); + + for (i = GT9XX_ADDR_LENGTH; i < offet + GT9XX_ADDR_LENGTH; i++) + { + check_sum += reg_data[i]; + } + + reg_data[offet + GT9XX_ADDR_LENGTH] = (~check_sum) + 1; //checksum + reg_data[offet + GT9XX_ADDR_LENGTH + 1] = 1; //refresh + + gt_print("Driver send config.\n"); + + ret = gt9xx_write_reg(priv, reg_data, offet + GT9XX_ADDR_LENGTH + 2); + + return ret; +} + + +/**************************************************************************** + * Name: gt9xx_notify + ****************************************************************************/ + +static void gt9xx_notify(FAR struct gt9xx_dev_s *priv) +{ + int i; + + /* If there are threads waiting on poll() for GT9xx data to become + * available, then wake them up now. NOTE: we wake up all waiting threads + * because we do not know that they are going to do. If they all try to + * read the data, then some make end up blocking after all. + */ + + for (i = 0; i < CONFIG_GT9XX_NPOLLWAITERS; i++) + { + struct pollfd *fds = priv->fds[i]; + if (fds) + { + fds->revents |= POLLIN; + iinfo("Report events: %02x\n", fds->revents); + nxsem_post(fds->sem); + } + } + + /* If there are threads waiting for read data, then signal one of them + * that the read data is available. + */ + + if (priv->nwaiters > 0) + { + /* After posting this semaphore, we need to exit because the GT9xx + * is no longer available. + */ + + nxsem_post(&priv->waitsem); + } +} + +/**************************************************************************** + * Name: gt9xx_data_worker + ****************************************************************************/ + +static void gt9xx_data_worker(FAR void *arg) +{ + FAR struct gt9xx_dev_s *priv = (FAR struct gt9xx_dev_s *)arg; + FAR const struct gt9xx_config_s *config; + FAR struct gt9xx_touch_data_s *sample; + uint8_t regaddr[3]; + int ret; + + /* Get a pointer the callbacks for convenience */ + + DEBUGASSERT(priv != NULL && priv->config != NULL); + config = priv->config; + + /* We need to have exclusive access to the touchbuf so that we do not + * corrupt any read operation that is in place. + */ + do + { + ret = nxsem_wait_uninterruptible(&priv->devsem); + + /* This would only fail if something canceled the worker thread? + * That is not expected. + */ + + DEBUGASSERT(ret == OK || ret == -ECANCELED); + } + while (ret < 0); + + /* Read touch data */ + + /* Set up the address write operation */ + + regaddr[0] = GT9XX_REG_READ_COOR >> 8; + regaddr[1] = GT9XX_REG_READ_COOR & 0xFF; + + ret = gt9xx_read_reg(priv, regaddr, priv->touchbuf, GT9XX_TOUCH_DATA_LEN); + + if (ret >= 0) + { + /* In polled mode, we may read invalid touch data. If there is + * no touch data, the GT9xx returns all 0xff the very first time. + * After that, it returns the same old stale data when there is + * no touch data. + */ + + if(priv->touchbuf[0] & 0xf) + { + gt_print("get i2c %x reg %x %x ret %d ", config->address, regaddr[0], regaddr[1], ret); + for(int i = 0; i < GT9XX_TOUCH_DATA_LEN; i ++) + { + gt_print("%x ", priv->touchbuf[i]); + } + gt_print("\n"); + } + + sample = (FAR struct gt9xx_touch_data_s *)priv->touchbuf; + + /* Notify waiters (only if we ready some valid data). + * + * REVISIT: For improved performance consider moving the duplicate + * report and thresholding logic from gt9xx_sample() to here. That + * would save a context switch. + */ + sample->tdstatus &= 0xf; + + if (sample->tdstatus <= GT9XX_MAX_TOUCHES) + { + /* Notify any waiters that new GT9xx data is available */ + + priv->valid = true; + gt9xx_notify(priv); + } + +#ifdef CONFIG_GT9XX_POLLMODE + /* Update the poll rate */ + + if (sample->tdstatus > 0 && sample->tdstatus <= GT9XX_MAX_TOUCHES) + { + /* Keep it at the minimum if touches are detected. */ + + priv->delay = POLL_MINDELAY; + } + else if (priv->delay < POLL_MAXDELAY) + { + /* Otherwise, let the poll rate rise gradually up to the maximum + * if there is no touch. + */ + + priv->delay += POLL_INCREMENT; + } +#endif + } + + /* cmd end */ + gt9xx_write_reg(priv, regaddr, 3); + +#ifdef CONFIG_GT9XX_POLLMODE + /* Exit, re-starting the poll. */ + + wd_start(&priv->polltimer, priv->delay, + gt9xx_poll_timeout, (wdparm_t)priv); + +#else + /* Exit, re-enabling GT9xx interrupts */ + config->enable(config, true); +#endif + + nxsem_post(&priv->devsem); +} + +/**************************************************************************** + * Name: gt9xx_poll_timeout + ****************************************************************************/ + +#ifdef CONFIG_GT9XX_POLLMODE +static void gt9xx_poll_timeout(wdparm_t arg) +{ + FAR struct gt9xx_dev_s *priv = (FAR struct gt9xx_dev_s *)arg; + int ret; + + /* Transfer processing to the worker thread. Since GT9xx poll timer is + * disabled while the work is pending, no special action should be + * required to protected the work queue. + */ + + DEBUGASSERT(priv->work.worker == NULL); + ret = work_queue(HPWORK, &priv->work, gt9xx_data_worker, priv, 0); + if (ret != 0) + { + ierr("ERROR: Failed to queue work: %d\n", ret); + } +} +#endif + +/**************************************************************************** + * Name: gt9xx_data_interrupt + ****************************************************************************/ + +#ifndef CONFIG_GT9XX_POLLMODE +static int gt9xx_data_interrupt(int irq, FAR void *context, FAR void *arg) +{ + FAR struct gt9xx_dev_s *priv = (FAR struct gt9xx_dev_s *)arg; + FAR const struct gt9xx_config_s *config; + int ret; + + /* Get a pointer the callbacks for convenience (and so the code is not so + * ugly). + */ + + config = priv->config; + DEBUGASSERT(config != NULL); + + /* Disable further interrupts */ + + config->enable(config, false); + + /* Transfer processing to the worker thread. Since GT9xx interrupts are + * disabled while the work is pending, no special action should be required + * to protected the work queue. + */ + + DEBUGASSERT(priv->work.worker == NULL); + ret = work_queue(HPWORK, &priv->work, gt9xx_data_worker, priv, 0); + if (ret != 0) + { + ierr("ERROR: Failed to queue work: %d\n", ret); + } + + /* Clear any pending interrupts and return success */ + + config->clear(config); + return OK; +} +#endif + +/**************************************************************************** + * Name: gt9xx_sample + ****************************************************************************/ + +#ifdef CONFIG_GT9XX_SINGLEPOINT +static ssize_t gt9xx_sample(FAR struct gt9xx_dev_s *priv, FAR char *buffer, + size_t len) +{ + FAR struct gt9xx_touch_data_s *raw; + FAR struct gt9xx_touch_point_s *touch; + FAR struct touch_sample_s *sample; + FAR struct touch_point_s *point; + int16_t x; + int16_t y; + uint8_t event; + uint8_t id; + uint8_t finger; + + if (!priv->valid) + { + return 0; /* Nothing to read */ + } + + /* Raw data pointers (source) */ + + raw = (FAR struct gt9xx_touch_data_s *)priv->touchbuf; + touch = raw->touch; + + finger = priv->touchbuf[0]; + + if(finger == 0x0) + { + goto reset_and_drop; + } + + if((finger & 0x80) == 0) + { + goto reset_and_drop; + } + + if((finger & 0xf) == 0) + { + goto reset_and_drop; + } + + /* Get the reported X and Y positions */ +#ifdef CONFIG_GT9XX_SWAPXY + y = TOUCH_POINT_GET_X(touch[0]); + x = TOUCH_POINT_GET_Y(touch[0]); +#else + x = TOUCH_POINT_GET_X(touch[0]); + y = TOUCH_POINT_GET_Y(touch[0]); +#endif + + /* Get the touch point ID and event */ + + event = GT9XX_DOWN; + id = TOUCH_POINT_GET_ID(touch[0]); + + if (event == GT9XX_INVALID) + { + priv->lastevent = GT9XX_INVALID; + goto reset_and_drop; + } + + gt_print("gt: [%s] event %d id %d\n", __func__, event, id); + + if (id == priv->lastid && event == priv->lastevent) + { + /* Same ID and event.. Is there positional data? */ + + if (raw->tdstatus == 0 || event == GT9XX_UP) + { + /* No... no new touch data */ + + goto reset_and_drop; + } + else + { + int16_t deltax; + int16_t deltay; + + /* Compare the change in position from the last report. */ + + deltax = (x - priv->lastx); + if (deltax < 0) + { + deltax = -deltax; + } + + if (deltax < CONFIG_GT9XX_THRESHX) + { + /* There as been no significant change in X, try Y */ + + deltay = (y - priv->lasty); + if (deltay < 0) + { + deltay = -deltay; + } + + if (deltax < CONFIG_GT9XX_THRESHX) + { + /* Ignore... no significant change in Y either */ + + goto drop; + } + } + } + } + + priv->lastid = id; + priv->lastevent = event; + priv->lastx = x; + priv->lasty = y; + + /* User data buffer points (sink) */ + + /* Return the number of touches read */ + + sample = (FAR struct touch_sample_s *)buffer; + sample->npoints = 1; + + /* Decode and return the single touch point */ + + point = sample->point; + point[0].id = id; + point[0].flags = g_event_map[event]; + point[0].x = x; + point[0].y = y; + point[0].h = 0; + point[0].w = 0; + point[0].pressure = 0; + + priv->valid = false; + return SIZEOF_TOUCH_SAMPLE_S(1); + +reset_and_drop: + priv->lastx = 0; + priv->lasty = 0; +drop: + priv->valid = false; + return 0; /* No new touches read. */ +} +#else +static ssize_t gt9xx_sample(FAR struct gt9xx_dev_s *priv, FAR char *buffer, + size_t len) +{ + FAR struct gt9xx_touch_data_s *raw; + FAR struct gt9xx_touch_point_s *touch; + FAR struct touch_sample_s *sample; + FAR struct touch_point_s *point; + unsigned int maxtouches; + unsigned int ntouches; + int i; + + maxtouches = (len - sizeof(int)) / sizeof(struct touch_point_s); + DEBUGASSERT(maxtouches > 0); /* Already verified */ + + if (!priv->valid) + { + return 0; /* Nothing to read */ + } + + /* Raw data pointers (source) */ + + raw = (FAR struct gt9xx_touch_data_s *)priv->touchbuf; + touch = raw->touch; + + /* Decode number of touches */ + + ntouches = raw->tdstatus; + DEBUGASSERT(ntouches <= GT9XX_MAX_TOUCHES); + + if (ntouches > maxtouches) + { + ntouches = maxtouches; + } + + if (ntouches < 1) + { + priv->valid = false; + return 0; /* No touches read. */ + } + + /* User data buffer points (sink) */ + + sample = (FAR struct touch_sample_s *)buffer; + point = sample->point; + + /* Return the number of touches read */ + + sample->npoints = ntouches; + + /* Decode and return the touch points */ + + for (i = 0; i < ntouches; i++) + { + int event = TOUCH_POINT_GET_EVENT(touch[i]); + + point[i].id = TOUCH_POINT_GET_ID(touch[i]); + point[i].flags = g_event_map[event]; +#ifdef CONFIG_GT9XX_SWAPXY + point[i].y = TOUCH_POINT_GET_X(touch[i]); + point[i].x = TOUCH_POINT_GET_Y(touch[i]); +#else + point[i].x = TOUCH_POINT_GET_X(touch[i]); + point[i].y = TOUCH_POINT_GET_Y(touch[i]); +#endif + point[i].h = 0; + point[i].w = 0; + point[i].pressure = 0; + +// gt_print("gt: [%s] %d - touch %x %x %x %x id %d flags %x x %d y %d\n", __func__, +// i, +// touch[i].xl, touch[i].xh, touch[i].yl, touch[i].yh, +// point[i].id, point[i].flags, +// point[i].x, point[i].y); + + } + + priv->valid = false; + return SIZEOF_TOUCH_SAMPLE_S(ntouches); +} +#endif /* CONFIG_GT9XX_SINGLEPOINT */ + +/**************************************************************************** + * Name: gt9xx_waitsample + ****************************************************************************/ + +static ssize_t gt9xx_waitsample(FAR struct gt9xx_dev_s *priv, + FAR char *buffer, size_t len) +{ + int ret; + + /* Disable pre-emption to prevent other threads from getting control while + * we muck with the semaphores. + */ + + sched_lock(); + + /* Now release the semaphore that manages mutually exclusive access to + * the device structure. This may cause other tasks to become ready to + * run, but they cannot run yet because pre-emption is disabled. + */ + + nxsem_post(&priv->devsem); + + /* Try to get the a sample... if we cannot, then wait on the semaphore + * that is posted when new sample data is available. + */ + + while (!priv->valid) + { + /* Increment the count of waiters */ + + priv->nwaiters++; + + /* Wait for a change in the GT9xx state */ + + ret = nxsem_wait(&priv->waitsem); + priv->nwaiters--; + + if (ret < 0) + { + ierr("ERROR: nxsem_wait failed: %d\n", ret); + goto errout; + } + } + + /* Re-acquire the semaphore that manages mutually exclusive access to + * the device structure. We may have to wait here. But we have our + * sample. Interrupts and pre-emption will be re-enabled while we wait. + */ + + ret = nxsem_wait(&priv->devsem); + if (ret >= 0) + { + /* Now sample the data. + * + * REVISIT: Is it safe to assume that priv->valid will always be + * true? I think that sched_lock() would protect the setting. + */ + + ret = gt9xx_sample(priv, buffer, len); + } + +errout: + /* Restore pre-emption. We might get suspended here but that is okay + * because we already have our sample. Note: this means that if there + * were two threads reading from the GT9xx for some reason, the data + * might be read out of order. + */ + + sched_unlock(); + return ret; +} + +int gt9xx_get_version(FAR struct gt9xx_dev_s *priv) +{ + FAR const struct gt9xx_config_s *config; + int ret; + uint8_t reg_addr[2]; + uint8_t reg_val[GT9XX_VER_LEN] = {0}; + + config = priv->config; + DEBUGASSERT(config != NULL); + + reg_addr[0] = (GT9XX_REG_VERSION) >> 8; /* config address */ + reg_addr[1] = (GT9XX_REG_VERSION) & 0xFF; + + ret = gt9xx_read_reg(priv, reg_addr, reg_val, GT9XX_VER_LEN); + + if (ret < 0) + { + ierr("gt: [%s] failed freq %ld addr %x ret %d\n", __func__, priv->frequency, config->address, ret); + return ret; + } + + gt_print("IC version: %s_%x%x\n", reg_val, reg_val[4], reg_val[5]); + + return OK; +} + +int gt9xx_get_info(FAR struct gt9xx_dev_s *priv) +{ + FAR const struct gt9xx_config_s *config; + int ret; + uint8_t reg_addr[2]; + uint8_t reg_val[GT9XX_INF_LEN] = {0}; + uint16_t abs_x_max = GT9XX_MAX_WIDTH; + uint16_t abs_y_max = GT9XX_MAX_HEIGHT; + uint8_t int_trigger_type = GT9XX_INT_TRIGGER; + + config = priv->config; + DEBUGASSERT(config != NULL); + + reg_addr[0] = (GT9XX_REG_CONFIG_DATA + 1) >> 8; /* config address */ + reg_addr[1] = (GT9XX_REG_CONFIG_DATA + 1) & 0xFF; + + ret = gt9xx_read_reg(priv, reg_addr, reg_val, GT9XX_INF_LEN); + + if (ret < 0) + { + ierr("gt: [%s] failed freq %ld addr %x ret %d\n", __func__, priv->frequency, config->address, ret); + return ret; + } + + abs_x_max = (reg_val[1] << 8) + reg_val[0]; + abs_y_max = (reg_val[3] << 8) + reg_val[2]; + + reg_addr[0] = (GT9XX_REG_CONFIG_DATA + 6) >> 8; /* config address */ + reg_addr[1] = (GT9XX_REG_CONFIG_DATA + 6) & 0xFF; + + ret = gt9xx_read_reg(priv, reg_addr, reg_val, GT9XX_CFG_LEN); + + if (ret < 0) + { + ierr("gt: [%s] failed freq %ld addr %x ret %d\n", __func__, priv->frequency, config->address, ret); + return ret; + } + + int_trigger_type = reg_val[0] & 0x03; + + iinfo("X_MAX = %d, Y_MAX = %d, TRIGGER = 0x%02x\n", + abs_x_max, abs_y_max, int_trigger_type); + + return OK; +} + + +/**************************************************************************** + * Name: gt9xx_bringup + ****************************************************************************/ + +static int gt9xx_bringup(FAR struct gt9xx_dev_s *priv) +{ + FAR const struct gt9xx_config_s *config; + config = priv->config; + DEBUGASSERT(config != NULL); + +#ifndef CONFIG_GT9XX_POLLMODE + /* Enable GT9xx interrupts */ + config->clear(config); + config->enable(config, true); +#endif + gt9xx_get_version(priv); + gt9xx_get_info(priv); + return OK; +} + +/**************************************************************************** + * Name: gt9xx_shutdown + ****************************************************************************/ + +static void gt9xx_shutdown(FAR struct gt9xx_dev_s *priv) +{ +#ifdef CONFIG_GT9XX_POLLMODE + /* Stop the poll timer */ + + wd_cancel(&priv->polltimer); + +#else + FAR const struct gt9xx_config_s *config = priv->config; + + /* Make sure that the GT9xx interrupt is disabled */ + + config->clear(config); + config->enable(config, false); +#endif +} + +/**************************************************************************** + * Name: gt9xx_open + ****************************************************************************/ + +static int gt9xx_open(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct gt9xx_dev_s *priv; + uint8_t tmp; + int ret; + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct gt9xx_dev_s *)inode->i_private; + + /* Get exclusive access to the driver data structure */ + + ret = nxsem_wait(&priv->devsem); + if (ret < 0) + { + ierr("ERROR: nxsem_wait failed: %d\n", ret); + return ret; + } + + /* Increment the reference count */ + + tmp = priv->crefs + 1; + if (tmp == 0) + { + /* More than 255 opens; uint8_t overflows to zero */ + + ret = -EMFILE; + goto errout_with_sem; + } + + /* When the reference increments to 1, this is the first open event + * on the driver.. and the time when we must initialize the driver. + */ + + if (tmp == 1) + { + ret = gt9xx_bringup(priv); + if (ret < 0) + { + ierr("ERROR: gt9xx_bringup failed: %d\n", ret); + goto errout_with_sem; + } + + ret = gt9xx_write_config(priv); + if (ret < 0) + { + ierr("ERROR: gt9xx_write_config failed: %d\n", ret); + goto errout_with_sem; + } + } + + /* Save the new open count on success */ + + priv->crefs = tmp; + +errout_with_sem: + nxsem_post(&priv->devsem); + return ret; +} + +/**************************************************************************** + * Name: gt9xx_close + ****************************************************************************/ + +static int gt9xx_close(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct gt9xx_dev_s *priv; + int ret; + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct gt9xx_dev_s *)inode->i_private; + + /* Get exclusive access to the driver data structure */ + + ret = nxsem_wait(&priv->devsem); + if (ret < 0) + { + ierr("ERROR: nxsem_wait failed: %d\n", ret); + return ret; + } + + /* Decrement the reference count unless it would decrement a negative + * value. + */ + + if (priv->crefs >= 1) + { + priv->crefs--; + } + + /* When the count decrements to zero, there are no further open references + * to the driver and it can be uninitialized. + */ + + if (priv->crefs == 0) + { + gt9xx_shutdown(priv); + } + + nxsem_post(&priv->devsem); + return OK; +} + +/**************************************************************************** + * Name: gt9xx_read + ****************************************************************************/ + +static ssize_t gt9xx_read(FAR struct file *filep, FAR char *buffer, + size_t len) +{ + FAR struct inode *inode; + FAR struct gt9xx_dev_s *priv; + int ret; + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct gt9xx_dev_s *)inode->i_private; + + /* Verify that the caller has provided a buffer large enough to receive + * the touch data. + */ + + if (len < SIZEOF_TOUCH_SAMPLE_S(1)) + { + /* We could provide logic to break up a touch report into segments and + * handle smaller reads... but why? + */ + + return -ENOSYS; + } + + /* Get exclusive access to the driver data structure */ + + ret = nxsem_wait(&priv->devsem); + if (ret < 0) + { + ierr("ERROR: nxsem_wait failed: %d\n", ret); + return ret; + } + + /* Try to read sample data. */ + + ret = gt9xx_sample(priv, buffer, len); + while (ret == 0) + { + /* Sample data is not available now. We would have to wait to receive + * sample data. If the user has specified the O_NONBLOCK option, then + * just return an error. + */ + + if (filep->f_oflags & O_NONBLOCK) + { + ret = -EAGAIN; + goto errout; + } + + /* Wait for sample data */ + + ret = gt9xx_waitsample(priv, buffer, len); + if (ret < 0) + { + /* We might have been awakened by a signal */ + + goto errout; + } + } + + ret = SIZEOF_TOUCH_SAMPLE_S(1); + +errout: + nxsem_post(&priv->devsem); + return ret; +} + +/**************************************************************************** + * Name: gt9xx_ioctl + ****************************************************************************/ + +static int gt9xx_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode; + FAR struct gt9xx_dev_s *priv; + int ret; + + iinfo("cmd: %d arg: %ld\n", cmd, arg); + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct gt9xx_dev_s *)inode->i_private; + + /* Get exclusive access to the driver data structure */ + + ret = nxsem_wait(&priv->devsem); + if (ret < 0) + { + ierr("ERROR: nxsem_wait failed: %d\n", ret); + return ret; + } + + /* Process the IOCTL by command */ + + switch (cmd) + { + case TSIOC_SETFREQUENCY: /* arg: Pointer to uint32_t frequency value */ + { + FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg); + DEBUGASSERT(priv->config != NULL && ptr != NULL); + priv->frequency = *ptr; + } + break; + + case TSIOC_GETFREQUENCY: /* arg: Pointer to uint32_t frequency value */ + { + FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg); + DEBUGASSERT(priv->config != NULL && ptr != NULL); + *ptr = priv->frequency; + } + break; + + default: + ret = -ENOTTY; + break; + } + + nxsem_post(&priv->devsem); + return ret; +} + +/**************************************************************************** + * Name: gt9xx_poll + ****************************************************************************/ + +static int gt9xx_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup) +{ + FAR struct inode *inode; + FAR struct gt9xx_dev_s *priv; + int ret; + int i; + + iinfo("setup: %d\n", (int)setup); + DEBUGASSERT(filep && fds); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct gt9xx_dev_s *)inode->i_private; + + /* Are we setting up the poll? Or tearing it down? */ + + ret = nxsem_wait(&priv->devsem); + if (ret < 0) + { + ierr("ERROR: nxsem_wait failed: %d\n", ret); + return ret; + } + + if (setup) + { + /* Ignore waits that do not include POLLIN */ + + if ((fds->events & POLLIN) == 0) + { + ierr("ERROR: Missing POLLIN: revents: %08x\n", fds->revents); + ret = -EDEADLK; + goto errout; + } + + /* This is a request to set up the poll. Find an available + * slot for the poll structure reference + */ + + for (i = 0; i < CONFIG_GT9XX_NPOLLWAITERS; i++) + { + /* Find an available slot */ + + if (!priv->fds[i]) + { + /* Bind the poll structure and this slot */ + + priv->fds[i] = fds; + fds->priv = &priv->fds[i]; + break; + } + } + + if (i >= CONFIG_GT9XX_NPOLLWAITERS) + { + ierr("ERROR: No available slot found: %d\n", i); + fds->priv = NULL; + ret = -EBUSY; + goto errout; + } + + /* Should we immediately notify on any of the requested events? */ + + if (priv->valid) + { + gt9xx_notify(priv); + } + } + else if (fds->priv) + { + /* This is a request to tear down the poll. */ + + struct pollfd **slot = (struct pollfd **)fds->priv; + DEBUGASSERT(slot != NULL); + + /* Remove all memory of the poll setup */ + + *slot = NULL; + fds->priv = NULL; + } + +errout: + nxsem_post(&priv->devsem); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: gt9xx_register + * + * Description: + * Configure the GT9xx to use the provided I2C device instance. This + * will register the driver as /dev/inputN where N is the minor device + * number + * + * Input Parameters: + * dev - An I2C driver instance + * config - Persistent board configuration data + * minor - The input device minor number + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int gt9xx_register(FAR struct i2c_master_s *i2c, + FAR const struct gt9xx_config_s *config, int minor) +{ + FAR struct gt9xx_dev_s *priv; + char devname[DEV_NAMELEN]; + int ret; + + iinfo("i2c: %p minor: %d\n", i2c, minor); + + /* Debug-only sanity checks */ + + DEBUGASSERT(i2c != NULL && config != NULL && minor >= 0 && minor < 100); +#ifdef CONFIG_GT9XX_POLLMODE + DEBUGASSERT(config->wakeup != NULL && config->nreset != NULL); +#else + DEBUGASSERT(config->attach != NULL && config->enable != NULL && + config->clear != NULL && config->wakeup != NULL && + config->nreset != NULL); +#endif + + /* Create and initialize a GT9xx device driver instance */ + + priv = (FAR struct gt9xx_dev_s *)kmm_zalloc(sizeof(struct gt9xx_dev_s)); + if (!priv) + { + ierr("ERROR: kmm_zalloc(%d) failed\n", sizeof(struct gt9xx_dev_s)); + return -ENOMEM; + } + + /* Initialize the GT9xx device driver instance */ + + priv->i2c = i2c; /* Save the I2C device handle */ + priv->config = config; /* Save the board configuration */ + priv->frequency = config->frequency; /* Set the current I2C frequency */ + + nxsem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */ + nxsem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */ + + /* The event wait semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + + nxsem_set_protocol(&priv->waitsem, SEM_PRIO_NONE); + +#ifdef CONFIG_GT9XX_POLLMODE + /* Allocate a timer for polling the GT9xx */ + priv->delay = POLL_MAXDELAY; +#else + /* Make sure that the GT9xx interrupt interrupt is disabled */ + + config->clear(config); + config->enable(config, false); + + /* Attach the interrupt handler */ + + ret = config->attach(config, gt9xx_data_interrupt, + priv); + if (ret < 0) + { + ierr("ERROR: Failed to attach interrupt\n"); + goto errout_with_priv; + } +#endif + + /* Register the device as an input device */ + + snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor); + iinfo("Registering %s\n", devname); + + ret = register_driver(devname, >9xx_fops, 0666, priv); + if (ret < 0) + { + ierr("ERROR: register_driver() failed: %d\n", ret); + goto errout_with_priv; + } + + /* Schedule work to perform the initial sampling and to set the data + * availability conditions. + */ + + ret = work_queue(HPWORK, &priv->work, gt9xx_data_worker, priv, 0); + if (ret < 0) + { + ierr("ERROR: Failed to queue work: %d\n", ret); + goto errout_with_priv; + } + + /* And return success */ + + return OK; + +errout_with_priv: + nxsem_destroy(&priv->devsem); + kmm_free(priv); + return ret; +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/input/gt9xx.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/input/gt9xx.h new file mode 100755 index 000000000..7a518c8c0 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/input/gt9xx.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2022 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @file gt9xx.h + * @brief API for gt9xx. + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.5.31 + */ + + +#ifndef __GT9XX_H_ +#define __GT9XX_H_ + +#define GT9XX_MAX_TOUCHES (1) +#define GT9XX_TOUCH_DATA_LEN (8 * GT9XX_MAX_TOUCHES + 4) + +#define TOUCH_POINT_GET_EVENT(t) ((t).xh >> 6) +#define TOUCH_POINT_GET_ID(t) ((t).yh >> 4) +#define TOUCH_POINT_GET_X(t) ((((t).xh & 0x0f) << 8) | (t).xl) +#define TOUCH_POINT_GET_Y(t) ((((t).yh & 0x0f) << 8) | (t).yl) + + +#define GT9XX_MAX_HEIGHT 272 +#define GT9XX_MAX_WIDTH 480 +#define GT9XX_INT_TRIGGER 0 + +#define GT9XX_ADDR_LENGTH 2 +#define GT9XX_CONFIG_MIN_LENGTH 186 +#define GT9XX_CONFIG_MAX_LENGTH 240 + +#define GT9XX_REG_BAK_REF 0x99D0 +#define GT9XX_REG_CHIP_TYPE 0x8000 +#define GT9XX_REG_MAIN_CLK 0x8020 +#define GT9XX_REG_COMMAND 0x8040 +#define GT9XX_REG_CONFIG_DATA 0x8047 +#define GT9XX_REG_CONFIG_CHKSUM 0x80FF +#define GT9XX_REG_VERSION 0x8140 +#define GT9XX_REG_SENSOR_ID 0x814A +#define GT9XX_REG_READ_COOR 0x814E + +#define GT9XX_COMMAND_READSTATUS 0 +#define GT9XX_COMMAND_DIFFERENCE 1 +#define GT9XX_COMMAND_SOFTRESET 2 +#define GT9XX_COMMAND_UPDATE 3 +#define GT9XX_COMMAND_CALCULATE 4 +#define GT9XX_COMMAND_TURNOFF 5 + +enum touch_event_e +{ + GT9XX_DOWN = 0, /* The state changed to touched */ + GT9XX_UP = 1, /* The state changed to not touched */ + GT9XX_CONTACT = 2, /* There is a continuous touch being detected */ + GT9XX_INVALID = 3 /* No touch information available */ +}; + +/* Describes on touchpoint returned by the GT9xx */ + +struct gt9xx_touch_point_s +{ + uint8_t xh; + uint8_t xl; + uint8_t yh; + uint8_t yl; + uint8_t weight; + uint8_t area; +}; + +/* Describes all touch data returned by the GT9xx */ + +struct gt9xx_touch_data_s +{ + uint8_t tdstatus; /* Touch status */ + struct gt9xx_touch_point_s touch[GT9XX_MAX_TOUCHES]; +}; + +/* Maximum number of threads than can be waiting for POLL events */ + +#ifndef CONFIG_GT9XX_NPOLLWAITERS +# define CONFIG_GT9XX_NPOLLWAITERS 2 +#endif + +struct gt9xx_config_s +{ + uint8_t address; /* 7-bit I2C address (only bits 0-6 used) */ + uint32_t frequency; /* Default I2C frequency */ + +#ifndef CONFIG_GT9XX_POLLMODE + int (*attach)(FAR const struct gt9xx_config_s *config, xcpt_t isr, + FAR void *arg); + void (*enable)(FAR const struct gt9xx_config_s *config, bool enable); + void (*clear)(FAR const struct gt9xx_config_s *config); +#endif + void (*wakeup)(FAR const struct gt9xx_config_s *config); + void (*nreset)(FAR const struct gt9xx_config_s *config, + bool state); +}; + +int gt9xx_register(FAR struct i2c_master_s *i2c, + FAR const struct gt9xx_config_s *config, int minor); + + +#endif /* __GT9XX_H__ */ diff --git a/Ubiquitous/XiZi/arch/arm/cortex-m7/interrupt.c b/Ubiquitous/XiZi/arch/arm/cortex-m7/interrupt.c index db1f45812..f37418b90 100644 --- a/Ubiquitous/XiZi/arch/arm/cortex-m7/interrupt.c +++ b/Ubiquitous/XiZi/arch/arm/cortex-m7/interrupt.c @@ -20,7 +20,7 @@ #include #include - +#include "fsl_common.h" x_base __attribute__((naked)) DisableLocalInterrupt() { @@ -37,11 +37,13 @@ void __attribute__((naked)) EnableLocalInterrupt(x_base level) int32 ArchEnableHwIrq(uint32 irq_num) { + EnableIRQ(irq_num); return EOK; } int32 ArchDisableHwIrq(uint32 irq_num) { + DisableIRQ(irq_num); return EOK; } diff --git a/Ubiquitous/XiZi/board/xidatong/board.c b/Ubiquitous/XiZi/board/xidatong/board.c index 9ea490b0c..014925cd8 100644 --- a/Ubiquitous/XiZi/board/xidatong/board.c +++ b/Ubiquitous/XiZi/board/xidatong/board.c @@ -44,6 +44,10 @@ Modification: #include #endif +#ifdef BSP_USING_I2C +#include +#endif + #ifdef BSP_USING_CH438 #include #endif @@ -67,6 +71,14 @@ extern int ExtSramInit(void); extern int ETH_BSP_Config(); #endif +#ifdef BSP_USING_LCD +extern int Imxrt1052HwLcdInit(void); +#endif + +#ifdef BSP_USING_TOUCH +extern int HwTouchInit(); +#endif + void BOARD_SD_Pin_Config(uint32_t speed, uint32_t strength) { IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, @@ -277,27 +289,56 @@ void SysTick_Handler(int irqn, void *arg) } DECLARE_HW_IRQ(SYSTICK_IRQN, SysTick_Handler, NONE); +struct InitSequenceDesc _board_init[] = +{ +#ifdef BSP_USING_GPIO + { "hw_pin", Imxrt1052HwGpioInit }, +#endif + +#ifdef BSP_USING_CH438 + {"ch438", Imxrt1052HwCh438Init()}, +#endif + +#ifdef BSP_USING_SDIO + { "sdio", Imxrt1052HwSdioInit }, +#endif + +#ifdef BSP_USING_I2C + { "hw_i2c", Imxrt1052HwI2cInit }, +#endif + +#ifdef BSP_USING_LCD + { "hw_lcd", Imxrt1052HwLcdInit }, +#endif + +#ifdef BSP_USING_TOUCH + {"touch", HwTouchInit }, +#endif + +#ifdef BSP_USING_LWIP + {"ETH_BSP", ETH_BSP_Config}, +#endif + +#ifdef BSP_USING_WDT + { "hw_wdt", Imxrt1052HwWdgInit }, +#endif + { " NONE ",NONE }, +}; + /** * This function will initial imxrt1050 board. */ void InitBoardHardware() { + int i = 0; + int ret = 0; + BOARD_ConfigMPU(); BOARD_InitPins(); BOARD_BootClockRUN(); -#ifndef BSP_USING_LWIP NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); SysTick_Config(SystemCoreClock / TICK_PER_SECOND); -#endif - -#ifdef BSP_USING_GPIO - Imxrt1052HwGpioInit(); -#endif - -#ifdef BSP_USING_LPUART - BOARD_InitUartPins(); -#endif InitBoardMemory((void *)HEAP_BEGIN, (void *)HEAP_END); @@ -317,26 +358,19 @@ void InitBoardHardware() #endif #endif -#ifdef BSP_USING_LWIP - ETH_BSP_Config(); -#endif - #ifdef BSP_USING_LPUART Imxrt1052HwUartInit(); #endif InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); + KPrintf("\nconsole init completed.\n"); + KPrintf("board initialization......\n"); -#ifdef BSP_USING_CH438 - Imxrt1052HwCh438Init(); -#endif - -#ifdef BSP_USING_SDIO - Imxrt1052HwSdioInit(); -#endif - -#ifdef BSP_USING_WDT - Imxrt1052HwWdgInit(); -#endif + for(i = 0; _board_init[i].fn != NONE; i++) { + ret = _board_init[i].fn(); + KPrintf("initialize %s %s\n",_board_init[i].fn_name, ret == 0 ? "success" : "failed"); + } + KPrintf("board init done.\n"); + KPrintf("start kernel...\n"); } diff --git a/Ubiquitous/XiZi/board/xidatong/link.lds b/Ubiquitous/XiZi/board/xidatong/link.lds index 38d111b23..d9db1e140 100644 --- a/Ubiquitous/XiZi/board/xidatong/link.lds +++ b/Ubiquitous/XiZi/board/xidatong/link.lds @@ -61,6 +61,9 @@ MEMORY m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x03FFDC00 m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000 m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00060000 + + m_sdram (RW) : ORIGIN = 0x80000000, LENGTH = 0x01E00000 + m_nocache (RW) : ORIGIN = 0x81E00000, LENGTH = 0x00200000 } /* Define output sections */ @@ -217,14 +220,14 @@ SECTIONS *(NonCacheable.init) . = ALIGN(4); __noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */ - } > m_data + } > m_nocache . = __noncachedata_init_end__; .ncache : { *(NonCacheable) . = ALIGN(4); __noncachedata_end__ = .; /* define a global symbol at ncache data end */ - } > m_data + } > m_nocache __DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__); text_end = ORIGIN(m_text) + LENGTH(m_text); diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/Kconfig b/Ubiquitous/XiZi/board/xidatong/third_party_driver/Kconfig index a21740ed2..223f5e966 100644 --- a/Ubiquitous/XiZi/board/xidatong/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/Kconfig @@ -20,6 +20,15 @@ menuconfig BSP_USING_GPIO if BSP_USING_GPIO source "$BSP_DIR/third_party_driver/gpio/Kconfig" endif + +menuconfig BSP_USING_I2C + bool "Using I2C device" + default n + select RESOURCES_I2C + + if BSP_USING_I2C + source "$BSP_DIR/third_party_driver/i2c/Kconfig" + endif menuconfig BSP_USING_LWIP bool "Using LwIP device" @@ -40,6 +49,22 @@ menuconfig BSP_USING_SDIO if BSP_USING_SDIO source "$BSP_DIR/third_party_driver/sdio/Kconfig" endif +menuconfig BSP_USING_LCD + bool "Using LCD device" + default n + select RESOURCES_LCD + if BSP_USING_LCD + source "$BSP_DIR/third_party_driver/lcd/Kconfig" + endif +menuconfig BSP_USING_TOUCH + bool "Using TOUCH device" + default n + select RESOURCES_TOUCH + select BSP_USING_I2C + select BSP_USING_LCD + if BSP_USING_TOUCH + source "$BSP_DIR/third_party_driver/touch/Kconfig" + endif menuconfig BSP_USING_USB bool "Using USB device" diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/Makefile b/Ubiquitous/XiZi/board/xidatong/third_party_driver/Makefile index 66f6f6bbf..e7c289a05 100644 --- a/Ubiquitous/XiZi/board/xidatong/third_party_driver/Makefile +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/Makefile @@ -7,6 +7,9 @@ endif ifeq ($(CONFIG_BSP_USING_SEMC),y) SRC_DIR += semc endif +ifeq ($(CONFIG_BSP_USING_I2C),y) + SRC_DIR += i2c +endif ifeq ($(CONFIG_BSP_USING_LPUART),y) SRC_DIR += uart @@ -24,6 +27,14 @@ ifeq ($(CONFIG_BSP_USING_USB),y) SRC_DIR += usb endif +ifeq ($(CONFIG_BSP_USING_LCD),y) + SRC_DIR += lcd +endif + +ifeq ($(CONFIG_BSP_USING_TOUCH),y) + SRC_DIR += touch +endif + ifeq ($(CONFIG_BSP_USING_WDT),y) SRC_DIR += wdt endif diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/common/pin_mux.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/common/pin_mux.c index be6b733b1..84576605f 100755 --- a/Ubiquitous/XiZi/board/xidatong/third_party_driver/common/pin_mux.c +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/common/pin_mux.c @@ -742,6 +742,359 @@ BOARD_InitPins: pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_4, slew_rate: Fast} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ +void Lcd_InitPins(void) +{ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_00_LCD_CLK, /* GPIO_B0_00 is configured as LCD_CLK */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_01_LCD_ENABLE, /* GPIO_B0_01 is configured as LCD_ENABLE */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_02_LCD_HSYNC, /* GPIO_B0_02 is configured as LCD_HSYNC */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_03_LCD_VSYNC, /* GPIO_B0_03 is configured as LCD_VSYNC */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_04_LCD_DATA00, /* GPIO_B0_04 is configured as LCD_DATA00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_05_LCD_DATA01, /* GPIO_B0_05 is configured as LCD_DATA01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_06_LCD_DATA02, /* GPIO_B0_06 is configured as LCD_DATA02 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_07_LCD_DATA03, /* GPIO_B0_07 is configured as LCD_DATA03 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_08_LCD_DATA04, /* GPIO_B0_08 is configured as LCD_DATA04 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_09_LCD_DATA05, /* GPIO_B0_09 is configured as LCD_DATA05 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_10_LCD_DATA06, /* GPIO_B0_10 is configured as LCD_DATA06 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_11_LCD_DATA07, /* GPIO_B0_11 is configured as LCD_DATA07 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_12_LCD_DATA08, /* GPIO_B0_12 is configured as LCD_DATA08 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_13_LCD_DATA09, /* GPIO_B0_13 is configured as LCD_DATA09 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_14_LCD_DATA10, /* GPIO_B0_14 is configured as LCD_DATA10 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_15_LCD_DATA11, /* GPIO_B0_15 is configured as LCD_DATA11 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_00_LCD_DATA12, /* GPIO_B1_00 is configured as LCD_DATA12 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_01_LCD_DATA13, /* GPIO_B1_01 is configured as LCD_DATA13 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_02_LCD_DATA14, /* GPIO_B1_02 is configured as LCD_DATA14 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_03_LCD_DATA15, /* GPIO_B1_03 is configured as LCD_DATA15 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_15_GPIO2_IO31, /* GPIO_B1_15 is configured as GPIO2_IO31 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_00_LCD_CLK, /* GPIO_B0_00 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_01_LCD_ENABLE, /* GPIO_B0_01 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_02_LCD_HSYNC, /* GPIO_B0_02 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_03_LCD_VSYNC, /* GPIO_B0_03 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_04_LCD_DATA00, /* GPIO_B0_04 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_05_LCD_DATA01, /* GPIO_B0_05 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_06_LCD_DATA02, /* GPIO_B0_06 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_07_LCD_DATA03, /* GPIO_B0_07 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_08_LCD_DATA04, /* GPIO_B0_08 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_09_LCD_DATA05, /* GPIO_B0_09 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_10_LCD_DATA06, /* GPIO_B0_10 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_11_LCD_DATA07, /* GPIO_B0_11 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_12_LCD_DATA08, /* GPIO_B0_12 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_13_LCD_DATA09, /* GPIO_B0_13 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_14_LCD_DATA10, /* GPIO_B0_14 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_15_LCD_DATA11, /* GPIO_B0_15 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_00_LCD_DATA12, /* GPIO_B1_00 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_01_LCD_DATA13, /* GPIO_B1_01 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_02_LCD_DATA14, /* GPIO_B1_02 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_03_LCD_DATA15, /* GPIO_B1_03 PAD functional properties : */ + 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Pull + Pull Up / Down Config. Field: 100K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_15_GPIO2_IO31, /* GPIO_B1_15 PAD functional properties : */ + 0x10B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Disabled */ +} + +void BOARD_InitI2C1Pins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */ + + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, /* GPIO_AD_B1_00 is configured as LPI2C1_SCL */ + 1U); /* Software Input On Field: Force input path of pad GPIO_AD_B1_00 */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, /* GPIO_AD_B1_01 is configured as LPI2C1_SDA */ + 1U); /* Software Input On Field: Force input path of pad GPIO_AD_B1_01 */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, /* GPIO_AD_B1_00 PAD functional properties : */ + 0xD8B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Enabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 22K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, /* GPIO_AD_B1_01 PAD functional properties : */ + 0xD8B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Enabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 22K Ohm Pull Up + Hyst. Enable Field: Hysteresis Disabled */ +} + +void BOARD_InitUartPins(void) +{ +#ifdef BSP_USING_LPUART1 + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 is configured as LPUART1_TX */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 is configured as LPUART1_RX */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 PAD functional properties : */ + 0x10B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Disabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 PAD functional properties : */ + 0x10B0u); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: R0/6 + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Enabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 100K Ohm Pull Down + Hyst. Enable Field: Hysteresis Disabled */ +#endif +#ifdef BSP_USING_LPUART2 + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B1_02_LPUART2_TX, + 0U); + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B1_03_LPUART2_RX, + 0U); + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B1_02_LPUART2_TX, + 0x10B0u); + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B1_03_LPUART2_RX, + 0x10B0u); +#endif +} /* FUNCTION ************************************************************************************************************ * @@ -749,11 +1102,24 @@ BOARD_InitPins: * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ -void BOARD_InitPins(void) { +void BOARD_InitPins(void) +{ CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */ /* Software Input On Field: Input Path is determined by functionality */ SemcPinmuxConfig(); +#ifdef BSP_USING_LPUART + BOARD_InitUartPins(); +#endif + +#ifdef BSP_USING_LCD + Lcd_InitPins(); +#endif + +#ifdef BSP_USING_I2C + BOARD_InitI2C1Pins(); +#endif + IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_03_GPIO1_IO03, /* GPIO_AD_B0_09 is configured as GPIO1_IO09 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/ethernet/enet_ethernetif.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/ethernet/enet_ethernetif.c index d04c8adb3..6360d9911 100755 --- a/Ubiquitous/XiZi/board/xidatong/third_party_driver/ethernet/enet_ethernetif.c +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/ethernet/enet_ethernetif.c @@ -99,7 +99,6 @@ void ethernetif_clk_init(void) { const clock_enet_pll_config_t config = {.enableClkOutput = true, .enableClkOutput25M = false, .loopDivider = 1}; CLOCK_InitEnetPll(&config); - SysTick_Config(USEC_TO_COUNT(1000U, CLOCK_GetFreq(kCLOCK_CoreSysClk))); } void ethernetif_gpio_init(void) diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/Kconfig b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/Kconfig new file mode 100755 index 000000000..ddc59900d --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/Kconfig @@ -0,0 +1,12 @@ +if BSP_USING_I2C + config I2C_BUS_NAME_1 + string "i2c bus 1 name" + default "i2c1" + config I2C_DRV_NAME_1 + string "i2c bus 1 driver name" + default "i2c1_drv" + config I2C_1_DEVICE_NAME_0 + string "i2c bus 1 device 0 name" + default "i2c1_dev0" +endif + diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/Makefile b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/Makefile new file mode 100755 index 000000000..e99bb9e03 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_i2c.c hardware_i2c.c fsl_lpi2c.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/connect_i2c.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/connect_i2c.c new file mode 100755 index 000000000..85d6672fc --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/connect_i2c.c @@ -0,0 +1,179 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_i2c.c +* @brief support ok1052-c board i2c function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-03-01 +*/ + +#include +#include "bus_serial.h" +#include "connect_i2c.h" +#include "fsl_lpi2c.h" + +static uint32 I2cWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) +{ + status_t ret; + Stm32I2cType *param = (Stm32I2cType *)i2c_dev->haldev.private_data; + ret = I2cHardwareWrite(param->base, param->slave_addr, param->sub_addr, msg->buf, msg->len); + if(kStatus_Success == ret) + return 1; + return 0; +} + +static uint32 I2cReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) +{ + status_t ret; + Stm32I2cType *param = (Stm32I2cType *)i2c_dev->haldev.private_data; + ret = I2cHardwareRead(param->base, i2c_dev->i2c_dev_addr, param->sub_addr, msg->buf, msg->len); + if(kStatus_Success == ret) + return 1; + return 0; +} + +static uint32 I2cInit(struct I2cDriver *i2c_drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(i2c_drv); + + struct I2cHardwareDevice *i2c_dev = (struct I2cHardwareDevice *)i2c_drv->driver.owner_bus->owner_haldev; + + if (configure_info->private_data) { + i2c_dev->i2c_dev_addr = *((uint16 *)configure_info->private_data); + return EOK; + } + + i2c_print("I2cInit need set i2c dev addr\n"); + return ERROR; +} + +static uint32 I2cDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct I2cDriver *i2c_drv = (struct I2cDriver *)drv; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + ret = I2cInit(i2c_drv, configure_info); + break; + default: + break; + } + + return ret; +} + +/*manage the i2c device operations*/ +static const struct I2cDevDone i2c_dev_done = +{ + .dev_open = NONE, + .dev_close = NONE, + .dev_write = I2cWriteData, + .dev_read = I2cReadData, +}; + +/*Init i2c bus*/ +static int BoardI2cBusInit(struct I2cBus *i2c_bus, struct I2cDriver *i2c_driver) +{ + x_err_t ret = EOK; + + /*Init the i2c bus */ + i2c_bus->private_data = (void *)NULL; + ret = I2cBusInit(i2c_bus, I2C_BUS_NAME_1); + if (EOK != ret) { + i2c_print("BoardI2cBusInit I2cBusInit error %d\n", ret); + return ERROR; + } + + /*Init the i2c driver*/ + i2c_driver->private_data = (void *)NULL; + ret = I2cDriverInit(i2c_driver, I2C_DRV_NAME_1); + if (EOK != ret) { + i2c_print("BoardI2cBusInit I2cDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the i2c driver to the i2c bus*/ + ret = I2cDriverAttachToBus(I2C_DRV_NAME_1, I2C_BUS_NAME_1); + if (EOK != ret) { + i2c_print("BoardI2cBusInit I2cDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the i2c device to the i2c bus*/ +static int BoardI2cDevBend(void) +{ + x_err_t ret = EOK; + static struct I2cHardwareDevice i2c_device0; + memset(&i2c_device0, 0, sizeof(struct I2cHardwareDevice)); + + i2c_device0.i2c_dev_done = &i2c_dev_done; + + ret = I2cDeviceRegister(&i2c_device0, NONE, I2C_1_DEVICE_NAME_0); + if (EOK != ret) { + i2c_print("BoardI2cDevBend I2cDeviceInit device %s error %d\n", I2C_1_DEVICE_NAME_0, ret); + return ERROR; + } + + ret = I2cDeviceAttachToBus(I2C_1_DEVICE_NAME_0, I2C_BUS_NAME_1); + if (EOK != ret) { + i2c_print("BoardI2cDevBend I2cDeviceAttachToBus device %s error %d\n", I2C_1_DEVICE_NAME_0, ret); + return ERROR; + } + + return ret; +} + +/*BOARD I2C INIT*/ +int Imxrt1052HwI2cInit(void) +{ + static int init_flag = 0; + x_err_t ret = EOK; + + if(init_flag) + { + return ret; + } + init_flag = 1; + + static struct I2cBus i2c_bus; + memset(&i2c_bus, 0, sizeof(struct I2cBus)); + static struct I2cDriver i2c_driver; + memset(&i2c_driver, 0, sizeof(struct I2cDriver)); + +#ifdef BSP_USING_I2C + i2c_driver.configure = I2cDrvConfigure; + + ret = BoardI2cBusInit(&i2c_bus, &i2c_driver); + if (EOK != ret) { + i2c_print("board_i2c_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardI2cDevBend(); + if (EOK != ret) { + i2c_print("board_i2c_Init error ret %u\n", ret); + return ERROR; + } +#endif + + return ret; +} diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/connect_i2c_eeprom.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/connect_i2c_eeprom.c new file mode 100755 index 000000000..792a19273 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/connect_i2c_eeprom.c @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_i2c_eeprom.h +* @brief ok1052-c board eeprom relative codes +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-03-01 +*/ + +#include "board.h" +#include "connect_i2c.h" +#include "fsl_lpi2c.h" +#include "pin_mux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define I2C_EEPROM_BASE LPI2C1 +#define I2C_EEPROM_ADDR (0xA0 >> 1) + +/******************************************************************************* + * Code + ******************************************************************************/ + +void I2cEEpromTestWrite(void) +{ + uint8_t dat[8] = {0}; + + if(I2cHardwareRead(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success) + { + i2c_print("Read from EEPROM %d %d %d %d %d %d %d %d\r\n", + dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]); + } + + for(uint8_t i = 0; i < 8; i++) + { + dat[i] ++; + } + + if(I2cHardwareWrite(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success) + { + i2c_print("Write to EEPROM %d %d %d %d %d %d %d %d\r\n", + dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]); + } + + memset(dat, 0, 8); + if(I2cHardwareRead(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success) + { + i2c_print("Read from EEPROM %d %d %d %d %d %d %d %d\r\n", + dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]); + } +} + +int I2cEEpromTest(void) +{ + BOARD_InitI2C1Pins(); + I2cHardwareInit(); + I2cEEpromTestWrite(); + return 0; +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)| SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)| SHELL_CMD_PARAM_NUM(0), + eeprom, I2cEEpromTest, test i2c eeprom); + diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/fsl_lpi2c.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/fsl_lpi2c.c new file mode 100755 index 000000000..cf55ec5d5 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/fsl_lpi2c.c @@ -0,0 +1,2249 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_lpi2c.h" +#include +#include +#include + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.lpi2c" +#endif + +/*! @brief Common sets of flags used by the driver. */ +enum _lpi2c_flag_constants +{ + /*! All flags which are cleared by the driver upon starting a transfer. */ + kMasterClearFlags = kLPI2C_MasterEndOfPacketFlag | kLPI2C_MasterStopDetectFlag | kLPI2C_MasterNackDetectFlag | + kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterFifoErrFlag | kLPI2C_MasterPinLowTimeoutFlag | + kLPI2C_MasterDataMatchFlag, + + /*! IRQ sources enabled by the non-blocking transactional API. */ + kMasterIrqFlags = kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterTxReadyFlag | kLPI2C_MasterRxReadyFlag | + kLPI2C_MasterStopDetectFlag | kLPI2C_MasterNackDetectFlag | kLPI2C_MasterPinLowTimeoutFlag | + kLPI2C_MasterFifoErrFlag, + + /*! Errors to check for. */ + kMasterErrorFlags = kLPI2C_MasterNackDetectFlag | kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterFifoErrFlag | + kLPI2C_MasterPinLowTimeoutFlag, + + /*! All flags which are cleared by the driver upon starting a transfer. */ + kSlaveClearFlags = kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveBitErrFlag | + kLPI2C_SlaveFifoErrFlag, + + /*! IRQ sources enabled by the non-blocking transactional API. */ + kSlaveIrqFlags = kLPI2C_SlaveTxReadyFlag | kLPI2C_SlaveRxReadyFlag | kLPI2C_SlaveStopDetectFlag | + kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveFifoErrFlag | kLPI2C_SlaveBitErrFlag | + kLPI2C_SlaveTransmitAckFlag | kLPI2C_SlaveAddressValidFlag, + + /*! Errors to check for. */ + kSlaveErrorFlags = kLPI2C_SlaveFifoErrFlag | kLPI2C_SlaveBitErrFlag, +}; + +/* ! @brief LPI2C master fifo commands. */ +enum _lpi2c_master_fifo_cmd +{ + kTxDataCmd = LPI2C_MTDR_CMD(0x0U), /*!< Transmit DATA[7:0] */ + kRxDataCmd = LPI2C_MTDR_CMD(0X1U), /*!< Receive (DATA[7:0] + 1) bytes */ + kStopCmd = LPI2C_MTDR_CMD(0x2U), /*!< Generate STOP condition */ + kStartCmd = LPI2C_MTDR_CMD(0x4U), /*!< Generate(repeated) START and transmit address in DATA[[7:0] */ +}; + +/*! + * @brief Default watermark values. + * + * The default watermarks are set to zero. + */ +enum _lpi2c_default_watermarks +{ + kDefaultTxWatermark = 0, + kDefaultRxWatermark = 0, +}; + +/*! @brief States for the state machine used by transactional APIs. */ +enum _lpi2c_transfer_states +{ + kIdleState = 0, + kSendCommandState, + kIssueReadCommandState, + kTransferDataState, + kStopState, + kWaitForCompletionState, +}; + +/*! @brief Typedef for master interrupt handler. */ +typedef void (*lpi2c_master_isr_t)(LPI2C_Type *base, lpi2c_master_handle_t *handle); + +/*! @brief Typedef for slave interrupt handler. */ +typedef void (*lpi2c_slave_isr_t)(LPI2C_Type *base, lpi2c_slave_handle_t *handle); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/* Not static so it can be used from fsl_lpi2c_edma.c. */ +uint32_t LPI2C_GetInstance(LPI2C_Type *base); + +static uint32_t LPI2C_GetCyclesForWidth(uint32_t sourceClock_Hz, + uint32_t width_ns, + uint32_t maxCycles, + uint32_t prescaler); + +static status_t LPI2C_MasterWaitForTxReady(LPI2C_Type *base); + +static status_t LPI2C_RunTransferStateMachine(LPI2C_Type *base, lpi2c_master_handle_t *handle, bool *isDone); + +static void LPI2C_InitTransferStateMachine(lpi2c_master_handle_t *handle); + +static status_t LPI2C_SlaveCheckAndClearError(LPI2C_Type *base, uint32_t flags); + +static void LPI2C_CommonIRQHandler(LPI2C_Type *base, uint32_t instance); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Array to map LPI2C instance number to base pointer. */ +static LPI2C_Type *const kLpi2cBases[] = LPI2C_BASE_PTRS; + +/*! @brief Array to map LPI2C instance number to IRQ number. */ +static IRQn_Type const kLpi2cIrqs[] = LPI2C_IRQS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Array to map LPI2C instance number to clock gate enum. */ +static clock_ip_name_t const kLpi2cClocks[] = LPI2C_CLOCKS; + +#if defined(LPI2C_PERIPH_CLOCKS) +/*! @brief Array to map LPI2C instance number to pheripheral clock gate enum. */ +static const clock_ip_name_t kLpi2cPeriphClocks[] = LPI2C_PERIPH_CLOCKS; +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Pointer to master IRQ handler for each instance. */ +static lpi2c_master_isr_t s_lpi2cMasterIsr; + +/*! @brief Pointers to master handles for each instance. */ +static lpi2c_master_handle_t *s_lpi2cMasterHandle[ARRAY_SIZE(kLpi2cBases)]; + +/*! @brief Pointer to slave IRQ handler for each instance. */ +static lpi2c_slave_isr_t s_lpi2cSlaveIsr; + +/*! @brief Pointers to slave handles for each instance. */ +static lpi2c_slave_handle_t *s_lpi2cSlaveHandle[ARRAY_SIZE(kLpi2cBases)]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Returns an instance number given a base address. + * + * If an invalid base address is passed, debug builds will assert. Release builds will just return + * instance number 0. + * + * @param base The LPI2C peripheral base address. + * @return LPI2C instance number starting from 0. + */ +uint32_t LPI2C_GetInstance(LPI2C_Type *base) +{ + uint32_t instance; + for (instance = 0; instance < ARRAY_SIZE(kLpi2cBases); ++instance) + { + if (kLpi2cBases[instance] == base) + { + return instance; + } + } + + assert(false); + return 0; +} + +/*! + * @brief Computes a cycle count for a given time in nanoseconds. + * @param sourceClock_Hz LPI2C functional clock frequency in Hertz. + * @param width_ns Desired with in nanoseconds. + * @param maxCycles Maximum cycle count, determined by the number of bits wide the cycle count field is. + * @param prescaler LPI2C prescaler setting. Pass 1 if the prescaler should not be used, as for slave glitch widths. + */ +static uint32_t LPI2C_GetCyclesForWidth(uint32_t sourceClock_Hz, + uint32_t width_ns, + uint32_t maxCycles, + uint32_t prescaler) +{ + assert(sourceClock_Hz > 0); + assert(prescaler > 0); + + uint32_t busCycle_ns = 1000000 / (sourceClock_Hz / prescaler / 1000); + uint32_t cycles = 0; + + /* Search for the cycle count just below the desired glitch width. */ + while ((((cycles + 1) * busCycle_ns) < width_ns) && (cycles + 1 < maxCycles)) + { + ++cycles; + } + + /* If we end up with zero cycles, then set the filter to a single cycle unless the */ + /* bus clock is greater than 10x the desired glitch width. */ + if ((cycles == 0) && (busCycle_ns <= (width_ns * 10))) + { + cycles = 1; + } + + return cycles; +} + +/*! + * @brief Convert provided flags to status code, and clear any errors if present. + * @param base The LPI2C peripheral base address. + * @param status Current status flags value that will be checked. + * @retval #kStatus_Success + * @retval #kStatus_LPI2C_PinLowTimeout + * @retval #kStatus_LPI2C_ArbitrationLost + * @retval #kStatus_LPI2C_Nak + * @retval #kStatus_LPI2C_FifoError + */ +/* Not static so it can be used from fsl_lpi2c_edma.c. */ +status_t LPI2C_MasterCheckAndClearError(LPI2C_Type *base, uint32_t status) +{ + status_t result = kStatus_Success; + + /* Check for error. These errors cause a stop to automatically be sent. We must */ + /* clear the errors before a new transfer can start. */ + status &= kMasterErrorFlags; + if (status) + { + /* Select the correct error code. Ordered by severity, with bus issues first. */ + if (status & kLPI2C_MasterPinLowTimeoutFlag) + { + result = kStatus_LPI2C_PinLowTimeout; + } + else if (status & kLPI2C_MasterArbitrationLostFlag) + { + result = kStatus_LPI2C_ArbitrationLost; + } + else if (status & kLPI2C_MasterNackDetectFlag) + { + result = kStatus_LPI2C_Nak; + } + else if (status & kLPI2C_MasterFifoErrFlag) + { + result = kStatus_LPI2C_FifoError; + } + else + { + assert(false); + } + + /* Clear the flags. */ + LPI2C_MasterClearStatusFlags(base, status); + + /* Reset fifos. These flags clear automatically. */ + base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK; + } + + return result; +} + +/*! + * @brief Wait until there is room in the tx fifo. + * @param base The LPI2C peripheral base address. + * @retval #kStatus_Success + * @retval #kStatus_LPI2C_PinLowTimeout + * @retval #kStatus_LPI2C_ArbitrationLost + * @retval #kStatus_LPI2C_Nak + * @retval #kStatus_LPI2C_FifoError + */ +static status_t LPI2C_MasterWaitForTxReady(LPI2C_Type *base) +{ + uint32_t status; + size_t txCount; + size_t txFifoSize = FSL_FEATURE_LPI2C_FIFO_SIZEn(base); + +#if LPI2C_WAIT_TIMEOUT + uint32_t waitTimes = LPI2C_WAIT_TIMEOUT; +#endif + do + { + status_t result; + + /* Get the number of words in the tx fifo and compute empty slots. */ + LPI2C_MasterGetFifoCounts(base, NULL, &txCount); + txCount = txFifoSize - txCount; + + /* Check for error flags. */ + status = LPI2C_MasterGetStatusFlags(base); + result = LPI2C_MasterCheckAndClearError(base, status); + if (result) + { + return result; + } +#if LPI2C_WAIT_TIMEOUT + } while ((!txCount) && (--waitTimes)); + + if (waitTimes == 0) + { + return kStatus_LPI2C_Timeout; + } +#else + } while (!txCount); +#endif + + return kStatus_Success; +} + +/*! + * @brief Make sure the bus isn't already busy. + * + * A busy bus is allowed if we are the one driving it. + * + * @param base The LPI2C peripheral base address. + * @retval #kStatus_Success + * @retval #kStatus_LPI2C_Busy + */ +/* Not static so it can be used from fsl_lpi2c_edma.c. */ +status_t LPI2C_CheckForBusyBus(LPI2C_Type *base) +{ + uint32_t status = LPI2C_MasterGetStatusFlags(base); + if ((status & kLPI2C_MasterBusBusyFlag) && (!(status & kLPI2C_MasterBusyFlag))) + { + return kStatus_LPI2C_Busy; + } + + return kStatus_Success; +} + +/*! + * brief Provides a default configuration for the LPI2C master peripheral. + * + * This function provides the following default configuration for the LPI2C master peripheral: + * code + * masterConfig->enableMaster = true; + * masterConfig->debugEnable = false; + * masterConfig->ignoreAck = false; + * masterConfig->pinConfig = kLPI2C_2PinOpenDrain; + * masterConfig->baudRate_Hz = 100000U; + * masterConfig->busIdleTimeout_ns = 0; + * masterConfig->pinLowTimeout_ns = 0; + * masterConfig->sdaGlitchFilterWidth_ns = 0; + * masterConfig->sclGlitchFilterWidth_ns = 0; + * masterConfig->hostRequest.enable = false; + * masterConfig->hostRequest.source = kLPI2C_HostRequestExternalPin; + * masterConfig->hostRequest.polarity = kLPI2C_HostRequestPinActiveHigh; + * endcode + * + * After calling this function, you can override any settings in order to customize the configuration, + * prior to initializing the master driver with LPI2C_MasterInit(). + * + * param[out] masterConfig User provided configuration structure for default values. Refer to #lpi2c_master_config_t. + */ +void LPI2C_MasterGetDefaultConfig(lpi2c_master_config_t *masterConfig) +{ + /* Initializes the configure structure to zero. */ + memset(masterConfig, 0, sizeof(*masterConfig)); + + masterConfig->enableMaster = true; + masterConfig->debugEnable = false; + masterConfig->enableDoze = true; + masterConfig->ignoreAck = false; + masterConfig->pinConfig = kLPI2C_2PinOpenDrain; + masterConfig->baudRate_Hz = 100000U; + masterConfig->busIdleTimeout_ns = 0; + masterConfig->pinLowTimeout_ns = 0; + masterConfig->sdaGlitchFilterWidth_ns = 0; + masterConfig->sclGlitchFilterWidth_ns = 0; + masterConfig->hostRequest.enable = false; + masterConfig->hostRequest.source = kLPI2C_HostRequestExternalPin; + masterConfig->hostRequest.polarity = kLPI2C_HostRequestPinActiveHigh; +} + +/*! + * brief Initializes the LPI2C master peripheral. + * + * This function enables the peripheral clock and initializes the LPI2C master peripheral as described by the user + * provided configuration. A software reset is performed prior to configuration. + * + * param base The LPI2C peripheral base address. + * param masterConfig User provided peripheral configuration. Use LPI2C_MasterGetDefaultConfig() to get a set of + * defaults + * that you can override. + * param sourceClock_Hz Frequency in Hertz of the LPI2C functional clock. Used to calculate the baud rate divisors, + * filter widths, and timeout periods. + */ +void LPI2C_MasterInit(LPI2C_Type *base, const lpi2c_master_config_t *masterConfig, uint32_t sourceClock_Hz) +{ + uint32_t prescaler; + uint32_t cycles; + uint32_t cfgr2; + uint32_t value; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + + uint32_t instance = LPI2C_GetInstance(base); + + /* Ungate the clock. */ + CLOCK_EnableClock(kLpi2cClocks[instance]); +#if defined(LPI2C_PERIPH_CLOCKS) + /* Ungate the functional clock in initialize function. */ + CLOCK_EnableClock(kLpi2cPeriphClocks[instance]); +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset peripheral before configuring it. */ + LPI2C_MasterReset(base); + + /* Doze bit: 0 is enable, 1 is disable */ + base->MCR = LPI2C_MCR_DBGEN(masterConfig->debugEnable) | LPI2C_MCR_DOZEN(!(masterConfig->enableDoze)); + + /* host request */ + value = base->MCFGR0; + value &= (~(LPI2C_MCFGR0_HREN_MASK | LPI2C_MCFGR0_HRPOL_MASK | LPI2C_MCFGR0_HRSEL_MASK)); + value |= LPI2C_MCFGR0_HREN(masterConfig->hostRequest.enable) | + LPI2C_MCFGR0_HRPOL(masterConfig->hostRequest.polarity) | + LPI2C_MCFGR0_HRSEL(masterConfig->hostRequest.source); + base->MCFGR0 = value; + + /* pin config and ignore ack */ + value = base->MCFGR1; + value &= ~(LPI2C_MCFGR1_PINCFG_MASK | LPI2C_MCFGR1_IGNACK_MASK); + value |= LPI2C_MCFGR1_PINCFG(masterConfig->pinConfig); + value |= LPI2C_MCFGR1_IGNACK(masterConfig->ignoreAck); + base->MCFGR1 = value; + + LPI2C_MasterSetWatermarks(base, kDefaultTxWatermark, kDefaultRxWatermark); + + LPI2C_MasterSetBaudRate(base, sourceClock_Hz, masterConfig->baudRate_Hz); + + /* Configure glitch filters and bus idle and pin low timeouts. */ + prescaler = (base->MCFGR1 & LPI2C_MCFGR1_PRESCALE_MASK) >> LPI2C_MCFGR1_PRESCALE_SHIFT; + cfgr2 = base->MCFGR2; + if (masterConfig->busIdleTimeout_ns) + { + cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->busIdleTimeout_ns, + (LPI2C_MCFGR2_BUSIDLE_MASK >> LPI2C_MCFGR2_BUSIDLE_SHIFT), prescaler); + cfgr2 &= ~LPI2C_MCFGR2_BUSIDLE_MASK; + cfgr2 |= LPI2C_MCFGR2_BUSIDLE(cycles); + } + if (masterConfig->sdaGlitchFilterWidth_ns) + { + cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->sdaGlitchFilterWidth_ns, + (LPI2C_MCFGR2_FILTSDA_MASK >> LPI2C_MCFGR2_FILTSDA_SHIFT), 1); + cfgr2 &= ~LPI2C_MCFGR2_FILTSDA_MASK; + cfgr2 |= LPI2C_MCFGR2_FILTSDA(cycles); + } + if (masterConfig->sclGlitchFilterWidth_ns) + { + cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->sclGlitchFilterWidth_ns, + (LPI2C_MCFGR2_FILTSCL_MASK >> LPI2C_MCFGR2_FILTSCL_SHIFT), 1); + cfgr2 &= ~LPI2C_MCFGR2_FILTSCL_MASK; + cfgr2 |= LPI2C_MCFGR2_FILTSCL(cycles); + } + base->MCFGR2 = cfgr2; + if (masterConfig->pinLowTimeout_ns) + { + cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->pinLowTimeout_ns / 256, + (LPI2C_MCFGR2_BUSIDLE_MASK >> LPI2C_MCFGR2_BUSIDLE_SHIFT), prescaler); + base->MCFGR3 = (base->MCFGR3 & ~LPI2C_MCFGR3_PINLOW_MASK) | LPI2C_MCFGR3_PINLOW(cycles); + } + + LPI2C_MasterEnable(base, masterConfig->enableMaster); +} + +/*! + * brief Deinitializes the LPI2C master peripheral. + * + * This function disables the LPI2C master peripheral and gates the clock. It also performs a software + * reset to restore the peripheral to reset conditions. + * + * param base The LPI2C peripheral base address. + */ +void LPI2C_MasterDeinit(LPI2C_Type *base) +{ + /* Restore to reset state. */ + LPI2C_MasterReset(base); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + + uint32_t instance = LPI2C_GetInstance(base); + + /* Gate clock. */ + CLOCK_DisableClock(kLpi2cClocks[instance]); +#if defined(LPI2C_PERIPH_CLOCKS) + /* Gate the functional clock. */ + CLOCK_DisableClock(kLpi2cPeriphClocks[instance]); +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Configures LPI2C master data match feature. + * + * param base The LPI2C peripheral base address. + * param config Settings for the data match feature. + */ +void LPI2C_MasterConfigureDataMatch(LPI2C_Type *base, const lpi2c_data_match_config_t *config) +{ + /* Disable master mode. */ + bool wasEnabled = (base->MCR & LPI2C_MCR_MEN_MASK) >> LPI2C_MCR_MEN_SHIFT; + LPI2C_MasterEnable(base, false); + + base->MCFGR1 = (base->MCFGR1 & ~LPI2C_MCFGR1_MATCFG_MASK) | LPI2C_MCFGR1_MATCFG(config->matchMode); + base->MCFGR0 = (base->MCFGR0 & ~LPI2C_MCFGR0_RDMO_MASK) | LPI2C_MCFGR0_RDMO(config->rxDataMatchOnly); + base->MDMR = LPI2C_MDMR_MATCH0(config->match0) | LPI2C_MDMR_MATCH1(config->match1); + + /* Restore master mode. */ + if (wasEnabled) + { + LPI2C_MasterEnable(base, true); + } +} + +/*! + * brief Sets the I2C bus frequency for master transactions. + * + * The LPI2C master is automatically disabled and re-enabled as necessary to configure the baud + * rate. Do not call this function during a transfer, or the transfer is aborted. + * + * note Please note that the second parameter is the clock frequency of LPI2C module, the third + * parameter means user configured bus baudrate, this implementation is different from other I2C drivers + * which use baudrate configuration as second parameter and source clock frequency as third parameter. + * + * param base The LPI2C peripheral base address. + * param sourceClock_Hz LPI2C functional clock frequency in Hertz. + * param baudRate_Hz Requested bus frequency in Hertz. + */ +void LPI2C_MasterSetBaudRate(LPI2C_Type *base, uint32_t sourceClock_Hz, uint32_t baudRate_Hz) +{ + uint32_t prescale = 0; + uint32_t bestPre = 0; + uint32_t bestClkHi = 0; + uint32_t absError = 0; + uint32_t bestError = 0xffffffffu; + uint32_t value; + uint32_t clkHiCycle; + uint32_t computedRate; + int i; + bool wasEnabled; + + /* Disable master mode. */ + wasEnabled = (base->MCR & LPI2C_MCR_MEN_MASK) >> LPI2C_MCR_MEN_SHIFT; + LPI2C_MasterEnable(base, false); + + /* Baud rate = (sourceClock_Hz/2^prescale)/(CLKLO+1+CLKHI+1 + ROUNDDOWN((2+FILTSCL)/2^prescale) */ + /* Assume CLKLO = 2*CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2. */ + for (prescale = 1; (prescale <= 128) && (bestError != 0); prescale = 2 * prescale) + { + for (clkHiCycle = 1; clkHiCycle < 32; clkHiCycle++) + { + if (clkHiCycle == 1) + { + computedRate = (sourceClock_Hz / prescale) / (1 + 3 + 2 + 2 / prescale); + } + else + { + computedRate = (sourceClock_Hz / prescale) / (3 * clkHiCycle + 2 + 2 / prescale); + } + + absError = baudRate_Hz > computedRate ? baudRate_Hz - computedRate : computedRate - baudRate_Hz; + + if (absError < bestError) + { + bestPre = prescale; + bestClkHi = clkHiCycle; + bestError = absError; + + /* If the error is 0, then we can stop searching because we won't find a better match. */ + if (absError == 0) + { + break; + } + } + } + } + + /* Standard, fast, fast mode plus and ultra-fast transfers. */ + value = LPI2C_MCCR0_CLKHI(bestClkHi); + + if (bestClkHi < 2) + { + value |= LPI2C_MCCR0_CLKLO(3) | LPI2C_MCCR0_SETHOLD(2) | LPI2C_MCCR0_DATAVD(1); + } + else + { + value |= LPI2C_MCCR0_CLKLO(2 * bestClkHi) | LPI2C_MCCR0_SETHOLD(bestClkHi) | LPI2C_MCCR0_DATAVD(bestClkHi / 2); + } + + base->MCCR0 = value; + + for (i = 0; i < 8; i++) + { + if (bestPre == (1U << i)) + { + bestPre = i; + break; + } + } + base->MCFGR1 = (base->MCFGR1 & ~LPI2C_MCFGR1_PRESCALE_MASK) | LPI2C_MCFGR1_PRESCALE(bestPre); + + /* Restore master mode. */ + if (wasEnabled) + { + LPI2C_MasterEnable(base, true); + } +} + +/*! + * brief Sends a START signal and slave address on the I2C bus. + * + * This function is used to initiate a new master mode transfer. First, the bus state is checked to ensure + * that another master is not occupying the bus. Then a START signal is transmitted, followed by the + * 7-bit address specified in the a address parameter. Note that this function does not actually wait + * until the START and address are successfully sent on the bus before returning. + * + * param base The LPI2C peripheral base address. + * param address 7-bit slave device address, in bits [6:0]. + * param dir Master transfer direction, either #kLPI2C_Read or #kLPI2C_Write. This parameter is used to set + * the R/w bit (bit 0) in the transmitted slave address. + * retval #kStatus_Success START signal and address were successfully enqueued in the transmit FIFO. + * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus. + */ +status_t LPI2C_MasterStart(LPI2C_Type *base, uint8_t address, lpi2c_direction_t dir) +{ + /* Return an error if the bus is already in use not by us. */ + status_t result = LPI2C_CheckForBusyBus(base); + if (result) + { + return result; + } + + /* Clear all flags. */ + LPI2C_MasterClearStatusFlags(base, kMasterClearFlags); + + /* Turn off auto-stop option. */ + base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK; + + /* Wait until there is room in the fifo. */ + result = LPI2C_MasterWaitForTxReady(base); + if (result) + { + return result; + } + + /* Issue start command. */ + base->MTDR = kStartCmd | (((uint32_t)address << 1U) | (uint32_t)dir); + + return kStatus_Success; +} + +/*! + * brief Sends a STOP signal on the I2C bus. + * + * This function does not return until the STOP signal is seen on the bus, or an error occurs. + * + * param base The LPI2C peripheral base address. + * retval #kStatus_Success The STOP signal was successfully sent on the bus and the transaction terminated. + * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus. + * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte. + * retval #kStatus_LPI2C_FifoError FIFO under run or overrun. + * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error. + * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout. + */ +status_t LPI2C_MasterStop(LPI2C_Type *base) +{ + /* Wait until there is room in the fifo. */ + status_t result = LPI2C_MasterWaitForTxReady(base); + if (result) + { + return result; + } + + /* Send the STOP signal */ + base->MTDR = kStopCmd; + +/* Wait for the stop detected flag to set, indicating the transfer has completed on the bus. */ +/* Also check for errors while waiting. */ +#if LPI2C_WAIT_TIMEOUT + uint32_t waitTimes = LPI2C_WAIT_TIMEOUT; +#endif + +#if LPI2C_WAIT_TIMEOUT + while ((result == kStatus_Success) && (--waitTimes)) +#else + while (result == kStatus_Success) +#endif + { + uint32_t status = LPI2C_MasterGetStatusFlags(base); + + /* Check for error flags. */ + result = LPI2C_MasterCheckAndClearError(base, status); + + /* Check if the stop was sent successfully. */ + if ((status & kLPI2C_MasterStopDetectFlag) && (status & kLPI2C_MasterTxReadyFlag)) + { + LPI2C_MasterClearStatusFlags(base, kLPI2C_MasterStopDetectFlag); + break; + } + } + +#if LPI2C_WAIT_TIMEOUT + if (waitTimes == 0) + { + return kStatus_LPI2C_Timeout; + } +#endif + + return result; +} + +/*! + * brief Performs a polling receive transfer on the I2C bus. + * + * param base The LPI2C peripheral base address. + * param rxBuff The pointer to the data to be transferred. + * param rxSize The length in bytes of the data to be transferred. + * retval #kStatus_Success Data was received successfully. + * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus. + * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte. + * retval #kStatus_LPI2C_FifoError FIFO under run or overrun. + * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error. + * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout. + */ +status_t LPI2C_MasterReceive(LPI2C_Type *base, void *rxBuff, size_t rxSize) +{ + status_t result; + uint8_t *buf; + + assert(rxBuff); + + /* Handle empty read. */ + if (!rxSize) + { + return kStatus_Success; + } + + /* Wait until there is room in the command fifo. */ + result = LPI2C_MasterWaitForTxReady(base); + if (result) + { + return result; + } + + /* Issue command to receive data. */ + base->MTDR = kRxDataCmd | LPI2C_MTDR_DATA(rxSize - 1); + +#if LPI2C_WAIT_TIMEOUT + uint32_t waitTimes = LPI2C_WAIT_TIMEOUT; +#endif + + /* Receive data */ + buf = (uint8_t *)rxBuff; + while (rxSize--) + { + /* Read LPI2C receive fifo register. The register includes a flag to indicate whether */ + /* the FIFO is empty, so we can both get the data and check if we need to keep reading */ + /* using a single register read. */ + uint32_t value; + do + { + /* Check for errors. */ + result = LPI2C_MasterCheckAndClearError(base, LPI2C_MasterGetStatusFlags(base)); + if (result) + { + return result; + } + + value = base->MRDR; +#if LPI2C_WAIT_TIMEOUT + } while ((value & LPI2C_MRDR_RXEMPTY_MASK) && (--waitTimes)); + if (waitTimes == 0) + { + return kStatus_LPI2C_Timeout; + } +#else + } while (value & LPI2C_MRDR_RXEMPTY_MASK); +#endif + + *buf++ = value & LPI2C_MRDR_DATA_MASK; + } + + return kStatus_Success; +} + +/*! + * brief Performs a polling send transfer on the I2C bus. + * + * Sends up to a txSize number of bytes to the previously addressed slave device. The slave may + * reply with a NAK to any byte in order to terminate the transfer early. If this happens, this + * function returns #kStatus_LPI2C_Nak. + * + * param base The LPI2C peripheral base address. + * param txBuff The pointer to the data to be transferred. + * param txSize The length in bytes of the data to be transferred. + * retval #kStatus_Success Data was sent successfully. + * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus. + * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte. + * retval #kStatus_LPI2C_FifoError FIFO under run or over run. + * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error. + * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout. + */ +status_t LPI2C_MasterSend(LPI2C_Type *base, void *txBuff, size_t txSize) +{ + uint8_t *buf = (uint8_t *)txBuff; + + assert(txBuff); + + /* Send data buffer */ + while (txSize--) + { + /* Wait until there is room in the fifo. This also checks for errors. */ + status_t result = LPI2C_MasterWaitForTxReady(base); + if (result) + { + return result; + } + + /* Write byte into LPI2C master data register. */ + base->MTDR = *buf++; + } + + return kStatus_Success; +} + +/*! + * brief Performs a master polling transfer on the I2C bus. + * + * note The API does not return until the transfer succeeds or fails due + * to error happens during transfer. + * + * param base The LPI2C peripheral base address. + * param transfer Pointer to the transfer structure. + * retval #kStatus_Success Data was received successfully. + * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus. + * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte. + * retval #kStatus_LPI2C_FifoError FIFO under run or overrun. + * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error. + * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout. + */ +status_t LPI2C_MasterTransferBlocking(LPI2C_Type *base, lpi2c_master_transfer_t *transfer) +{ + status_t result = kStatus_Success; + uint16_t commandBuffer[7]; + uint32_t cmdCount = 0; + + assert(transfer); + assert(transfer->subaddressSize <= sizeof(transfer->subaddress)); + + /* Return an error if the bus is already in use not by us. */ + result = LPI2C_CheckForBusyBus(base); + if (result) + { + return result; + } + + /* Clear all flags. */ + LPI2C_MasterClearStatusFlags(base, kMasterClearFlags); + + /* Turn off auto-stop option. */ + base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK; + + lpi2c_direction_t direction = transfer->subaddressSize ? kLPI2C_Write : transfer->direction; + if (!(transfer->flags & kLPI2C_TransferNoStartFlag)) + { + commandBuffer[cmdCount++] = + (uint16_t)kStartCmd | (uint16_t)((uint16_t)((uint16_t)transfer->slaveAddress << 1U) | (uint16_t)direction); + } + + /* Subaddress, MSB first. */ + if (transfer->subaddressSize) + { + uint32_t subaddressRemaining = transfer->subaddressSize; + while (subaddressRemaining--) + { + uint8_t subaddressByte = (transfer->subaddress >> (8 * subaddressRemaining)) & 0xff; + commandBuffer[cmdCount++] = subaddressByte; + } + } + + /* Reads need special handling. */ + if ((transfer->dataSize) && (transfer->direction == kLPI2C_Read)) + { + /* Need to send repeated start if switching directions to read. */ + if (direction == kLPI2C_Write) + { + commandBuffer[cmdCount++] = + (uint16_t)kStartCmd | + (uint16_t)((uint16_t)((uint16_t)transfer->slaveAddress << 1U) | (uint16_t)kLPI2C_Read); + } + } + + /* Send command buffer */ + uint32_t index = 0; + while (cmdCount--) + { + /* Wait until there is room in the fifo. This also checks for errors. */ + result = LPI2C_MasterWaitForTxReady(base); + if (result) + { + return result; + } + + /* Write byte into LPI2C master data register. */ + base->MTDR = commandBuffer[index]; + index++; + } + + /* Transmit data. */ + if ((transfer->direction == kLPI2C_Write) && (transfer->dataSize > 0)) + { + /* Send Data. */ + result = LPI2C_MasterSend(base, transfer->data, transfer->dataSize); + } + + /* Receive Data. */ + if ((transfer->direction == kLPI2C_Read) && (transfer->dataSize > 0)) + { + result = LPI2C_MasterReceive(base, transfer->data, transfer->dataSize); + } + + if (result) + { + return result; + } + + if ((transfer->flags & kLPI2C_TransferNoStopFlag) == 0) + { + result = LPI2C_MasterStop(base); + } + + return result; +} + +/*! + * brief Creates a new handle for the LPI2C master non-blocking APIs. + * + * The creation of a handle is for use with the non-blocking APIs. Once a handle + * is created, there is not a corresponding destroy handle. If the user wants to + * terminate a transfer, the LPI2C_MasterTransferAbort() API shall be called. + * + * + * note The function also enables the NVIC IRQ for the input LPI2C. Need to notice + * that on some SoCs the LPI2C IRQ is connected to INTMUX, in this case user needs to + * enable the associated INTMUX IRQ in application. + * + * param base The LPI2C peripheral base address. + * param[out] handle Pointer to the LPI2C master driver handle. + * param callback User provided pointer to the asynchronous callback function. + * param userData User provided pointer to the application callback data. + */ +void LPI2C_MasterTransferCreateHandle(LPI2C_Type *base, + lpi2c_master_handle_t *handle, + lpi2c_master_transfer_callback_t callback, + void *userData) +{ + uint32_t instance; + + assert(handle); + + /* Clear out the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Look up instance number */ + instance = LPI2C_GetInstance(base); + + /* Save base and instance. */ + handle->completionCallback = callback; + handle->userData = userData; + + /* Save this handle for IRQ use. */ + s_lpi2cMasterHandle[instance] = handle; + + /* Set irq handler. */ + s_lpi2cMasterIsr = LPI2C_MasterTransferHandleIRQ; + + /* Clear internal IRQ enables and enable NVIC IRQ. */ + LPI2C_MasterDisableInterrupts(base, kMasterIrqFlags); + + /* Enable NVIC IRQ, this only enables the IRQ directly connected to the NVIC. + In some cases the LPI2C IRQ is configured through INTMUX, user needs to enable + INTMUX IRQ in application code. */ + EnableIRQ(kLpi2cIrqs[instance]); +} + +/*! + * @brief Execute states until FIFOs are exhausted. + * @param handle Master nonblocking driver handle. + * @param[out] isDone Set to true if the transfer has completed. + * @retval #kStatus_Success + * @retval #kStatus_LPI2C_PinLowTimeout + * @retval #kStatus_LPI2C_ArbitrationLost + * @retval #kStatus_LPI2C_Nak + * @retval #kStatus_LPI2C_FifoError + */ +static status_t LPI2C_RunTransferStateMachine(LPI2C_Type *base, lpi2c_master_handle_t *handle, bool *isDone) +{ + uint32_t status; + status_t result = kStatus_Success; + lpi2c_master_transfer_t *xfer; + size_t txCount; + size_t rxCount; + size_t txFifoSize = FSL_FEATURE_LPI2C_FIFO_SIZEn(base); + bool state_complete = false; + + /* Set default isDone return value. */ + *isDone = false; + + /* Check for errors. */ + status = LPI2C_MasterGetStatusFlags(base); + result = LPI2C_MasterCheckAndClearError(base, status); + if (result) + { + return result; + } + + /* Get pointer to private data. */ + xfer = &handle->transfer; + + /* Get fifo counts and compute room in tx fifo. */ + LPI2C_MasterGetFifoCounts(base, &rxCount, &txCount); + txCount = txFifoSize - txCount; + + while (!state_complete) + { + /* Execute the state. */ + switch (handle->state) + { + case kSendCommandState: + { + /* Make sure there is room in the tx fifo for the next command. */ + if (!txCount--) + { + state_complete = true; + break; + } + + /* Issue command. buf is a uint8_t* pointing at the uint16 command array. */ + base->MTDR = *(uint16_t *)handle->buf; + handle->buf += sizeof(uint16_t); + + /* Count down until all commands are sent. */ + if (--handle->remainingBytes == 0) + { + /* Choose next state and set up buffer pointer and count. */ + if (xfer->dataSize) + { + /* Either a send or receive transfer is next. */ + handle->state = kTransferDataState; + handle->buf = (uint8_t *)xfer->data; + handle->remainingBytes = xfer->dataSize; + if (xfer->direction == kLPI2C_Read) + { + /* Disable TX interrupt */ + LPI2C_MasterDisableInterrupts(base, kLPI2C_MasterTxReadyFlag); + } + } + else + { + /* No transfer, so move to stop state. */ + handle->state = kStopState; + } + } + break; + } + + case kIssueReadCommandState: + /* Make sure there is room in the tx fifo for the read command. */ + if (!txCount--) + { + state_complete = true; + break; + } + + base->MTDR = kRxDataCmd | LPI2C_MTDR_DATA(xfer->dataSize - 1); + + /* Move to transfer state. */ + handle->state = kTransferDataState; + if (xfer->direction == kLPI2C_Read) + { + /* Disable TX interrupt */ + LPI2C_MasterDisableInterrupts(base, kLPI2C_MasterTxReadyFlag); + } + break; + + case kTransferDataState: + if (xfer->direction == kLPI2C_Write) + { + /* Make sure there is room in the tx fifo. */ + if (!txCount--) + { + state_complete = true; + break; + } + + /* Put byte to send in fifo. */ + base->MTDR = *(handle->buf)++; + } + else + { + /* XXX handle receive sizes > 256, use kIssueReadCommandState */ + /* Make sure there is data in the rx fifo. */ + if (!rxCount--) + { + state_complete = true; + break; + } + + /* Read byte from fifo. */ + *(handle->buf)++ = base->MRDR & LPI2C_MRDR_DATA_MASK; + } + + /* Move to stop when the transfer is done. */ + if (--handle->remainingBytes == 0) + { + if (xfer->direction == kLPI2C_Write) + { + state_complete = true; + } + handle->state = kStopState; + } + break; + + case kStopState: + /* Only issue a stop transition if the caller requested it. */ + if ((xfer->flags & kLPI2C_TransferNoStopFlag) == 0) + { + /* Make sure there is room in the tx fifo for the stop command. */ + if (!txCount--) + { + state_complete = true; + break; + } + + base->MTDR = kStopCmd; + } + else + { + /* Caller doesn't want to send a stop, so we're done now. */ + *isDone = true; + state_complete = true; + break; + } + handle->state = kWaitForCompletionState; + break; + + case kWaitForCompletionState: + /* We stay in this state until the stop state is detected. */ + if (status & kLPI2C_MasterStopDetectFlag) + { + *isDone = true; + } + state_complete = true; + break; + default: + assert(false); + break; + } + } + return result; +} + +/*! + * @brief Prepares the transfer state machine and fills in the command buffer. + * @param handle Master nonblocking driver handle. + */ +static void LPI2C_InitTransferStateMachine(lpi2c_master_handle_t *handle) +{ + lpi2c_master_transfer_t *xfer = &handle->transfer; + + /* Handle no start option. */ + if (xfer->flags & kLPI2C_TransferNoStartFlag) + { + if (xfer->direction == kLPI2C_Read) + { + /* Need to issue read command first. */ + handle->state = kIssueReadCommandState; + } + else + { + /* Start immediately in the data transfer state. */ + handle->state = kTransferDataState; + } + + handle->buf = (uint8_t *)xfer->data; + handle->remainingBytes = xfer->dataSize; + } + else + { + uint16_t *cmd = (uint16_t *)&handle->commandBuffer; + uint32_t cmdCount = 0; + + /* Initial direction depends on whether a subaddress was provided, and of course the actual */ + /* data transfer direction. */ + lpi2c_direction_t direction = xfer->subaddressSize ? kLPI2C_Write : xfer->direction; + + /* Start command. */ + cmd[cmdCount++] = + (uint16_t)kStartCmd | (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)direction); + + /* Subaddress, MSB first. */ + if (xfer->subaddressSize) + { + uint32_t subaddressRemaining = xfer->subaddressSize; + while (subaddressRemaining--) + { + uint8_t subaddressByte = (xfer->subaddress >> (8 * subaddressRemaining)) & 0xff; + cmd[cmdCount++] = subaddressByte; + } + } + + /* Reads need special handling. */ + if ((xfer->dataSize) && (xfer->direction == kLPI2C_Read)) + { + /* Need to send repeated start if switching directions to read. */ + if (direction == kLPI2C_Write) + { + cmd[cmdCount++] = (uint16_t)kStartCmd | + (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)kLPI2C_Read); + } + + /* Read command. */ + cmd[cmdCount++] = kRxDataCmd | LPI2C_MTDR_DATA(xfer->dataSize - 1); + } + + /* Set up state machine for transferring the commands. */ + handle->state = kSendCommandState; + handle->remainingBytes = cmdCount; + handle->buf = (uint8_t *)&handle->commandBuffer; + } +} + +/*! + * brief Performs a non-blocking transaction on the I2C bus. + * + * param base The LPI2C peripheral base address. + * param handle Pointer to the LPI2C master driver handle. + * param transfer The pointer to the transfer descriptor. + * retval #kStatus_Success The transaction was started successfully. + * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking + * transaction is already in progress. + */ +status_t LPI2C_MasterTransferNonBlocking(LPI2C_Type *base, + lpi2c_master_handle_t *handle, + lpi2c_master_transfer_t *transfer) +{ + status_t result; + + assert(handle); + assert(transfer); + assert(transfer->subaddressSize <= sizeof(transfer->subaddress)); + + /* Return busy if another transaction is in progress. */ + if (handle->state != kIdleState) + { + return kStatus_LPI2C_Busy; + } + + /* Return an error if the bus is already in use not by us. */ + result = LPI2C_CheckForBusyBus(base); + if (result) + { + return result; + } + + /* Disable LPI2C IRQ sources while we configure stuff. */ + LPI2C_MasterDisableInterrupts(base, kMasterIrqFlags); + + /* Save transfer into handle. */ + handle->transfer = *transfer; + + /* Generate commands to send. */ + LPI2C_InitTransferStateMachine(handle); + + /* Clear all flags. */ + LPI2C_MasterClearStatusFlags(base, kMasterClearFlags); + + /* Turn off auto-stop option. */ + base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK; + + /* Enable LPI2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */ + LPI2C_MasterEnableInterrupts(base, kMasterIrqFlags); + + return result; +} + +/*! + * brief Returns number of bytes transferred so far. + * param base The LPI2C peripheral base address. + * param handle Pointer to the LPI2C master driver handle. + * param[out] count Number of bytes transferred so far by the non-blocking transaction. + * retval #kStatus_Success + * retval #kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. + */ +status_t LPI2C_MasterTransferGetCount(LPI2C_Type *base, lpi2c_master_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (handle->state == kIdleState) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + uint8_t state; + uint16_t remainingBytes; + uint32_t dataSize; + + /* Cache some fields with IRQs disabled. This ensures all field values */ + /* are synchronized with each other during an ongoing transfer. */ + uint32_t irqs = LPI2C_MasterGetEnabledInterrupts(base); + LPI2C_MasterDisableInterrupts(base, irqs); + state = handle->state; + remainingBytes = handle->remainingBytes; + dataSize = handle->transfer.dataSize; + LPI2C_MasterEnableInterrupts(base, irqs); + + /* Get transfer count based on current transfer state. */ + switch (state) + { + case kIdleState: + case kSendCommandState: + case kIssueReadCommandState: /* XXX return correct value for this state when >256 reads are supported */ + *count = 0; + break; + + case kTransferDataState: + *count = dataSize - remainingBytes; + break; + + case kStopState: + case kWaitForCompletionState: + default: + *count = dataSize; + break; + } + + return kStatus_Success; +} + +/*! + * brief Terminates a non-blocking LPI2C master transmission early. + * + * note It is not safe to call this function from an IRQ handler that has a higher priority than the + * LPI2C peripheral's IRQ priority. + * + * param base The LPI2C peripheral base address. + * param handle Pointer to the LPI2C master driver handle. + * retval #kStatus_Success A transaction was successfully aborted. + * retval #kStatus_LPI2C_Idle There is not a non-blocking transaction currently in progress. + */ +void LPI2C_MasterTransferAbort(LPI2C_Type *base, lpi2c_master_handle_t *handle) +{ + if (handle->state != kIdleState) + { + /* Disable internal IRQ enables. */ + LPI2C_MasterDisableInterrupts(base, kMasterIrqFlags); + + /* Reset fifos. */ + base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK; + + /* Send a stop command to finalize the transfer. */ + base->MTDR = kStopCmd; + + /* Reset handle. */ + handle->state = kIdleState; + } +} + +/*! + * brief Reusable routine to handle master interrupts. + * note This function does not need to be called unless you are reimplementing the + * nonblocking API's interrupt handler routines to add special functionality. + * param base The LPI2C peripheral base address. + * param handle Pointer to the LPI2C master driver handle. + */ +void LPI2C_MasterTransferHandleIRQ(LPI2C_Type *base, lpi2c_master_handle_t *handle) +{ + bool isDone; + status_t result; + + /* Don't do anything if we don't have a valid handle. */ + if (!handle) + { + return; + } + + if (handle->state == kIdleState) + { + return; + } + + result = LPI2C_RunTransferStateMachine(base, handle, &isDone); + + if (isDone || (result != kStatus_Success)) + { + /* XXX need to handle data that may be in rx fifo below watermark level? */ + + /* XXX handle error, terminate xfer */ + + /* Disable internal IRQ enables. */ + LPI2C_MasterDisableInterrupts(base, kMasterIrqFlags); + + /* Set handle to idle state. */ + handle->state = kIdleState; + + /* Invoke callback. */ + if (handle->completionCallback) + { + handle->completionCallback(base, handle, result, handle->userData); + } + } +} + +/*! + * brief Provides a default configuration for the LPI2C slave peripheral. + * + * This function provides the following default configuration for the LPI2C slave peripheral: + * code + * slaveConfig->enableSlave = true; + * slaveConfig->address0 = 0U; + * slaveConfig->address1 = 0U; + * slaveConfig->addressMatchMode = kLPI2C_MatchAddress0; + * slaveConfig->filterDozeEnable = true; + * slaveConfig->filterEnable = true; + * slaveConfig->enableGeneralCall = false; + * slaveConfig->sclStall.enableAck = false; + * slaveConfig->sclStall.enableTx = true; + * slaveConfig->sclStall.enableRx = true; + * slaveConfig->sclStall.enableAddress = true; + * slaveConfig->ignoreAck = false; + * slaveConfig->enableReceivedAddressRead = false; + * slaveConfig->sdaGlitchFilterWidth_ns = 0; + * slaveConfig->sclGlitchFilterWidth_ns = 0; + * slaveConfig->dataValidDelay_ns = 0; + * slaveConfig->clockHoldTime_ns = 0; + * endcode + * + * After calling this function, override any settings to customize the configuration, + * prior to initializing the master driver with LPI2C_SlaveInit(). Be sure to override at least the a + * address0 member of the configuration structure with the desired slave address. + * + * param[out] slaveConfig User provided configuration structure that is set to default values. Refer to + * #lpi2c_slave_config_t. + */ +void LPI2C_SlaveGetDefaultConfig(lpi2c_slave_config_t *slaveConfig) +{ + /* Initializes the configure structure to zero. */ + memset(slaveConfig, 0, sizeof(*slaveConfig)); + + slaveConfig->enableSlave = true; + slaveConfig->address0 = 0U; + slaveConfig->address1 = 0U; + slaveConfig->addressMatchMode = kLPI2C_MatchAddress0; + slaveConfig->filterDozeEnable = true; + slaveConfig->filterEnable = true; + slaveConfig->enableGeneralCall = false; + slaveConfig->sclStall.enableAck = false; + slaveConfig->sclStall.enableTx = true; + slaveConfig->sclStall.enableRx = true; + slaveConfig->sclStall.enableAddress = false; + slaveConfig->ignoreAck = false; + slaveConfig->enableReceivedAddressRead = false; + slaveConfig->sdaGlitchFilterWidth_ns = 0; /* TODO determine default width values */ + slaveConfig->sclGlitchFilterWidth_ns = 0; + slaveConfig->dataValidDelay_ns = 0; + slaveConfig->clockHoldTime_ns = 0; +} + +/*! + * brief Initializes the LPI2C slave peripheral. + * + * This function enables the peripheral clock and initializes the LPI2C slave peripheral as described by the user + * provided configuration. + * + * param base The LPI2C peripheral base address. + * param slaveConfig User provided peripheral configuration. Use LPI2C_SlaveGetDefaultConfig() to get a set of defaults + * that you can override. + * param sourceClock_Hz Frequency in Hertz of the LPI2C functional clock. Used to calculate the filter widths, + * data valid delay, and clock hold time. + */ +void LPI2C_SlaveInit(LPI2C_Type *base, const lpi2c_slave_config_t *slaveConfig, uint32_t sourceClock_Hz) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + + uint32_t instance = LPI2C_GetInstance(base); + + /* Ungate the clock. */ + CLOCK_EnableClock(kLpi2cClocks[instance]); +#if defined(LPI2C_PERIPH_CLOCKS) + /* Ungate the functional clock in initialize function. */ + CLOCK_EnableClock(kLpi2cPeriphClocks[instance]); +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Restore to reset conditions. */ + LPI2C_SlaveReset(base); + + /* Configure peripheral. */ + base->SAMR = LPI2C_SAMR_ADDR0(slaveConfig->address0) | LPI2C_SAMR_ADDR1(slaveConfig->address1); + + base->SCFGR1 = + LPI2C_SCFGR1_ADDRCFG(slaveConfig->addressMatchMode) | LPI2C_SCFGR1_IGNACK(slaveConfig->ignoreAck) | + LPI2C_SCFGR1_RXCFG(slaveConfig->enableReceivedAddressRead) | LPI2C_SCFGR1_GCEN(slaveConfig->enableGeneralCall) | + LPI2C_SCFGR1_ACKSTALL(slaveConfig->sclStall.enableAck) | LPI2C_SCFGR1_TXDSTALL(slaveConfig->sclStall.enableTx) | + LPI2C_SCFGR1_RXSTALL(slaveConfig->sclStall.enableRx) | + LPI2C_SCFGR1_ADRSTALL(slaveConfig->sclStall.enableAddress); + + base->SCFGR2 = + LPI2C_SCFGR2_FILTSDA(LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->sdaGlitchFilterWidth_ns, + (LPI2C_SCFGR2_FILTSDA_MASK >> LPI2C_SCFGR2_FILTSDA_SHIFT), 1)) | + LPI2C_SCFGR2_FILTSCL(LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->sclGlitchFilterWidth_ns, + (LPI2C_SCFGR2_FILTSCL_MASK >> LPI2C_SCFGR2_FILTSCL_SHIFT), 1)) | + LPI2C_SCFGR2_DATAVD(LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->dataValidDelay_ns, + (LPI2C_SCFGR2_DATAVD_MASK >> LPI2C_SCFGR2_DATAVD_SHIFT), 1)) | + LPI2C_SCFGR2_CLKHOLD(LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->clockHoldTime_ns, + (LPI2C_SCFGR2_CLKHOLD_MASK >> LPI2C_SCFGR2_CLKHOLD_SHIFT), 1)); + + /* Save SCR to last so we don't enable slave until it is configured */ + base->SCR = LPI2C_SCR_FILTDZ(slaveConfig->filterDozeEnable) | LPI2C_SCR_FILTEN(slaveConfig->filterEnable) | + LPI2C_SCR_SEN(slaveConfig->enableSlave); +} + +/*! + * brief Deinitializes the LPI2C slave peripheral. + * + * This function disables the LPI2C slave peripheral and gates the clock. It also performs a software + * reset to restore the peripheral to reset conditions. + * + * param base The LPI2C peripheral base address. + */ +void LPI2C_SlaveDeinit(LPI2C_Type *base) +{ + LPI2C_SlaveReset(base); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + + uint32_t instance = LPI2C_GetInstance(base); + + /* Gate the clock. */ + CLOCK_DisableClock(kLpi2cClocks[instance]); + +#if defined(LPI2C_PERIPH_CLOCKS) + /* Gate the functional clock. */ + CLOCK_DisableClock(kLpi2cPeriphClocks[instance]); +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * @brief Convert provided flags to status code, and clear any errors if present. + * @param base The LPI2C peripheral base address. + * @param status Current status flags value that will be checked. + * @retval #kStatus_Success + * @retval #kStatus_LPI2C_BitError + * @retval #kStatus_LPI2C_FifoError + */ +static status_t LPI2C_SlaveCheckAndClearError(LPI2C_Type *base, uint32_t flags) +{ + status_t result = kStatus_Success; + + flags &= kSlaveErrorFlags; + if (flags) + { + if (flags & kLPI2C_SlaveBitErrFlag) + { + result = kStatus_LPI2C_BitError; + } + else if (flags & kLPI2C_SlaveFifoErrFlag) + { + result = kStatus_LPI2C_FifoError; + } + else + { + assert(false); + } + + /* Clear the errors. */ + LPI2C_SlaveClearStatusFlags(base, flags); + } + + return result; +} + +/*! + * brief Performs a polling send transfer on the I2C bus. + * + * param base The LPI2C peripheral base address. + * param txBuff The pointer to the data to be transferred. + * param txSize The length in bytes of the data to be transferred. + * param[out] actualTxSize + * return Error or success status returned by API. + */ +status_t LPI2C_SlaveSend(LPI2C_Type *base, void *txBuff, size_t txSize, size_t *actualTxSize) +{ + uint8_t *buf = (uint8_t *)txBuff; + size_t remaining = txSize; + + assert(txBuff); + +#if LPI2C_WAIT_TIMEOUT + uint32_t waitTimes = LPI2C_WAIT_TIMEOUT; +#endif + + /* Clear stop flag. */ + LPI2C_SlaveClearStatusFlags(base, kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag); + + while (remaining) + { + uint32_t flags; + status_t result; + + /* Wait until we can transmit. */ + do + { + /* Check for errors */ + flags = LPI2C_SlaveGetStatusFlags(base); + result = LPI2C_SlaveCheckAndClearError(base, flags); + if (result) + { + if (actualTxSize) + { + *actualTxSize = txSize - remaining; + } + return result; + } +#if LPI2C_WAIT_TIMEOUT + } while ( + (!(flags & (kLPI2C_SlaveTxReadyFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag))) && + (--waitTimes)); + if (waitTimes == 0) + { + return kStatus_LPI2C_Timeout; + } +#else + } while ( + !(flags & (kLPI2C_SlaveTxReadyFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag))); +#endif + + /* Send a byte. */ + if (flags & kLPI2C_SlaveTxReadyFlag) + { + base->STDR = *buf++; + --remaining; + } + + /* Exit loop if we see a stop or restart in transfer*/ + if ((flags & (kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag)) && (remaining != 0U)) + { + LPI2C_SlaveClearStatusFlags(base, kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag); + break; + } + } + + if (actualTxSize) + { + *actualTxSize = txSize - remaining; + } + + return kStatus_Success; +} + +/*! + * brief Performs a polling receive transfer on the I2C bus. + * + * param base The LPI2C peripheral base address. + * param rxBuff The pointer to the data to be transferred. + * param rxSize The length in bytes of the data to be transferred. + * param[out] actualRxSize + * return Error or success status returned by API. + */ +status_t LPI2C_SlaveReceive(LPI2C_Type *base, void *rxBuff, size_t rxSize, size_t *actualRxSize) +{ + uint8_t *buf = (uint8_t *)rxBuff; + size_t remaining = rxSize; + + assert(rxBuff); + +#if LPI2C_WAIT_TIMEOUT + uint32_t waitTimes = LPI2C_WAIT_TIMEOUT; +#endif + + /* Clear stop flag. */ + LPI2C_SlaveClearStatusFlags(base, kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag); + + while (remaining) + { + uint32_t flags; + status_t result; + + /* Wait until we can receive. */ + do + { + /* Check for errors */ + flags = LPI2C_SlaveGetStatusFlags(base); + result = LPI2C_SlaveCheckAndClearError(base, flags); + if (result) + { + if (actualRxSize) + { + *actualRxSize = rxSize - remaining; + } + return result; + } +#if LPI2C_WAIT_TIMEOUT + } while ( + (!(flags & (kLPI2C_SlaveRxReadyFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag))) && + (--waitTimes)); + if (waitTimes == 0) + { + return kStatus_LPI2C_Timeout; + } +#else + } while ( + !(flags & (kLPI2C_SlaveRxReadyFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag))); +#endif + + /* Receive a byte. */ + if (flags & kLPI2C_SlaveRxReadyFlag) + { + *buf++ = base->SRDR & LPI2C_SRDR_DATA_MASK; + --remaining; + } + + /* Exit loop if we see a stop or restart */ + if ((flags & (kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag)) && (remaining != 0U)) + { + LPI2C_SlaveClearStatusFlags(base, kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag); + break; + } + } + + if (actualRxSize) + { + *actualRxSize = rxSize - remaining; + } + + return kStatus_Success; +} + +/*! + * brief Creates a new handle for the LPI2C slave non-blocking APIs. + * + * The creation of a handle is for use with the non-blocking APIs. Once a handle + * is created, there is not a corresponding destroy handle. If the user wants to + * terminate a transfer, the LPI2C_SlaveTransferAbort() API shall be called. + * + * note The function also enables the NVIC IRQ for the input LPI2C. Need to notice + * that on some SoCs the LPI2C IRQ is connected to INTMUX, in this case user needs to + * enable the associated INTMUX IRQ in application. + + * param base The LPI2C peripheral base address. + * param[out] handle Pointer to the LPI2C slave driver handle. + * param callback User provided pointer to the asynchronous callback function. + * param userData User provided pointer to the application callback data. + */ +void LPI2C_SlaveTransferCreateHandle(LPI2C_Type *base, + lpi2c_slave_handle_t *handle, + lpi2c_slave_transfer_callback_t callback, + void *userData) +{ + uint32_t instance; + + assert(handle); + + /* Clear out the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Look up instance number */ + instance = LPI2C_GetInstance(base); + + /* Save base and instance. */ + handle->callback = callback; + handle->userData = userData; + + /* Save this handle for IRQ use. */ + s_lpi2cSlaveHandle[instance] = handle; + + /* Set irq handler. */ + s_lpi2cSlaveIsr = LPI2C_SlaveTransferHandleIRQ; + + /* Clear internal IRQ enables and enable NVIC IRQ. */ + LPI2C_SlaveDisableInterrupts(base, kSlaveIrqFlags); + EnableIRQ(kLpi2cIrqs[instance]); + + /* Nack by default. */ + base->STAR = LPI2C_STAR_TXNACK_MASK; +} + +/*! + * brief Starts accepting slave transfers. + * + * Call this API after calling I2C_SlaveInit() and LPI2C_SlaveTransferCreateHandle() to start processing + * transactions driven by an I2C master. The slave monitors the I2C bus and pass events to the + * callback that was passed into the call to LPI2C_SlaveTransferCreateHandle(). The callback is always invoked + * from the interrupt context. + * + * The set of events received by the callback is customizable. To do so, set the a eventMask parameter to + * the OR'd combination of #lpi2c_slave_transfer_event_t enumerators for the events you wish to receive. + * The #kLPI2C_SlaveTransmitEvent and #kLPI2C_SlaveReceiveEvent events are always enabled and do not need + * to be included in the mask. Alternatively, you can pass 0 to get a default set of only the transmit and + * receive events that are always enabled. In addition, the #kLPI2C_SlaveAllEvents constant is provided as + * a convenient way to enable all events. + * + * param base The LPI2C peripheral base address. + * param handle Pointer to #lpi2c_slave_handle_t structure which stores the transfer state. + * param eventMask Bit mask formed by OR'ing together #lpi2c_slave_transfer_event_t enumerators to specify + * which events to send to the callback. Other accepted values are 0 to get a default set of + * only the transmit and receive events, and #kLPI2C_SlaveAllEvents to enable all events. + * + * retval #kStatus_Success Slave transfers were successfully started. + * retval #kStatus_LPI2C_Busy Slave transfers have already been started on this handle. + */ +status_t LPI2C_SlaveTransferNonBlocking(LPI2C_Type *base, lpi2c_slave_handle_t *handle, uint32_t eventMask) +{ + uint32_t status; + + assert(handle); + + /* Return busy if another transaction is in progress. */ + if (handle->isBusy) + { + return kStatus_LPI2C_Busy; + } + + /* Return an error if the bus is already in use not by us. */ + status = LPI2C_SlaveGetStatusFlags(base); + if ((status & kLPI2C_SlaveBusBusyFlag) && (!(status & kLPI2C_SlaveBusyFlag))) + { + return kStatus_LPI2C_Busy; + } + + /* Disable LPI2C IRQ sources while we configure stuff. */ + LPI2C_SlaveDisableInterrupts(base, kSlaveIrqFlags); + + /* Clear transfer in handle. */ + memset(&handle->transfer, 0, sizeof(handle->transfer)); + + /* Record that we're busy. */ + handle->isBusy = true; + + /* Set up event mask. tx and rx are always enabled. */ + handle->eventMask = eventMask | kLPI2C_SlaveTransmitEvent | kLPI2C_SlaveReceiveEvent; + + /* Ack by default. */ + base->STAR = 0; + + /* Clear all flags. */ + LPI2C_SlaveClearStatusFlags(base, kSlaveClearFlags); + + /* Enable LPI2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */ + LPI2C_SlaveEnableInterrupts(base, kSlaveIrqFlags); + + return kStatus_Success; +} + +/*! + * brief Gets the slave transfer status during a non-blocking transfer. + * param base The LPI2C peripheral base address. + * param handle Pointer to i2c_slave_handle_t structure. + * param[out] count Pointer to a value to hold the number of bytes transferred. May be NULL if the count is not + * required. + * retval #kStatus_Success + * retval #kStatus_NoTransferInProgress + */ +status_t LPI2C_SlaveTransferGetCount(LPI2C_Type *base, lpi2c_slave_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (!handle->isBusy) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + /* For an active transfer, just return the count from the handle. */ + *count = handle->transferredCount; + + return kStatus_Success; +} + +/*! + * brief Aborts the slave non-blocking transfers. + * note This API could be called at any time to stop slave for handling the bus events. + * param base The LPI2C peripheral base address. + * param handle Pointer to #lpi2c_slave_handle_t structure which stores the transfer state. + * retval #kStatus_Success + * retval #kStatus_LPI2C_Idle + */ +void LPI2C_SlaveTransferAbort(LPI2C_Type *base, lpi2c_slave_handle_t *handle) +{ + assert(handle); + + /* Return idle if no transaction is in progress. */ + if (handle->isBusy) + { + /* Disable LPI2C IRQ sources. */ + LPI2C_SlaveDisableInterrupts(base, kSlaveIrqFlags); + + /* Nack by default. */ + base->STAR = LPI2C_STAR_TXNACK_MASK; + + /* Reset transfer info. */ + memset(&handle->transfer, 0, sizeof(handle->transfer)); + + /* We're no longer busy. */ + handle->isBusy = false; + } +} + +/*! + * brief Reusable routine to handle slave interrupts. + * note This function does not need to be called unless you are reimplementing the + * non blocking API's interrupt handler routines to add special functionality. + * param base The LPI2C peripheral base address. + * param handle Pointer to #lpi2c_slave_handle_t structure which stores the transfer state. + */ +void LPI2C_SlaveTransferHandleIRQ(LPI2C_Type *base, lpi2c_slave_handle_t *handle) +{ + uint32_t flags; + lpi2c_slave_transfer_t *xfer; + + /* Check for a valid handle in case of a spurious interrupt. */ + if (!handle) + { + return; + } + + xfer = &handle->transfer; + + /* Get status flags. */ + flags = LPI2C_SlaveGetStatusFlags(base); + + if (flags & (kLPI2C_SlaveBitErrFlag | kLPI2C_SlaveFifoErrFlag)) + { + xfer->event = kLPI2C_SlaveCompletionEvent; + xfer->completionStatus = LPI2C_SlaveCheckAndClearError(base, flags); + + if ((handle->eventMask & kLPI2C_SlaveCompletionEvent) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + return; + } + if (flags & (kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveStopDetectFlag)) + { + xfer->event = (flags & kLPI2C_SlaveRepeatedStartDetectFlag) ? kLPI2C_SlaveRepeatedStartEvent : + kLPI2C_SlaveCompletionEvent; + xfer->receivedAddress = 0; + xfer->completionStatus = kStatus_Success; + xfer->transferredCount = handle->transferredCount; + + if (xfer->event == kLPI2C_SlaveCompletionEvent) + { + handle->isBusy = false; + } + + if (handle->wasTransmit) + { + /* Subtract one from the transmit count to offset the fact that LPI2C asserts the */ + /* tx flag before it sees the nack from the master-receiver, thus causing one more */ + /* count that the master actually receives. */ + --xfer->transferredCount; + handle->wasTransmit = false; + } + + /* Clear the flag. */ + LPI2C_SlaveClearStatusFlags(base, flags & (kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveStopDetectFlag)); + + /* Revert to sending an Ack by default, in case we sent a Nack for receive. */ + base->STAR = 0; + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + + /* Clean up transfer info on completion, after the callback has been invoked. */ + memset(&handle->transfer, 0, sizeof(handle->transfer)); + } + if (flags & kLPI2C_SlaveAddressValidFlag) + { + xfer->event = kLPI2C_SlaveAddressMatchEvent; + xfer->receivedAddress = base->SASR & LPI2C_SASR_RADDR_MASK; + + /* Update handle status to busy because slave is addressed. */ + handle->isBusy = true; + if ((handle->eventMask & kLPI2C_SlaveAddressMatchEvent) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + } + if (flags & kLPI2C_SlaveTransmitAckFlag) + { + xfer->event = kLPI2C_SlaveTransmitAckEvent; + + if ((handle->eventMask & kLPI2C_SlaveTransmitAckEvent) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + } + + /* Handle transmit and receive. */ + if (flags & kLPI2C_SlaveTxReadyFlag) + { + handle->wasTransmit = true; + + /* If we're out of data, invoke callback to get more. */ + if ((!xfer->data) || (!xfer->dataSize)) + { + xfer->event = kLPI2C_SlaveTransmitEvent; + if (handle->callback) + { + handle->callback(base, xfer, handle->userData); + } + + /* Clear the transferred count now that we have a new buffer. */ + handle->transferredCount = 0; + } + + /* Transmit a byte. */ + if ((xfer->data) && (xfer->dataSize)) + { + base->STDR = *xfer->data++; + --xfer->dataSize; + ++handle->transferredCount; + } + } + if (flags & kLPI2C_SlaveRxReadyFlag) + { + /* If we're out of room in the buffer, invoke callback to get another. */ + if ((!xfer->data) || (!xfer->dataSize)) + { + xfer->event = kLPI2C_SlaveReceiveEvent; + if (handle->callback) + { + handle->callback(base, xfer, handle->userData); + } + + /* Clear the transferred count now that we have a new buffer. */ + handle->transferredCount = 0; + } + + /* Receive a byte. */ + if ((xfer->data) && (xfer->dataSize)) + { + *xfer->data++ = base->SRDR; + --xfer->dataSize; + ++handle->transferredCount; + } + else + { + /* We don't have any room to receive more data, so send a nack. */ + base->STAR = LPI2C_STAR_TXNACK_MASK; + } + } +} + +/*! + * @brief Shared IRQ handler that can call both master and slave ISRs. + * + * The master and slave ISRs are called through function pointers in order to decouple + * this code from the ISR functions. Without this, the linker would always pull in both + * ISRs and every function they call, even if only the functional API was used. + * + * @param base The LPI2C peripheral base address. + * @param instance The LPI2C peripheral instance number. + */ +static void LPI2C_CommonIRQHandler(LPI2C_Type *base, uint32_t instance) +{ + /* Check for master IRQ. */ + if ((base->MCR & LPI2C_MCR_MEN_MASK) && s_lpi2cMasterIsr) + { + /* Master mode. */ + s_lpi2cMasterIsr(base, s_lpi2cMasterHandle[instance]); + } + + /* Check for slave IRQ. */ + if ((base->SCR & LPI2C_SCR_SEN_MASK) && s_lpi2cSlaveIsr) + { + /* Slave mode. */ + s_lpi2cSlaveIsr(base, s_lpi2cSlaveHandle[instance]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +#if defined(LPI2C0) +/* Implementation of LPI2C0 handler named in startup code. */ +void LPI2C0_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(LPI2C0, 0); +} +#endif + +#if defined(LPI2C1) +/* Implementation of LPI2C1 handler named in startup code. */ +void LPI2C1_DriverIRQHandler(int irqn, void *arg) +{ + DisableIRQ(LPI2C1_IRQn); + LPI2C_CommonIRQHandler(LPI2C1, 1); + EnableIRQ(LPI2C1_IRQn); +} +DECLARE_HW_IRQ(LPI2C1_IRQn, LPI2C1_DriverIRQHandler, NONE); +#endif + +#if defined(LPI2C2) +/* Implementation of LPI2C2 handler named in startup code. */ +void LPI2C2_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(LPI2C2, 2); +} +#endif + +#if defined(LPI2C3) +/* Implementation of LPI2C3 handler named in startup code. */ +void LPI2C3_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(LPI2C3, 3); +} +#endif + +#if defined(LPI2C4) +/* Implementation of LPI2C4 handler named in startup code. */ +void LPI2C4_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(LPI2C4, 4); +} +#endif + +#if defined(CM4_0__LPI2C) +/* Implementation of CM4_0__LPI2C handler named in startup code. */ +void M4_0_LPI2C_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(CM4_0__LPI2C, LPI2C_GetInstance(CM4_0__LPI2C)); +} +#endif + +#if defined(CM4__LPI2C) +/* Implementation of CM4__LPI2C handler named in startup code. */ +void M4_LPI2C_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(CM4__LPI2C, LPI2C_GetInstance(CM4__LPI2C)); +} +#endif + +#if defined(CM4_1__LPI2C) +/* Implementation of CM4_1__LPI2C handler named in startup code. */ +void M4_1_LPI2C_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(CM4_1__LPI2C, LPI2C_GetInstance(CM4_1__LPI2C)); +} +#endif + +#if defined(DMA__LPI2C0) +/* Implementation of DMA__LPI2C0 handler named in startup code. */ +void DMA_I2C0_INT_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(DMA__LPI2C0, LPI2C_GetInstance(DMA__LPI2C0)); +} +#endif + +#if defined(DMA__LPI2C1) +/* Implementation of DMA__LPI2C1 handler named in startup code. */ +void DMA_I2C1_INT_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(DMA__LPI2C1, LPI2C_GetInstance(DMA__LPI2C1)); +} +#endif + +#if defined(DMA__LPI2C2) +/* Implementation of DMA__LPI2C2 handler named in startup code. */ +void DMA_I2C2_INT_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(DMA__LPI2C2, LPI2C_GetInstance(DMA__LPI2C2)); +} +#endif + +#if defined(DMA__LPI2C3) +/* Implementation of DMA__LPI2C3 handler named in startup code. */ +void DMA_I2C3_INT_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(DMA__LPI2C3, LPI2C_GetInstance(DMA__LPI2C3)); +} +#endif + +#if defined(DMA__LPI2C4) +/* Implementation of DMA__LPI2C3 handler named in startup code. */ +void DMA_I2C4_INT_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(DMA__LPI2C4, LPI2C_GetInstance(DMA__LPI2C4)); +} +#endif + +#if defined(ADMA__LPI2C0) +/* Implementation of DMA__LPI2C0 handler named in startup code. */ +void ADMA_I2C0_INT_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(ADMA__LPI2C0, LPI2C_GetInstance(ADMA__LPI2C0)); +} +#endif + +#if defined(ADMA__LPI2C1) +/* Implementation of DMA__LPI2C1 handler named in startup code. */ +void ADMA_I2C1_INT_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(ADMA__LPI2C1, LPI2C_GetInstance(ADMA__LPI2C1)); +} +#endif + +#if defined(ADMA__LPI2C2) +/* Implementation of DMA__LPI2C2 handler named in startup code. */ +void ADMA_I2C2_INT_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(ADMA__LPI2C2, LPI2C_GetInstance(ADMA__LPI2C2)); +} +#endif + +#if defined(ADMA__LPI2C3) +/* Implementation of DMA__LPI2C3 handler named in startup code. */ +void ADMA_I2C3_INT_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(ADMA__LPI2C3, LPI2C_GetInstance(ADMA__LPI2C3)); +} +#endif + +#if defined(ADMA__LPI2C4) +/* Implementation of DMA__LPI2C3 handler named in startup code. */ +void ADMA_I2C4_INT_DriverIRQHandler(void) +{ + LPI2C_CommonIRQHandler(ADMA__LPI2C4, LPI2C_GetInstance(ADMA__LPI2C4)); +} +#endif diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/hardware_i2c.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/hardware_i2c.c new file mode 100755 index 000000000..06781487f --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/i2c/hardware_i2c.c @@ -0,0 +1,94 @@ +/* + * The Clear BSD License + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** +* @file hardware_i2c.c +* @brief ok1052-c i2c board relative codes +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-03-01 +*/ + +#include "fsl_common.h" +#include "fsl_lpi2c.h" + +#define I2C_BASE LPI2C1 + +/* Select USB1 PLL (480 MHz) as master lpi2c clock source */ +#define LPI2C_CLOCK_SOURCE_SELECT (0U) +/* Clock divider for master lpi2c clock source */ +#define LPI2C_CLOCK_SOURCE_DIVIDER (5U) + +#define I2C_CLOCK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U)) +#define I2C_BAUDRATE 100000U + +void I2cHardwareInit(void) +{ + lpi2c_master_config_t masterConfig = {0}; + + LPI2C_MasterGetDefaultConfig(&masterConfig); + + /* Change the default baudrate configuration */ + masterConfig.baudRate_Hz = I2C_BAUDRATE; + + /* Initialize the LPI2C master peripheral */ + LPI2C_MasterInit(I2C_BASE, &masterConfig, I2C_CLOCK_FREQ); +} + +status_t I2cHardwareWrite(LPI2C_Type* base, uint16_t slave_addr, uint32_t subAdd, uint8_t* dataBuff, uint16_t dataLen) +{ + lpi2c_master_transfer_t xfer; + xfer.slaveAddress = slave_addr; + xfer.direction = kLPI2C_Write; + xfer.subaddress = subAdd; + xfer.subaddressSize = 0x01; + xfer.data = dataBuff; + xfer.dataSize = dataLen; + xfer.flags = kLPI2C_TransferDefaultFlag; + return LPI2C_MasterTransferBlocking(base, &xfer); +} + +status_t I2cHardwareRead(LPI2C_Type* base, uint16_t slave_addr, uint32_t subAdd, uint8_t* dataBuffer, uint16_t dataLen) +{ + lpi2c_master_transfer_t masterXfer = {0}; + masterXfer.slaveAddress = slave_addr; + masterXfer.direction = kLPI2C_Read; + masterXfer.subaddress = subAdd; + masterXfer.subaddressSize = 0x01; + masterXfer.data = dataBuffer; + masterXfer.dataSize = dataLen; + masterXfer.flags = kLPI2C_TransferDefaultFlag; + return LPI2C_MasterTransferBlocking(base, &masterXfer); +} + diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_i2c.h b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_i2c.h new file mode 100755 index 000000000..4ac207c5f --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_i2c.h @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2021 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_i2c.h +* @brief define ok1052-c board i2c function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_I2C_H +#define CONNECT_I2C_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct Stm32I2c +{ + LPI2C_Type* base; + uint16_t slave_addr; + uint32_t sub_addr; +}Stm32I2cType; + +#define i2c_print KPrintf + +int Imxrt1052HwI2cInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_lcd.h b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_lcd.h new file mode 100644 index 000000000..20c88eaf8 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_lcd.h @@ -0,0 +1,20 @@ +/** +* @file connect_lcd.h +* @brief define xidatong lcd function +* @version 1.0 +* @author AIIT XiUOS Lab +* @date 2022-04-25 +*/ + +#ifndef CONNECT_LCD_H +#define CONNECT_LCD_H + +#include + +#ifdef BSP_USING_TOUCH +#include "connect_touch.h" +#endif + + +int Imxrt1052HwLcdInit(void); +#endif diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_touch.h b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_touch.h new file mode 100644 index 000000000..1be319f06 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_touch.h @@ -0,0 +1,61 @@ + +/** +* @file connect_touch.c +* @brief support xidatong touch function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-04-25 +*/ + +#ifndef CONNECT_TOUCH_H +#define CONNECT_TOUCH_H + +#include + +/* 表示读数据 */ +#define I2C_M_RD 0x0001 + +struct i2c_msg { + uint8_t addr; /*从设备的I2C设备地址 */ + uint16_t flags; /*控制标志 */ + uint16_t len; /*读写数据的长度 */ + uint8_t *buf; /*存储读写数据的指针 */ +}; + +typedef struct +{ + int X; + int Y; +}POINT; + +typedef enum _touch_event +{ + kTouch_Down = 0, /*!< The state changed to touched. */ + kTouch_Up = 1, /*!< The state changed to not touched. */ + kTouch_Contact = 2, /*!< There is a continuous touch being detected. */ + kTouch_Reserved = 3 /*!< No touch information available. */ +} touch_event_t; + +/*设定使用的电容屏IIC设备地址*/ +#define GTP_ADDRESS 0xBA + +#define GTP_MAX_HEIGHT 272 +#define GTP_MAX_WIDTH 480 +#define GTP_INT_TRIGGER 0 +#define GTP_MAX_TOUCH 5 + +#define GTP_CONFIG_MAX_LENGTH 240 +#define GTP_ADDR_LENGTH 2 + +// Registers define +#define GTP_READ_COOR_ADDR 0x814E +#define GTP_REG_SLEEP 0x8040 +#define GTP_REG_SENSOR_ID 0x814A +#define GTP_REG_CONFIG_DATA 0x8047 +#define GTP_REG_VERSION 0x8140 + +#define CFG_GROUP_LEN(p_cfg_grp) (sizeof(p_cfg_grp) / sizeof(p_cfg_grp[0])) + +int HwTouchInit(void); + +#endif diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/fsl_elcdif.h b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/fsl_elcdif.h new file mode 100644 index 000000000..c8e32af13 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/fsl_elcdif.h @@ -0,0 +1,750 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_ELCDIF_H_ +#define _FSL_ELCDIF_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup elcdif + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief eLCDIF driver version */ +#define FSL_ELCDIF_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1. */ +/*@}*/ + +/* All IRQ flags in CTRL1 register. */ +#define ELCDIF_CTRL1_IRQ_MASK \ + (LCDIF_CTRL1_BM_ERROR_IRQ_MASK | LCDIF_CTRL1_OVERFLOW_IRQ_MASK | LCDIF_CTRL1_UNDERFLOW_IRQ_MASK | \ + LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_MASK | LCDIF_CTRL1_VSYNC_EDGE_IRQ_MASK) + +/* All IRQ enable control bits in CTRL1 register. */ +#define ELCDIF_CTRL1_IRQ_EN_MASK \ + (LCDIF_CTRL1_BM_ERROR_IRQ_EN_MASK | LCDIF_CTRL1_OVERFLOW_IRQ_EN_MASK | LCDIF_CTRL1_UNDERFLOW_IRQ_EN_MASK | \ + LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_EN_MASK | LCDIF_CTRL1_VSYNC_EDGE_IRQ_EN_MASK) + +/* All IRQ flags in AS_CTRL register. */ +#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK) +#define ELCDIF_AS_CTRL_IRQ_MASK (LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK) +#else +#define ELCDIF_AS_CTRL_IRQ_MASK 0U +#endif + +/* All IRQ enable control bits in AS_CTRL register. */ +#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK) +#define ELCDIF_AS_CTRL_IRQ_EN_MASK (LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK) +#else +#define ELCDIF_AS_CTRL_IRQ_EN_MASK 0U +#endif + +#if ((ELCDIF_CTRL1_IRQ_MASK & ELCDIF_AS_CTRL_IRQ_MASK) || (ELCDIF_AS_CTRL_IRQ_MASK & ELCDIF_AS_CTRL_IRQ_EN_MASK)) +#error Interrupt bits overlap, need to update the interrupt functions. +#endif + +/* LUT memory entery number. */ +#define ELCDIF_LUT_ENTRY_NUM 256 + +/*! + * @brief eLCDIF signal polarity flags + */ +enum _elcdif_polarity_flags +{ + kELCDIF_VsyncActiveLow = 0U, /*!< VSYNC active low. */ + kELCDIF_VsyncActiveHigh = LCDIF_VDCTRL0_VSYNC_POL_MASK, /*!< VSYNC active high. */ + kELCDIF_HsyncActiveLow = 0U, /*!< HSYNC active low. */ + kELCDIF_HsyncActiveHigh = LCDIF_VDCTRL0_HSYNC_POL_MASK, /*!< HSYNC active high. */ + kELCDIF_DataEnableActiveLow = 0U, /*!< Data enable line active low. */ + kELCDIF_DataEnableActiveHigh = LCDIF_VDCTRL0_ENABLE_POL_MASK, /*!< Data enable line active high. */ + kELCDIF_DriveDataOnFallingClkEdge = 0U, /*!< Drive data on falling clock edge, capture data + on rising clock edge. */ + kELCDIF_DriveDataOnRisingClkEdge = LCDIF_VDCTRL0_DOTCLK_POL_MASK, /*!< Drive data on falling + clock edge, capture data + on rising clock edge. */ +}; + +/*! + * @brief The eLCDIF interrupts to enable. + */ +enum _elcdif_interrupt_enable +{ + kELCDIF_BusMasterErrorInterruptEnable = LCDIF_CTRL1_BM_ERROR_IRQ_EN_MASK, /*!< Bus master error interrupt. */ + kELCDIF_TxFifoOverflowInterruptEnable = LCDIF_CTRL1_OVERFLOW_IRQ_EN_MASK, /*!< TXFIFO overflow interrupt. */ + kELCDIF_TxFifoUnderflowInterruptEnable = LCDIF_CTRL1_UNDERFLOW_IRQ_EN_MASK, /*!< TXFIFO underflow interrupt. */ + kELCDIF_CurFrameDoneInterruptEnable = + LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_EN_MASK, /*!< Interrupt when hardware enters vertical blanking state. */ + kELCDIF_VsyncEdgeInterruptEnable = + LCDIF_CTRL1_VSYNC_EDGE_IRQ_EN_MASK, /*!< Interrupt when hardware encounters VSYNC edge. */ +#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK) + kELCDIF_SciSyncOnInterruptEnable = + LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK, /*!< Interrupt when eLCDIF lock with CSI input. */ +#endif +}; + +/*! + * @brief The eLCDIF interrupt status flags. + */ +enum _elcdif_interrupt_flags +{ + kELCDIF_BusMasterError = LCDIF_CTRL1_BM_ERROR_IRQ_MASK, /*!< Bus master error interrupt. */ + kELCDIF_TxFifoOverflow = LCDIF_CTRL1_OVERFLOW_IRQ_MASK, /*!< TXFIFO overflow interrupt. */ + kELCDIF_TxFifoUnderflow = LCDIF_CTRL1_UNDERFLOW_IRQ_MASK, /*!< TXFIFO underflow interrupt. */ + kELCDIF_CurFrameDone = + LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_MASK, /*!< Interrupt when hardware enters vertical blanking state. */ + kELCDIF_VsyncEdge = LCDIF_CTRL1_VSYNC_EDGE_IRQ_MASK, /*!< Interrupt when hardware encounters VSYNC edge. */ +#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK) + kELCDIF_SciSyncOn = LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK, /*!< Interrupt when eLCDIF lock with CSI input. */ +#endif +}; + +/*! + * @brief eLCDIF status flags + */ +enum _elcdif_status_flags +{ + kELCDIF_LFifoFull = LCDIF_STAT_LFIFO_FULL_MASK, /*!< LFIFO full. */ + kELCDIF_LFifoEmpty = LCDIF_STAT_LFIFO_EMPTY_MASK, /*!< LFIFO empty. */ + kELCDIF_TxFifoFull = LCDIF_STAT_TXFIFO_FULL_MASK, /*!< TXFIFO full. */ + kELCDIF_TxFifoEmpty = LCDIF_STAT_TXFIFO_EMPTY_MASK, /*!< TXFIFO empty. */ +#if defined(LCDIF_STAT_BUSY_MASK) + kELCDIF_LcdControllerBusy = LCDIF_STAT_BUSY_MASK, /*!< The external LCD controller busy signal. */ +#endif +#if defined(LCDIF_STAT_DVI_CURRENT_FIELD_MASK) + kELCDIF_CurDviField2 = LCDIF_STAT_DVI_CURRENT_FIELD_MASK, /*!< Current DVI filed, if set, then current filed is 2, + otherwise current filed is 1. */ +#endif +}; + +/*! + * @brief The pixel format. + * + * This enumerator should be defined together with the array s_pixelFormatReg. + * To support new pixel format, enhance this enumerator and s_pixelFormatReg. + */ +typedef enum _elcdif_pixel_format +{ + kELCDIF_PixelFormatRAW8 = 0, /*!< RAW 8 bit, four data use 32 bits. */ + kELCDIF_PixelFormatRGB565 = 1, /*!< RGB565, two pixel use 32 bits. */ + kELCDIF_PixelFormatRGB666 = 2, /*!< RGB666 unpacked, one pixel uses 32 bits, high byte unused, + upper 2 bits of other bytes unused. */ + kELCDIF_PixelFormatXRGB8888 = 3, /*!< XRGB8888 unpacked, one pixel uses 32 bits, high byte unused. */ + kELCDIF_PixelFormatRGB888 = 4, /*!< RGB888 packed, one pixel uses 24 bits. */ +} elcdif_pixel_format_t; + +/*! @brief The LCD data bus type. */ +typedef enum _elcdif_lcd_data_bus +{ + kELCDIF_DataBus8Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(1), /*!< 8-bit data bus. */ + kELCDIF_DataBus16Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(0), /*!< 16-bit data bus, support RGB565. */ + kELCDIF_DataBus18Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(2), /*!< 18-bit data bus, support RGB666. */ + kELCDIF_DataBus24Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(3), /*!< 24-bit data bus, support RGB888. */ +} elcdif_lcd_data_bus_t; + +/*! + * @brief The register value when using different pixel format. + * + * These register bits control the pixel format: + * - CTRL[DATA_FORMAT_24_BIT] + * - CTRL[DATA_FORMAT_18_BIT] + * - CTRL[DATA_FORMAT_16_BIT] + * - CTRL[WORD_LENGTH] + * - CTRL1[BYTE_PACKING_FORMAT] + */ +typedef struct _elcdif_pixel_format_reg +{ + uint32_t regCtrl; /*!< Value of register CTRL. */ + uint32_t regCtrl1; /*!< Value of register CTRL1. */ +} elcdif_pixel_format_reg_t; + +/*! + * @brief eLCDIF configure structure for RGB mode (DOTCLK mode). + */ +typedef struct _elcdif_rgb_mode_config +{ + uint16_t panelWidth; /*!< Display panel width, pixels per line. */ + uint16_t panelHeight; /*!< Display panel height, how many lines per panel. */ + uint8_t hsw; /*!< HSYNC pulse width. */ + uint8_t hfp; /*!< Horizontal front porch. */ + uint8_t hbp; /*!< Horizontal back porch. */ + uint8_t vsw; /*!< VSYNC pulse width. */ + uint8_t vfp; /*!< Vrtical front porch. */ + uint8_t vbp; /*!< Vertical back porch. */ + uint32_t polarityFlags; /*!< OR'ed value of @ref _elcdif_polarity_flags, used to contol the signal polarity. */ + uint32_t bufferAddr; /*!< Frame buffer address. */ + elcdif_pixel_format_t pixelFormat; /*!< Pixel format. */ + elcdif_lcd_data_bus_t dataBus; /*!< LCD data bus. */ +} elcdif_rgb_mode_config_t; + +/*! + * @brief eLCDIF alpha surface pixel format. + */ +typedef enum _elcdif_as_pixel_format +{ + kELCDIF_AsPixelFormatARGB8888 = 0x0, /*!< 32-bit pixels with alpha. */ + kELCDIF_AsPixelFormatRGB888 = 0x4, /*!< 32-bit pixels without alpha (unpacked 24-bit format) */ + kELCDIF_AsPixelFormatARGB1555 = 0x8, /*!< 16-bit pixels with alpha. */ + kELCDIF_AsPixelFormatARGB4444 = 0x9, /*!< 16-bit pixels with alpha. */ + kELCDIF_AsPixelFormatRGB555 = 0xC, /*!< 16-bit pixels without alpha. */ + kELCDIF_AsPixelFormatRGB444 = 0xD, /*!< 16-bit pixels without alpha. */ + kELCDIF_AsPixelFormatRGB565 = 0xE, /*!< 16-bit pixels without alpha. */ +} elcdif_as_pixel_format_t; + +/*! + * @brief eLCDIF alpha surface buffer configuration. + */ +typedef struct _elcdif_as_buffer_config +{ + uint32_t bufferAddr; /*!< Buffer address. */ + elcdif_as_pixel_format_t pixelFormat; /*!< Pixel format. */ +} elcdif_as_buffer_config_t; + +/*! + * @brief eLCDIF alpha mode during blending. + */ +typedef enum _elcdif_alpha_mode +{ + kELCDIF_AlphaEmbedded, /*!< The alpha surface pixel alpha value will be used for blend. */ + kELCDIF_AlphaOverride, /*!< The user defined alpha value will be used for blend directly. */ + kELCDIF_AlphaMultiply, /*!< The alpha surface pixel alpha value scaled the user defined + alpha value will be used for blend, for example, pixel alpha set + set to 200, user defined alpha set to 100, then the reault alpha + is 200 * 100 / 255. */ + kELCDIF_AlphaRop /*!< Raster operation. */ +} elcdif_alpha_mode_t; + +/*! + * @brief eLCDIF ROP mode during blending. + * + * Explanation: + * - AS: Alpha surface + * - PS: Process surface + * - nAS: Alpha surface NOT value + * - nPS: Process surface NOT value + */ +typedef enum _elcdif_rop_mode +{ + kELCDIF_RopMaskAs = 0x0, /*!< AS AND PS. */ + kELCDIF_RopMaskNotAs = 0x1, /*!< nAS AND PS. */ + kELCDIF_RopMaskAsNot = 0x2, /*!< AS AND nPS. */ + kELCDIF_RopMergeAs = 0x3, /*!< AS OR PS. */ + kELCDIF_RopMergeNotAs = 0x4, /*!< nAS OR PS. */ + kELCDIF_RopMergeAsNot = 0x5, /*!< AS OR nPS. */ + kELCDIF_RopNotCopyAs = 0x6, /*!< nAS. */ + kELCDIF_RopNot = 0x7, /*!< nPS. */ + kELCDIF_RopNotMaskAs = 0x8, /*!< AS NAND PS. */ + kELCDIF_RopNotMergeAs = 0x9, /*!< AS NOR PS. */ + kELCDIF_RopXorAs = 0xA, /*!< AS XOR PS. */ + kELCDIF_RopNotXorAs = 0xB /*!< AS XNOR PS. */ +} elcdif_rop_mode_t; + +/*! + * @brief eLCDIF alpha surface blending configuration. + */ +typedef struct _elcdif_as_blend_config +{ + uint8_t alpha; /*!< User defined alpha value, only used when @ref alphaMode is @ref kELCDIF_AlphaOverride or @ref + kELCDIF_AlphaRop. */ + bool invertAlpha; /*!< Set true to invert the alpha. */ + elcdif_alpha_mode_t alphaMode; /*!< Alpha mode. */ + elcdif_rop_mode_t ropMode; /*!< ROP mode, only valid when @ref alphaMode is @ref kELCDIF_AlphaRop. */ +} elcdif_as_blend_config_t; + +/*! + * @brief eLCDIF LUT + * + * The Lookup Table (LUT) is used to expand the 8 bits pixel to 24 bits pixel + * before output to external displayer. + * + * There are two 256x24 bits LUT memory in LCDIF, the LSB of frame buffer address + * determins which memory to use. + */ +typedef enum _elcdif_lut +{ + kELCDIF_Lut0 = 0, /*!< LUT 0. */ + kELCDIF_Lut1, /*!< LUT 1. */ +} elcdif_lut_t; + +/******************************************************************************* + * APIs + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name eLCDIF initialization and de-initialization + * @{ + */ + +/*! + * @brief Initializes the eLCDIF to work in RGB mode (DOTCLK mode). + * + * This function ungates the eLCDIF clock and configures the eLCDIF peripheral according + * to the configuration structure. + * + * @param base eLCDIF peripheral base address. + * @param config Pointer to the configuration structure. + */ +void ELCDIF_RgbModeInit(LCDIF_Type *base, const elcdif_rgb_mode_config_t *config); + +/*! + * @brief Gets the eLCDIF default configuration structure for RGB (DOTCLK) mode. + * + * This function sets the configuration structure to default values. + * The default configuration is set to the following values. + * @code + config->panelWidth = 480U; + config->panelHeight = 272U; + config->hsw = 41; + config->hfp = 4; + config->hbp = 8; + config->vsw = 10; + config->vfp = 4; + config->vbp = 2; + config->polarityFlags = kELCDIF_VsyncActiveLow | + kELCDIF_HsyncActiveLow | + kELCDIF_DataEnableActiveLow | + kELCDIF_DriveDataOnFallingClkEdge; + config->bufferAddr = 0U; + config->pixelFormat = kELCDIF_PixelFormatRGB888; + config->dataBus = kELCDIF_DataBus24Bit; + @code + * + * @param config Pointer to the eLCDIF configuration structure. + */ +void ELCDIF_RgbModeGetDefaultConfig(elcdif_rgb_mode_config_t *config); + +/*! + * @brief Deinitializes the eLCDIF peripheral. + * + * @param base eLCDIF peripheral base address. + */ +void ELCDIF_Deinit(LCDIF_Type *base); + +/* @} */ + +/*! + * @name Module operation + * @{ + */ + +/*! + * @brief Set the pixel format in RGB (DOTCLK) mode. + * + * @param base eLCDIF peripheral base address. + * @param pixelFormat The pixel format. + */ +void ELCDIF_RgbModeSetPixelFormat(LCDIF_Type *base, elcdif_pixel_format_t pixelFormat); + +/*! + * @brief Start to display in RGB (DOTCLK) mode. + * + * @param base eLCDIF peripheral base address. + */ +static inline void ELCDIF_RgbModeStart(LCDIF_Type *base) +{ + base->CTRL_SET = LCDIF_CTRL_RUN_MASK | LCDIF_CTRL_DOTCLK_MODE_MASK; +} + +/*! + * @brief Stop display in RGB (DOTCLK) mode and wait until finished. + * + * @param base eLCDIF peripheral base address. + */ +void ELCDIF_RgbModeStop(LCDIF_Type *base); + +/*! + * @brief Set the next frame buffer address to display. + * + * @param base eLCDIF peripheral base address. + * @param bufferAddr The frame buffer address to set. + */ +static inline void ELCDIF_SetNextBufferAddr(LCDIF_Type *base, uint32_t bufferAddr) +{ + base->NEXT_BUF = bufferAddr; +} + +/*! + * @brief Reset the eLCDIF peripheral. + * + * @param base eLCDIF peripheral base address. + */ +void ELCDIF_Reset(LCDIF_Type *base); + +#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_RESET_PIN) && FSL_FEATURE_LCDIF_HAS_NO_RESET_PIN) +/*! + * @brief Pull up or down the reset pin for the externel LCD controller. + * + * @param base eLCDIF peripheral base address. + * @param pullUp True to pull up reset pin, false to pull down. + */ +static inline void ELCDIF_PullUpResetPin(LCDIF_Type *base, bool pullUp) +{ + if (pullUp) + { + base->CTRL1_SET = LCDIF_CTRL1_RESET_MASK; + } + else + { + base->CTRL1_CLR = LCDIF_CTRL1_RESET_MASK; + } +} +#endif + +/*! + * @brief Enable or disable the hand shake with PXP. + * + * @param base eLCDIF peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void ELCDIF_EnablePxpHandShake(LCDIF_Type *base, bool enable) +{ + if (enable) + { + base->CTRL_SET = LCDIF_CTRL_ENABLE_PXP_HANDSHAKE_MASK; + } + else + { + base->CTRL_CLR = LCDIF_CTRL_ENABLE_PXP_HANDSHAKE_MASK; + } +} + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Get the CRC value of the frame sent out. + * + * When a frame is sent complete (the interrupt @ref kELCDIF_CurFrameDone assert), this function + * can be used to get the CRC value of the frame sent. + * + * @param base eLCDIF peripheral base address. + * @return The CRC value. + * + * @note The CRC value is dependent on the LCD_DATABUS_WIDTH. + */ +static inline uint32_t ELCDIF_GetCrcValue(LCDIF_Type *base) +{ + return base->CRC_STAT; +} + +/*! + * @brief Get the bus master error virtual address. + * + * When bus master error occurs (the interrupt kELCDIF_BusMasterError assert), this function + * can get the virtual address at which the AXI master received an error + * response from the slave. + * + * @param base eLCDIF peripheral base address. + * @return The error virtual address. + */ +static inline uint32_t ELCDIF_GetBusMasterErrorAddr(LCDIF_Type *base) +{ + return base->BM_ERROR_STAT; +} + +/*! + * @brief Get the eLCDIF status. + * + * The status flags are returned as a mask value, application could check the + * corresponding bit. Example: + * + * @code + uint32_t statusFlags; + statusFlags = ELCDIF_GetStatus(LCDIF); + + // If LFIFO is full. + if (kELCDIF_LFifoFull & statusFlags) + { + // ...; + } + // If TXFIFO is empty. + if (kELCDIF_TxFifoEmpty & statusFlags) + { + // ...; + } + @endcode + * + * @param base eLCDIF peripheral base address. + * @return The mask value of status flags, it is OR'ed value of @ref _elcdif_status_flags. + */ +static inline uint32_t ELCDIF_GetStatus(LCDIF_Type *base) +{ + return base->STAT & (LCDIF_STAT_LFIFO_FULL_MASK | LCDIF_STAT_LFIFO_EMPTY_MASK | LCDIF_STAT_TXFIFO_FULL_MASK | + LCDIF_STAT_TXFIFO_EMPTY_MASK +#if defined(LCDIF_STAT_BUSY_MASK) + | LCDIF_STAT_BUSY_MASK +#endif +#if defined(LCDIF_STAT_DVI_CURRENT_FIELD_MASK) + | LCDIF_STAT_DVI_CURRENT_FIELD_MASK +#endif + ); +} + +/*! + * @brief Get current count in Latency buffer (LFIFO). + * + * @param base eLCDIF peripheral base address. + * @return The LFIFO current count + */ +static inline uint32_t ELCDIF_GetLFifoCount(LCDIF_Type *base) +{ + return (base->STAT & LCDIF_STAT_LFIFO_COUNT_MASK) >> LCDIF_STAT_LFIFO_COUNT_SHIFT; +} + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables eLCDIF interrupt requests. + * + * @param base eLCDIF peripheral base address. + * @param mask interrupt source, OR'ed value of _elcdif_interrupt_enable. + */ +static inline void ELCDIF_EnableInterrupts(LCDIF_Type *base, uint32_t mask) +{ + base->CTRL1_SET = (mask & ELCDIF_CTRL1_IRQ_EN_MASK); +#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS) + base->AS_CTRL |= (mask & ELCDIF_AS_CTRL_IRQ_EN_MASK); +#endif +} + +/*! + * @brief Disables eLCDIF interrupt requests. + * + * @param base eLCDIF peripheral base address. + * @param mask interrupt source, OR'ed value of _elcdif_interrupt_enable. + */ +static inline void ELCDIF_DisableInterrupts(LCDIF_Type *base, uint32_t mask) +{ + base->CTRL1_CLR = (mask & ELCDIF_CTRL1_IRQ_EN_MASK); +#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS) + base->AS_CTRL &= ~(mask & ELCDIF_AS_CTRL_IRQ_EN_MASK); +#endif +} + +/*! + * @brief Get eLCDIF interrupt peding status. + * + * @param base eLCDIF peripheral base address. + * @return Interrupt pending status, OR'ed value of _elcdif_interrupt_flags. + */ +static inline uint32_t ELCDIF_GetInterruptStatus(LCDIF_Type *base) +{ + uint32_t flags; + + flags = (base->CTRL1 & ELCDIF_CTRL1_IRQ_MASK); +#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS) + flags |= (base->AS_CTRL & ELCDIF_AS_CTRL_IRQ_MASK); +#endif + + return flags; +} + +/*! + * @brief Clear eLCDIF interrupt peding status. + * + * @param base eLCDIF peripheral base address. + * @param mask of the flags to clear, OR'ed value of _elcdif_interrupt_flags. + */ +static inline void ELCDIF_ClearInterruptStatus(LCDIF_Type *base, uint32_t mask) +{ + base->CTRL1_CLR = (mask & ELCDIF_CTRL1_IRQ_MASK); +#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS) + base->AS_CTRL &= ~(mask & ELCDIF_AS_CTRL_IRQ_MASK); +#endif +} + +/* @} */ + +#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS) +/*! + * @name Alpha surface + * @{ + */ + +/*! + * @brief Set the configuration for alpha surface buffer. + * + * @param base eLCDIF peripheral base address. + * @param config Pointer to the configuration structure. + */ +void ELCDIF_SetAlphaSurfaceBufferConfig(LCDIF_Type *base, const elcdif_as_buffer_config_t *config); + +/*! + * @brief Set the alpha surface blending configuration. + * + * @param base eLCDIF peripheral base address. + * @param config Pointer to the configuration structure. + */ +void ELCDIF_SetAlphaSurfaceBlendConfig(LCDIF_Type *base, const elcdif_as_blend_config_t *config); + +/*! + * @brief Set the next alpha surface buffer address. + * + * @param base eLCDIF peripheral base address. + * @param bufferAddr Alpha surface buffer address. + */ +static inline void ELCDIF_SetNextAlphaSurfaceBufferAddr(LCDIF_Type *base, uint32_t bufferAddr) +{ + base->AS_NEXT_BUF = bufferAddr; +} + +/*! + * @brief Set the overlay color key. + * + * If a pixel in the current overlay image with a color that falls in the range + * from the @p colorKeyLow to @p colorKeyHigh range, it will use the process surface + * pixel value for that location. + * + * @param base eLCDIF peripheral base address. + * @param colorKeyLow Color key low range. + * @param colorKeyHigh Color key high range. + * + * @note Colorkey operations are higher priority than alpha or ROP operations + */ +static inline void ELCDIF_SetOverlayColorKey(LCDIF_Type *base, uint32_t colorKeyLow, uint32_t colorKeyHigh) +{ + base->AS_CLRKEYLOW = colorKeyLow; + base->AS_CLRKEYHIGH = colorKeyHigh; +} + +/*! + * @brief Enable or disable the color key. + * + * @param base eLCDIF peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void ELCDIF_EnableOverlayColorKey(LCDIF_Type *base, bool enable) +{ + if (enable) + { + base->AS_CTRL |= LCDIF_AS_CTRL_ENABLE_COLORKEY_MASK; + } + else + { + base->AS_CTRL &= ~LCDIF_AS_CTRL_ENABLE_COLORKEY_MASK; + } +} + +/*! + * @brief Enable or disable the alpha surface. + * + * @param base eLCDIF peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void ELCDIF_EnableAlphaSurface(LCDIF_Type *base, bool enable) +{ + if (enable) + { + base->AS_CTRL |= LCDIF_AS_CTRL_AS_ENABLE_MASK; + } + else + { + base->AS_CTRL &= ~LCDIF_AS_CTRL_AS_ENABLE_MASK; + } +} + +/*! + * @brief Enable or disable the process surface. + * + * Process surface is the normal frame buffer. The process surface content + * is controlled by @ref ELCDIF_SetNextBufferAddr. + * + * @param base eLCDIF peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void ELCDIF_EnableProcessSurface(LCDIF_Type *base, bool enable) +{ + if (enable) + { + base->AS_CTRL &= ~LCDIF_AS_CTRL_PS_DISABLE_MASK; + } + else + { + base->AS_CTRL |= LCDIF_AS_CTRL_PS_DISABLE_MASK; + } +} + +/* @} */ +#endif /* FSL_FEATURE_LCDIF_HAS_NO_AS */ + +#if (defined(FSL_FEATURE_LCDIF_HAS_LUT) && FSL_FEATURE_LCDIF_HAS_LUT) +/*! + * @name LUT + * + * The Lookup Table (LUT) is used to expand the 8 bits pixel to 24 bits pixel + * before output to external displayer. + * + * There are two 256x24 bits LUT memory in LCDIF, the LSB of frame buffer address + * determins which memory to use. + * + * @{ + */ + +/*! + * @brief Enable or disable the LUT. + * + * @param base eLCDIF peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void ELCDIF_EnableLut(LCDIF_Type *base, bool enable) +{ + if (enable) + { + base->LUT_CTRL &= ~LCDIF_LUT_CTRL_LUT_BYPASS_MASK; + } + else + { + base->LUT_CTRL |= LCDIF_LUT_CTRL_LUT_BYPASS_MASK; + } +} + +/*! + * @brief Load the LUT value. + * + * This function loads the LUT value to the specific LUT memory, user can + * specify the start entry index. + * + * @param base eLCDIF peripheral base address. + * @param lut Which LUT to load. + * @param startIndex The start index of the LUT entry to update. + * @param lutData The LUT data to load. + * @param count Count of @p lutData. + * @retval kStatus_Success Initialization success. + * @retval kStatus_InvalidArgument Wrong argument. + */ +status_t ELCDIF_UpdateLut( + LCDIF_Type *base, elcdif_lut_t lut, uint16_t startIndex, const uint32_t *lutData, uint16_t count); + +/* @} */ +#endif /* FSL_FEATURE_LCDIF_HAS_LUT */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/* @} */ + +#endif /*_FSL_ELCDIF_H_*/ diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/Kconfig b/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/Kconfig new file mode 100644 index 000000000..3bb8c7daf --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/Kconfig @@ -0,0 +1,21 @@ +if BSP_USING_LCD + config LCD_BUS_NAME + string "lcd bus name" + default "lcd" + config LCD_DRV_NAME + string "lcd bus driver name" + default "lcd_drv" + config LCD_DEVICE_NAME + string "lcd bus device name" + default "lcd_dev" + config LCD_BL_GPIO_PIN + int "BackLight pin number of rgb565 interface" + default 31 + config BSP_LCD_X_MAX + int "LCD Height" + default 272 + config BSP_LCD_Y_MAX + int "LCD Width" + default 480 + +endif diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/Makefile b/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/Makefile new file mode 100644 index 000000000..55d4b3486 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := connect_lcd.c fsl_elcdif.c + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/connect_lcd.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/connect_lcd.c new file mode 100644 index 000000000..ac1459aca --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/connect_lcd.c @@ -0,0 +1,248 @@ +/** +* @file connect_lcd.c +* @brief support xidatong lcd function and register to bus framework +* @version 2.0 +* @author AIIT XiUOS Lab +* @date 2022-04-25 +*/ + +#include +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_elcdif.h" +#include "fsl_gpio.h" + +/* Back light. */ +#define LCD_BL_GPIO GPIO2 +#define LCD_HSW 41 +#define LCD_HFP 8 +#define LCD_HBP 8 +#define LCD_VSW 10 +#define LCD_VFP 4 +#define LCD_VBP 2 + +#define LCD_HEIGHT BSP_LCD_X_MAX +#define LCD_WIDTH BSP_LCD_Y_MAX + + +static uint16_t frame_buffer[LCD_HEIGHT][LCD_WIDTH] SECTION("NonCacheable.init"); +static void InitLcdifPixelClock(void) +{ + /* + * The desired output frame rate is 60Hz. So the pixel clock frequency is: + * (480 + 41 + 4 + 18) * (272 + 10 + 4 + 2) * 60 = 9.2M. + * Here set the LCDIF pixel clock to 9.3M. + */ + + /* + * Initialize the Video PLL. + * Video PLL output clock is OSC24M * (loopDivider + (denominator / numerator)) / postDivider = 93MHz. + */ + clock_video_pll_config_t pll_config; + + pll_config.loopDivider = 31; + pll_config.postDivider = 8; + pll_config.numerator = 0; + pll_config.denominator = 0; + + CLOCK_InitVideoPll(&pll_config); + /* + * 000 derive clock from PLL2 + * 001 derive clock from PLL3 PFD3 + * 010 derive clock from PLL5 + * 011 derive clock from PLL2 PFD0 + * 100 derive clock from PLL2 PFD1 + * 101 derive clock from PLL3 PFD1 + */ + CLOCK_SetMux(kCLOCK_LcdifPreMux, 2); + + CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 4); + + CLOCK_SetDiv(kCLOCK_LcdifDiv, 1); +} +static void InitLcdBacklight(uint8_t level) +{ + gpio_pin_config_t config = { + kGPIO_DigitalOutput, + 0, + }; + + /* Backlight. */ + config.outputLogic = level; + GPIO_PinInit(LCD_BL_GPIO, LCD_BL_GPIO_PIN, &config); +} + +static void ELCDFramebuffSet(void) +{ + /* LCD */ + elcdif_rgb_mode_config_t lcd_config; + + lcd_config.panelWidth = LCD_WIDTH; + lcd_config.panelHeight = LCD_HEIGHT; + lcd_config.hsw = LCD_HSW; + lcd_config.hfp = LCD_HFP; + lcd_config.hbp = LCD_HBP; + lcd_config.vsw = LCD_VSW; + lcd_config.vfp = LCD_VFP; + lcd_config.vbp = LCD_VBP; + + lcd_config.polarityFlags = kELCDIF_DataEnableActiveHigh | + kELCDIF_VsyncActiveLow | + kELCDIF_HsyncActiveLow | + kELCDIF_DriveDataOnRisingClkEdge; + + lcd_config.bufferAddr = (uint32_t)frame_buffer; + lcd_config.pixelFormat = kELCDIF_PixelFormatRGB565; + lcd_config.dataBus = kELCDIF_DataBus16Bit; + + ELCDIF_RgbModeInit (LCDIF, &lcd_config); +} + +static void HwLcdInit() +{ + memset(frame_buffer, 0, sizeof(frame_buffer)); + + /*step1: config PLL clock */ + InitLcdifPixelClock(); + + /*step2: config backlight gpio*/ + InitLcdBacklight(GPIO_HIGH); + + /*step3: fill framebuff*/ + ELCDFramebuffSet(); + + ELCDIF_RgbModeStart(LCDIF); + +} +static void DrvLcdSetPixelDot(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, void* color) +{ + uint16_t i = 0; + uint16_t j = 0; + + for(i = y1; i <= y2; i++) { + for(j = x1; j <= x2; j++) { + frame_buffer[i][j] =(*(uint16_t*)color); + color += sizeof(uint16_t); + } + } +} + +static uint32 LcdWrite(void *dev, struct BusBlockWriteParam *write_param) +{ + x_err_t ret = EOK; + + if (write_param->buffer) + { + LcdWriteParam *show = (LcdWriteParam *)write_param->buffer; + //output string + if(0 == show->type) { + + } + //output dot + else if (1 == show->type) { + DrvLcdSetPixelDot(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos,show->pixel_info.pixel_color); + } else { + KPrintf("LcdWrite donnot support show type(0 string; 1 dot) %u\n", show->type); + ret = -ERROR; + } + } + + return ret; +} + +static uint32 LcdControl(void* drv, struct BusConfigureInfo *configure_info) +{ + x_err_t ret = EOK; + + return ret; +} + +static const struct LcdDevDone dev_done = +{ + NONE, + NONE, + LcdWrite, + NONE, +}; + +static int BoardLcdBusInit(struct LcdBus * lcd_bus, struct LcdDriver * lcd_driver,const char *bus_name, const char *drv_name) +{ + x_err_t ret = EOK; + + /*Init the lcd bus */ + ret = LcdBusInit( lcd_bus, bus_name); + if (EOK != ret) { + KPrintf("Board_lcd_init LcdBusInit error %d\n", ret); + return -ERROR; + } + + /*Init the lcd driver*/ + ret = LcdDriverInit( lcd_driver, drv_name); + if (EOK != ret) { + KPrintf("Board_LCD_init LcdDriverInit error %d\n", ret); + return -ERROR; + } + + /*Attach the lcd driver to the lcd bus*/ + ret = LcdDriverAttachToBus(drv_name, bus_name); + if (EOK != ret) { + KPrintf("Board_LCD_init LcdDriverAttachToBus error %d\n", ret); + return -ERROR; + } + + return ret; +} + +/*Attach the lcd device to the lcd bus*/ +static int BoardLcdDevBend(struct LcdHardwareDevice *lcd_device, void *param, const char *bus_name, const char *dev_name) +{ + x_err_t ret = EOK; + + ret = LcdDeviceRegister(lcd_device, param, dev_name); + if (EOK != ret) { + KPrintf("Board_LCD_init LcdDeviceInit device %s error %d\n", dev_name, ret); + return -ERROR; + } + + ret = LcdDeviceAttachToBus(dev_name, bus_name); + if (EOK != ret) { + KPrintf("Board_LCD_init LcdDeviceAttachToBus device %s error %d\n", dev_name, ret); + return -ERROR; + } + + return ret; +} + +int Imxrt1052HwLcdInit(void) +{ + x_err_t ret = EOK; + + static struct LcdBus lcd_bus; + static struct LcdDriver lcd_drv; + static struct LcdHardwareDevice lcd_dev; + + memset(&lcd_bus, 0, sizeof(struct LcdBus)); + memset(&lcd_drv, 0, sizeof(struct LcdDriver)); + memset(&lcd_dev, 0, sizeof(struct LcdHardwareDevice)); + + + lcd_drv.configure = LcdControl; + + ret = BoardLcdBusInit(&lcd_bus, &lcd_drv, LCD_BUS_NAME, LCD_DRV_NAME); + if (EOK != ret) { + KPrintf("HwLcdInit BoardLcdBusInit error ret %u\n", ret); + return -ERROR; + } + + lcd_dev.dev_done = &dev_done; + + ret = BoardLcdDevBend(&lcd_dev, NONE, LCD_BUS_NAME, LCD_DEVICE_NAME); //init lcd device + if (EOK != ret) { + KPrintf("HwLcdInit BoardLcdDevBend error ret %u\n", ret); + return -ERROR; + } + + HwLcdInit(); + + return ret; +} diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/fsl_elcdif.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/fsl_elcdif.c new file mode 100644 index 000000000..110b6ea07 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/lcd/fsl_elcdif.c @@ -0,0 +1,371 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_elcdif.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.elcdif" +#endif + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for ELCDIF module. + * + * @param base ELCDIF peripheral base address + */ +static uint32_t ELCDIF_GetInstance(LCDIF_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Pointers to ELCDIF bases for each instance. */ +static LCDIF_Type *const s_elcdifBases[] = LCDIF_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to eLCDIF apb_clk for each instance. */ +static const clock_ip_name_t s_elcdifApbClocks[] = LCDIF_CLOCKS; +#if defined(LCDIF_PERIPH_CLOCKS) +/*! @brief Pointers to eLCDIF pix_clk for each instance. */ +static const clock_ip_name_t s_elcdifPixClocks[] = LCDIF_PERIPH_CLOCKS; +#endif +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief The control register value to select different pixel format. */ +elcdif_pixel_format_reg_t s_pixelFormatReg[] = { + /* kELCDIF_PixelFormatRAW8 */ + {/* Register CTRL. */ + LCDIF_CTRL_WORD_LENGTH(1U), + /* Register CTRL1. */ + LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)}, + /* kELCDIF_PixelFormatRGB565 */ + {/* Register CTRL. */ + LCDIF_CTRL_WORD_LENGTH(0U), + /* Register CTRL1. */ + LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)}, + /* kELCDIF_PixelFormatRGB666 */ + {/* Register CTRL. */ + LCDIF_CTRL_WORD_LENGTH(3U) | LCDIF_CTRL_DATA_FORMAT_24_BIT(1U), + /* Register CTRL1. */ + LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)}, + /* kELCDIF_PixelFormatXRGB8888 */ + {/* Register CTRL. 24-bit. */ + LCDIF_CTRL_WORD_LENGTH(3U), + /* Register CTRL1. */ + LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)}, + /* kELCDIF_PixelFormatRGB888 */ + {/* Register CTRL. 24-bit. */ + LCDIF_CTRL_WORD_LENGTH(3U), + /* Register CTRL1. */ + LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)}, +}; + +/******************************************************************************* + * Codes + ******************************************************************************/ +static uint32_t ELCDIF_GetInstance(LCDIF_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_elcdifBases); instance++) + { + if (s_elcdifBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_elcdifBases)); + + return instance; +} + +/*! + * brief Initializes the eLCDIF to work in RGB mode (DOTCLK mode). + * + * This function ungates the eLCDIF clock and configures the eLCDIF peripheral according + * to the configuration structure. + * + * param base eLCDIF peripheral base address. + * param config Pointer to the configuration structure. + */ +void ELCDIF_RgbModeInit(LCDIF_Type *base, const elcdif_rgb_mode_config_t *config) +{ + assert(config); + assert(config->pixelFormat < ARRAY_SIZE(s_pixelFormatReg)); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + uint32_t instance = ELCDIF_GetInstance(base); + /* Enable the clock. */ + CLOCK_EnableClock(s_elcdifApbClocks[instance]); +#if defined(LCDIF_PERIPH_CLOCKS) + CLOCK_EnableClock(s_elcdifPixClocks[instance]); +#endif +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset. */ + ELCDIF_Reset(base); + + base->CTRL = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl | (uint32_t)(config->dataBus) | + LCDIF_CTRL_DOTCLK_MODE_MASK | /* RGB mode. */ + LCDIF_CTRL_BYPASS_COUNT_MASK | /* Keep RUN bit set. */ + LCDIF_CTRL_MASTER_MASK; + + base->CTRL1 = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl1; + + base->TRANSFER_COUNT = ((uint32_t)config->panelHeight << LCDIF_TRANSFER_COUNT_V_COUNT_SHIFT) | + ((uint32_t)config->panelWidth << LCDIF_TRANSFER_COUNT_H_COUNT_SHIFT); + + base->VDCTRL0 = LCDIF_VDCTRL0_ENABLE_PRESENT_MASK | /* Data enable signal. */ + LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT_MASK | /* VSYNC period in the unit of display clock. */ + LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT_MASK | /* VSYNC pulse width in the unit of display clock. */ + (uint32_t)config->polarityFlags | (uint32_t)config->vsw; + + base->VDCTRL1 = config->vsw + config->panelHeight + config->vfp + config->vbp; + base->VDCTRL2 = ((uint32_t)config->hsw << LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_SHIFT) | + ((uint32_t)(config->hfp + config->hbp + config->panelWidth + config->hsw)) + << LCDIF_VDCTRL2_HSYNC_PERIOD_SHIFT; + + base->VDCTRL3 = (((uint32_t)config->hbp + config->hsw) << LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_SHIFT) | + (((uint32_t)config->vbp + config->vsw) << LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_SHIFT); + + base->VDCTRL4 = LCDIF_VDCTRL4_SYNC_SIGNALS_ON_MASK | + ((uint32_t)config->panelWidth << LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_SHIFT); + + base->CUR_BUF = config->bufferAddr; + base->NEXT_BUF = config->bufferAddr; +} + +/*! + * brief Gets the eLCDIF default configuration structure for RGB (DOTCLK) mode. + * + * This function sets the configuration structure to default values. + * The default configuration is set to the following values. + * code + config->panelWidth = 480U; + config->panelHeight = 272U; + config->hsw = 41; + config->hfp = 4; + config->hbp = 8; + config->vsw = 10; + config->vfp = 4; + config->vbp = 2; + config->polarityFlags = kELCDIF_VsyncActiveLow | + kELCDIF_HsyncActiveLow | + kELCDIF_DataEnableActiveLow | + kELCDIF_DriveDataOnFallingClkEdge; + config->bufferAddr = 0U; + config->pixelFormat = kELCDIF_PixelFormatRGB888; + config->dataBus = kELCDIF_DataBus24Bit; + code + * + * param config Pointer to the eLCDIF configuration structure. + */ +void ELCDIF_RgbModeGetDefaultConfig(elcdif_rgb_mode_config_t *config) +{ + assert(config); + + /* Initializes the configure structure to zero. */ + memset(config, 0, sizeof(*config)); + + config->panelWidth = 480U; + config->panelHeight = 272U; + config->hsw = 41; + config->hfp = 4; + config->hbp = 8; + config->vsw = 10; + config->vfp = 4; + config->vbp = 2; + config->polarityFlags = kELCDIF_VsyncActiveLow | kELCDIF_HsyncActiveLow | kELCDIF_DataEnableActiveLow | + kELCDIF_DriveDataOnFallingClkEdge; + config->bufferAddr = 0U; + config->pixelFormat = kELCDIF_PixelFormatRGB888; + config->dataBus = kELCDIF_DataBus24Bit; +} + +/*! + * brief Set the pixel format in RGB (DOTCLK) mode. + * + * param base eLCDIF peripheral base address. + * param pixelFormat The pixel format. + */ +void ELCDIF_RgbModeSetPixelFormat(LCDIF_Type *base, elcdif_pixel_format_t pixelFormat) +{ + assert(pixelFormat < ARRAY_SIZE(s_pixelFormatReg)); + + base->CTRL = (base->CTRL & ~(LCDIF_CTRL_WORD_LENGTH_MASK | LCDIF_CTRL_DATA_FORMAT_24_BIT_MASK | + LCDIF_CTRL_DATA_FORMAT_18_BIT_MASK | LCDIF_CTRL_DATA_FORMAT_16_BIT_MASK)) | + s_pixelFormatReg[(uint32_t)pixelFormat].regCtrl; + + base->CTRL1 = s_pixelFormatReg[(uint32_t)pixelFormat].regCtrl1; +} + +/*! + * brief Deinitializes the eLCDIF peripheral. + * + * param base eLCDIF peripheral base address. + */ +void ELCDIF_Deinit(LCDIF_Type *base) +{ + ELCDIF_Reset(base); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + uint32_t instance = ELCDIF_GetInstance(base); +/* Disable the clock. */ +#if defined(LCDIF_PERIPH_CLOCKS) + CLOCK_DisableClock(s_elcdifPixClocks[instance]); +#endif + CLOCK_DisableClock(s_elcdifApbClocks[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Stop display in RGB (DOTCLK) mode and wait until finished. + * + * param base eLCDIF peripheral base address. + */ +void ELCDIF_RgbModeStop(LCDIF_Type *base) +{ + base->CTRL_CLR = LCDIF_CTRL_DOTCLK_MODE_MASK; + + /* Wait for data transfer finished. */ + while (base->CTRL & LCDIF_CTRL_DOTCLK_MODE_MASK) + { + } +} + +/*! + * brief Reset the eLCDIF peripheral. + * + * param base eLCDIF peripheral base address. + */ +void ELCDIF_Reset(LCDIF_Type *base) +{ + volatile uint32_t i = 0x100; + + /* Disable the clock gate. */ + base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK; + /* Confirm the clock gate is disabled. */ + while (base->CTRL & LCDIF_CTRL_CLKGATE_MASK) + { + } + + /* Reset the block. */ + base->CTRL_SET = LCDIF_CTRL_SFTRST_MASK; + /* Confirm the reset bit is set. */ + while (!(base->CTRL & LCDIF_CTRL_SFTRST_MASK)) + { + } + + /* Delay for the reset. */ + while (i--) + { + } + + /* Bring the module out of reset. */ + base->CTRL_CLR = LCDIF_CTRL_SFTRST_MASK; + /* Disable the clock gate. */ + base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK; +} + +#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS) +/*! + * brief Set the configuration for alpha surface buffer. + * + * param base eLCDIF peripheral base address. + * param config Pointer to the configuration structure. + */ +void ELCDIF_SetAlphaSurfaceBufferConfig(LCDIF_Type *base, const elcdif_as_buffer_config_t *config) +{ + assert(config); + + base->AS_CTRL = (base->AS_CTRL & ~LCDIF_AS_CTRL_FORMAT_MASK) | LCDIF_AS_CTRL_FORMAT(config->pixelFormat); + base->AS_BUF = config->bufferAddr; + base->AS_NEXT_BUF = config->bufferAddr; +} + +/*! + * brief Set the alpha surface blending configuration. + * + * param base eLCDIF peripheral base address. + * param config Pointer to the configuration structure. + */ +void ELCDIF_SetAlphaSurfaceBlendConfig(LCDIF_Type *base, const elcdif_as_blend_config_t *config) +{ + assert(config); + uint32_t reg; + + reg = base->AS_CTRL; + reg &= ~(LCDIF_AS_CTRL_ALPHA_INVERT_MASK | LCDIF_AS_CTRL_ROP_MASK | LCDIF_AS_CTRL_ALPHA_MASK | + LCDIF_AS_CTRL_ALPHA_CTRL_MASK); + reg |= (LCDIF_AS_CTRL_ROP(config->ropMode) | LCDIF_AS_CTRL_ALPHA(config->alpha) | + LCDIF_AS_CTRL_ALPHA_CTRL(config->alphaMode)); + + if (config->invertAlpha) + { + reg |= LCDIF_AS_CTRL_ALPHA_INVERT_MASK; + } + + base->AS_CTRL = reg; +} +#endif /* FSL_FEATURE_LCDIF_HAS_NO_AS */ + +#if (defined(FSL_FEATURE_LCDIF_HAS_LUT) && FSL_FEATURE_LCDIF_HAS_LUT) +/*! + * brief Load the LUT value. + * + * This function loads the LUT value to the specific LUT memory, user can + * specify the start entry index. + * + * param base eLCDIF peripheral base address. + * param lut Which LUT to load. + * param startIndex The start index of the LUT entry to update. + * param lutData The LUT data to load. + * param count Count of p lutData. + * retval kStatus_Success Initialization success. + * retval kStatus_InvalidArgument Wrong argument. + */ +status_t ELCDIF_UpdateLut( + LCDIF_Type *base, elcdif_lut_t lut, uint16_t startIndex, const uint32_t *lutData, uint16_t count) +{ + volatile uint32_t *regLutAddr; + volatile uint32_t *regLutData; + uint32_t i; + + /* Only has 256 entries. */ + if (startIndex + count > ELCDIF_LUT_ENTRY_NUM) + { + return kStatus_InvalidArgument; + } + + if (kELCDIF_Lut0 == lut) + { + regLutAddr = &(base->LUT0_ADDR); + regLutData = &(base->LUT0_DATA); + } + else + { + regLutAddr = &(base->LUT1_ADDR); + regLutData = &(base->LUT1_DATA); + } + + *regLutAddr = startIndex; + + for (i = 0; i < count; i++) + { + *regLutData = lutData[i]; + } + + return kStatus_Success; +} +#endif /* FSL_FEATURE_LCDIF_HAS_LUT */ diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/semc/connect_semc.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/semc/connect_semc.c index 2477fb2f6..58dbb2e23 100644 --- a/Ubiquitous/XiZi/board/xidatong/third_party_driver/semc/connect_semc.c +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/semc/connect_semc.c @@ -5,7 +5,7 @@ #define EXAMPLE_SEMC SEMC #define EXAMPLE_SEMC_START_ADDRESS (0x80000000U) #define EXAMPLE_SEMC_CLK_FREQ CLOCK_GetFreq(kCLOCK_SemcClk) -#define SEMC_SRAM_SIZE (32 * 1024 * 1024) +#define SEMC_SRAM_SIZE (30 * 1024 * 1024) status_t BOARD_InitSEMC(void) { diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/Kconfig b/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/Kconfig new file mode 100644 index 000000000..047564350 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/Kconfig @@ -0,0 +1,12 @@ +if BSP_USING_TOUCH + config TOUCH_BUS_NAME + string "touch bus name" + default "touch" + config TOUCH_DRV_NAME + string "touch bus driver name" + default "touch_drv" + config TOUCH_DEVICE_NAME + string "touch bus device name" + default "touch_dev" + +endif diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/Makefile b/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/Makefile new file mode 100644 index 000000000..80a85e1be --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := connect_touch.c i2c_touch.c + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/connect_touch.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/connect_touch.c new file mode 100644 index 000000000..3f26a3055 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/connect_touch.c @@ -0,0 +1,462 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_touch.c +* @brief support xidatong touch function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-05-15 +*/ + +#include +#include +#include "i2c_touch.h" + +#define LCD_HEIGHT BSP_LCD_X_MAX +#define LCD_WIDTH BSP_LCD_Y_MAX +#define DEFAULT_NUM 0x0D + +uint8_t CTP_CFG_GT911[] = { + 0x5B,0xE0,0x01,0x10,0x01,0x0A,0x0D,0x00,0x01,0x0A, + 0x28,0x0F,0x5A,0x3C,0x03,0x05,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87,0x28,0x09, + 0x32,0x34,0x0C,0x08,0x00,0x00,0x00,0x02,0x02,0x1D, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x28,0x55,0x94,0xC5,0x02,0x07,0x00,0x00,0x04, + 0x8D,0x2B,0x00,0x80,0x32,0x00,0x75,0x3A,0x00,0x6C, + 0x43,0x00,0x64,0x4F,0x00,0x64,0x00,0x00,0x00,0x00, + 0xF0,0x4A,0x3A,0xFF,0xFF,0x27,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x04,0x06,0x08,0x0A,0x0C,0x0E,0x10,0x12, + 0x14,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x26,0x24,0x22,0x21,0x20,0x1F,0x1E,0x1D, + 0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x81,0x01 +}; +uint8_t config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH] + = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; + +int touch_sem = 0; +POINT Pre_Touch_Point; + + + +static int32_t GtpI2cWrite(uint8_t client_addr,uint8_t *buf,int32_t len) +{ + struct i2c_msg msg; + int32_t ret = -1; + int32_t retries = 0; + + // GTP_DEBUG_FUNC(); + + msg.flags = !I2C_M_RD; + msg.addr = client_addr; + msg.len = len; + msg.buf = buf; + //msg.scl_rate = 300 * 1000; // for Rockchip, etc + + while(retries < 5) + { + ret = I2C_Transfer(&msg, 1); + if (ret == 1)break; + retries++; + } + if((retries >= 5)) + { + KPrintf("I2C Write: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((uint16_t)(buf[0] << 8)) | buf[1]), len-2, ret); + ret = -1; + } + return ret; +} +static int32_t GtpI2cRead(uint8_t client_addr, uint8_t *buf, int32_t len) +{ + struct i2c_msg msgs[2]; + int32_t ret = -1; + int32_t retries = 0; + + msgs[0].flags = !I2C_M_RD; + msgs[0].addr = client_addr; + msgs[0].len = GTP_ADDR_LENGTH; + msgs[0].buf = &buf[0]; + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = client_addr; + msgs[1].len = len - GTP_ADDR_LENGTH; + msgs[1].buf = &buf[GTP_ADDR_LENGTH]; + + while(retries < 5) + { + ret = I2C_Transfer( msgs, 2); + if(ret == 2)break; + retries++; + } + if((retries >= 5)) + { + KPrintf("I2C Read: 0x%04X, %d bytes %d times failed, errcode: %d! Process reset.\n", (((uint16_t)(buf[0] << 8)) | buf[1]), len-2, retries,ret); + ret = -1; + } + return ret; +} +static int32_t gt91xx_Config_Write_Proc() +{ + int32_t ret = -1; + + int32_t i = 0; + uint8_t check_sum = 0; + int32_t retry = 0; + uint8_t cfg_num =0x80FE - 0x8047+1 ; + + const uint8_t* cfg_info = CTP_CFG_GT911; + + uint8_t cfg_info_len = CFG_GROUP_LEN(CTP_CFG_GT911) ; + + memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH); + memcpy(&config[GTP_ADDR_LENGTH], cfg_info,cfg_info_len); + + + check_sum = 0; + for (i = GTP_ADDR_LENGTH; i < cfg_num+GTP_ADDR_LENGTH; i++) + { + check_sum += config[i]; + } + config[ cfg_num+GTP_ADDR_LENGTH] = (~check_sum) + 1; //checksum + config[ cfg_num+GTP_ADDR_LENGTH+1] = 1; //refresh ?????? + KPrintf("Driver send config check_sum 0x%x\n",check_sum); + for (retry = 0; retry < 5; retry++) + { + ret = GtpI2cWrite(GTP_ADDRESS, config , cfg_num + GTP_ADDR_LENGTH+2); + if (ret > 0) + { + break; + } + } + return ret; +} + +/** + * @brief 触屏处理函数,轮询或者在触摸中断调用 + * @param 无 + * @retval 无 + */ +bool GetTouchEvent(POINT *touch_point,touch_event_t *touch_event) +{ + + uint8_t end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0}; + uint8_t point_data[2 + 1 + 8 * GTP_MAX_TOUCH + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF}; + uint8_t touch_num = 0; + uint8_t finger = 0; + static uint16_t pre_touch = 0; + + uint8_t client_addr=GTP_ADDRESS; + uint8_t* coor_data = NULL; + int32_t input_x = 0; + int32_t input_y = 0; + int32_t input_w = 0; + + int32_t ret = -1; + + ret = GtpI2cRead(client_addr, point_data, 12);//10字节寄存器加2字节地址 + if (ret < 0) + { + KPrintf("I2C transfer error. errno:%d\n ", ret); + return 0; + } + + finger = point_data[GTP_ADDR_LENGTH];//状态寄存器数据 + + if (finger == 0x00) //没有数据,退出 + { + ret = 0; + goto exit_work_func; + } + + if((finger & 0x80) == 0)//判断buffer status位 + { + ret = 0; + goto exit_work_func;//坐标未就绪,数据无效 + } + + touch_num = finger & 0x0f;//坐标点数 + if (touch_num > GTP_MAX_TOUCH) + { + ret = 0; + goto exit_work_func;//大于最大支持点数,错误退出 + } + + if (touch_num) + { + coor_data = &point_data[0 * 8 + 3]; + input_x = coor_data[1] | (coor_data[2] << 8); //x坐标 + input_y = coor_data[3] | (coor_data[4] << 8); //y坐标 + input_w = coor_data[5] | (coor_data[6] << 8); //size + touch_point->X = input_x; + touch_point->Y = input_y; + *touch_event = kTouch_Down; + Pre_Touch_Point = *touch_point; + + } + else if (pre_touch) //touch_ num=0 且pre_touch!=0 + { + *touch_point = Pre_Touch_Point; + *touch_event = kTouch_Up; + Pre_Touch_Point.X = -1; + Pre_Touch_Point.Y = -1; + } + pre_touch = touch_num; + +exit_work_func: + { + ret = GtpI2cWrite(client_addr, end_cmd, 3); + if (ret < 0) + { + KPrintf("I2C write end_cmd error!\n"); + ret = 0; + } + } + return ret; +} + +int32_t GtpReadVersion(void) +{ + int32_t ret = -1; + uint8_t buf[8] = {GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff}; + + ret = GtpI2cRead(GTP_ADDRESS, buf, sizeof(buf)); + if (ret < 0) + { + KPrintf("GTP read version failed.\n"); + return ret; + } + + if (buf[5] == 0x00) + { + KPrintf("IC1 Version: %c%c%c_%02x%02x\n", buf[2], buf[3], buf[4], buf[7], buf[6]); + } + else + { + KPrintf("IC2 Version: %c%c%c%c_%02x%02x\n", buf[2], buf[3], buf[4], buf[5], buf[7], buf[6]); + } + return ret; +} + +static int32_t GtpGetInfo(void) +{ + uint8_t end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0}; + uint8_t opr_buf[6] = {0}; + int32_t ret = 0; + + uint16_t abs_x_max = GTP_MAX_WIDTH; + uint16_t abs_y_max = GTP_MAX_HEIGHT; + uint8_t int_trigger_type = GTP_INT_TRIGGER; + + /* config the touch as 480*272 size */ + gt91xx_Config_Write_Proc(); + + opr_buf[0] = (uint8_t)((GTP_REG_CONFIG_DATA+1) >> 8); + opr_buf[1] = (uint8_t)((GTP_REG_CONFIG_DATA+1) & 0xFF); + + ret = GtpI2cRead(GTP_ADDRESS, opr_buf, 6); + if (ret < 0) + { + return -1; + } + + abs_x_max = (opr_buf[3] << 8) + opr_buf[2]; + abs_y_max = (opr_buf[5] << 8) + opr_buf[4]; + + opr_buf[0] = (uint8_t)((GTP_REG_CONFIG_DATA+6) >> 8); + opr_buf[1] = (uint8_t)((GTP_REG_CONFIG_DATA+6) & 0xFF); + + ret = GtpI2cRead(GTP_ADDRESS, opr_buf, 3); + if (ret < 0) + { + return 0; + } + int_trigger_type = opr_buf[2] & 0x03; + + KPrintf("X_MAX = %d, Y_MAX = %d, TRIGGER = 0x%02x\n", + abs_x_max,abs_y_max,int_trigger_type); + + ret = GtpI2cWrite(GTP_ADDRESS, end_cmd, 3); + if (ret < 0) + { + KPrintf("I2C write end_cmd error!\n"); + ret = 0; + } + return 0; +} + +static uint32 TouchOpen(void *dev) +{ + int32_t ret = -1; + + I2C_Touch_Init(); + ret = GtpReadVersion(); + if(ret < 0) + { + KPrintf("gtp read version error\n"); + GtpI2cDeinit(); + return ret; + } + + ret = GtpGetInfo(); + if(ret < 0) + { + KPrintf("gtp read info error\n"); + GtpI2cDeinit(); + return ret; + } + + touch_sem = KSemaphoreCreate(0); + if (touch_sem < 0) { + KPrintf("touch create sem failed .\n"); + GtpI2cDeinit(); + return -1; + } + + GTP_IRQEnable(); + return ret; +} +static uint32 TouchClose(void *dev) +{ + GTP_IRQDisable(); + + KSemaphoreDelete(touch_sem); + + GtpI2cDeinit(); + return 0; +} + +static uint32 TouchRead(void *dev, struct BusBlockReadParam *read_param) +{ + uint32 ret = -1; + x_err_t result; + POINT touch_point; + touch_event_t touch_event; + + struct TouchDataStandard *data = (struct TouchDataStandard*)read_param->buffer; + read_param->read_length = 0; + result = KSemaphoreObtain(touch_sem, 1000); + if (EOK == result) + { + if(GetTouchEvent(&touch_point, &touch_event)) + { + data->x = abs(LCD_WIDTH - touch_point.X); + data->y = abs(LCD_HEIGHT - touch_point.Y); + data->x = touch_point.X; + data->y = touch_point.Y; + g_TouchPadInputSignal = 0; + + read_param->read_length = read_param->size; + ret = EOK; + } + SemReleaseFlag = 0; + } + + return ret; +} + +static uint32 TouchConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + return 0; +} + +struct TouchDevDone touch_dev_done = +{ + .open = TouchOpen, + .close = TouchClose, + .write = NONE, + .read = TouchRead +}; + +static int BoardTouchBusInit(struct TouchBus * touch_bus, struct TouchDriver * touch_driver,const char *bus_name, const char *drv_name) +{ + x_err_t ret = EOK; + + /*Init the touch bus */ + ret = TouchBusInit(touch_bus, bus_name); + if (EOK != ret) { + KPrintf("Board_touch_init touchBusInit error %d\n", ret); + return -ERROR; + } + + /*Init the touch driver*/ + ret = TouchDriverInit(touch_driver, drv_name); + if (EOK != ret){ + KPrintf("Board_touch_init touchDriverInit error %d\n", ret); + return -ERROR; + } + + /*Attach the touch driver to the touch bus*/ + ret = TouchDriverAttachToBus(drv_name, bus_name); + if (EOK != ret){ + KPrintf("Board_touch_init TouchDriverAttachToBus error %d\n", ret); + return -ERROR; + } + + return ret; +} + +/*Attach the touch device to the touch bus*/ +static int BoardTouchDevBend(struct TouchHardwareDevice *touch_device, void *param, const char *bus_name, const char *dev_name) +{ + x_err_t ret = EOK; + + ret = TouchDeviceRegister(touch_device, param, dev_name); + if (EOK != ret){ + KPrintf("TouchDeviceRegister device %s error %d\n", dev_name, ret); + return -ERROR; + } + + ret = TouchDeviceAttachToBus(dev_name, bus_name); + if (EOK != ret) { + KPrintf("TouchDeviceAttachToBus device %s error %d\n", dev_name, ret); + return -ERROR; + } + + return ret; +} + +int HwTouchInit(void) +{ + x_err_t ret = EOK; + + static struct TouchBus touch_bus; + static struct TouchDriver touch_driver; + static struct TouchHardwareDevice touch_dev; + + memset(&touch_bus, 0, sizeof(struct TouchBus)); + memset(&touch_driver, 0, sizeof(struct TouchDriver)); + memset(&touch_dev, 0, sizeof(struct TouchHardwareDevice)); + + touch_driver.configure = TouchConfigure; + + ret = BoardTouchBusInit(&touch_bus, &touch_driver,TOUCH_BUS_NAME,TOUCH_DRV_NAME); + if (EOK != ret) { + return -ERROR; + } + + touch_dev.dev_done = &touch_dev_done; + + ret = BoardTouchDevBend(&touch_dev, NONE, TOUCH_BUS_NAME, TOUCH_DEVICE_NAME); + if (EOK != ret) { + KPrintf("board_touch_Init error ret %u\n", ret); + return -ERROR; + } + + return EOK; +} diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/i2c_touch.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/i2c_touch.c new file mode 100644 index 000000000..52709a5da --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/i2c_touch.c @@ -0,0 +1,360 @@ + +// #include "fsl_debug_console.h" +#include +#include "fsl_iomuxc.h" +#include "pin_mux.h" +#include "fsl_gpio.h" +#include "fsl_lpi2c.h" + +#include "i2c_touch.h" +#include + + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void GTP_I2C_ModeInit(void); + +static void I2C_Master_Callback(LPI2C_Type *base, lpi2c_master_handle_t *handle, status_t status, void *userData); +static uint32_t I2C_Timeout_Callback(uint8_t errorCode); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +lpi2c_master_handle_t g_m_handle; +volatile bool g_MasterCompletionFlag = false; +volatile bool g_TouchPadInputSignal = false; +volatile bool SemReleaseFlag = false; +/******************************************************************************* + * Code + ******************************************************************************/ + +/** + * @brief GT91xxоƬиλ + * @param + * @retval + */ +void GTP_ResetChip(void) +{ + /* ȰRST INTΪģʽ */ + gpio_pin_config_t rst_int_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; + + GPIO_PinInit(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, &rst_int_config); + + /*ʼGT9157,INTΪ͵ƽgt9157豸ַΪ0xBA*/ + + /*λΪ͵ƽΪʼ׼*/ + GPIO_PinWrite(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, 0U); + + //INTóж + rst_int_config.direction = kGPIO_DigitalInput; + rst_int_config.outputLogic = 0; + rst_int_config.interruptMode = kGPIO_IntFallingEdge; + + GPIO_PinInit(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, &rst_int_config); + + /* ʹж */ + GPIO_PortEnableInterrupts(TOUCH_PAD_INT_GPIO, 1U << TOUCH_PAD_INT_GPIO_PIN); +} + +/** +* @brief ֹоƬж +* @param +* @retval +*/ +void GTP_IRQDisable(void) +{ + DisableIRQ(GT9xx_PEN_IRQ); +} + +/** +* @brief ʹܴоƬж +* @param +* @retval +*/ +void GTP_IRQEnable(void) +{ + + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_14_GPIO2_IO30, /* WAKEUP is configured as GPIO5_IO00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_14_GPIO2_IO30, + 0x10B0u); + + + gpio_pin_config_t rst_int_config; + + //INTóж + rst_int_config.direction = kGPIO_DigitalInput; + rst_int_config.outputLogic = 0; + rst_int_config.interruptMode = kGPIO_IntFallingEdge; + + GPIO_PinInit(TOUCH_PAD_INT_GPIO, TOUCH_PAD_INT_GPIO_PIN, &rst_int_config); + + /* ʹж */ + GPIO_PortEnableInterrupts(TOUCH_PAD_INT_GPIO, 1U << TOUCH_PAD_INT_GPIO_PIN); + + /* ʹжIRQ */ + EnableIRQ(GT9xx_PEN_IRQ); +} + + +/** +* @brief ʼоƬʹõI2C +* @param +* @retval +*/ +void GTP_I2C_ModeInit(void) +{ + lpi2c_master_config_t masterConfig; + + /* + * masterConfig.debugEnable = false; + * masterConfig.ignoreAck = false; + * masterConfig.pinConfig = kLPI2C_2PinOpenDrain; + * masterConfig.baudRate_Hz = 100000U; + * masterConfig.busIdleTimeout_ns = 0; + * masterConfig.pinLowTimeout_ns = 0; + * masterConfig.sdaGlitchFilterWidth_ns = 0; + * masterConfig.sclGlitchFilterWidth_ns = 0; + */ + LPI2C_MasterGetDefaultConfig(&masterConfig); + + masterConfig.baudRate_Hz = GTP_I2C_BAUDRATE; + + LPI2C_MasterInit(GTP_I2C_MASTER, &masterConfig, LPI2C_MASTER_CLOCK_FREQUENCY); + + LPI2C_MasterTransferCreateHandle(GTP_I2C_MASTER, &g_m_handle, I2C_Master_Callback, NULL); + +} + +void GtpI2cDeinit(void) +{ + LPI2C_MasterDeinit(GTP_I2C_MASTER); +} + +/** + * @brief ʹIICȡ + * @param + * @arg ClientAddr:豸ַ + * @arg pBuffer:ɴӻȡݵĻָ + * @arg NumByteToRead:ȡݳ + * @retval + */ +uint32_t I2C_ReadBytes(uint8_t ClientAddr,uint8_t* pBuffer, uint16_t NumByteToRead) +{ + lpi2c_master_transfer_t masterXfer = {0}; + status_t reVal = kStatus_Fail; + uint32_t i2c_timeout = I2CT_LONG_TIMEOUT; + + + /* subAddress = 0x00, data = pBuffer Դӻ + ʼźstart + 豸ַslaveaddress(w д) + ӵַsubAddress + + ظʼźrepeated start + 豸ַslaveaddress(r ) + + ջrx data buffer + ֹͣźstop */ + masterXfer.slaveAddress = (ClientAddr>>1); + masterXfer.direction = kLPI2C_Read; + masterXfer.subaddress = (uint32_t)0; + masterXfer.subaddressSize = 0; + masterXfer.data = pBuffer; + masterXfer.dataSize = NumByteToRead; + masterXfer.flags = kLPI2C_TransferDefaultFlag; + + /* λɱ־ */ + g_MasterCompletionFlag = false; + + reVal = LPI2C_MasterTransferNonBlocking(GTP_I2C_MASTER, &g_m_handle, &masterXfer); + if (reVal != kStatus_Success) + { + return 1; + } + + /* ȴ */ + while (!g_MasterCompletionFlag) + { + if((i2c_timeout--) == 0) + return I2C_Timeout_Callback(0); + } + + g_MasterCompletionFlag = false; + + return 0; +} + +/** + * @brief ʹIICд + * @param + * @arg ClientAddr:豸ַ + * @arg pBuffer:ָ + * @arg NumByteToWrite:дֽ + * @retval + */ +uint32_t I2C_WriteBytes(uint8_t ClientAddr,uint8_t* pBuffer, uint8_t NumByteToWrite) +{ + lpi2c_master_transfer_t masterXfer = {0}; + status_t reVal = kStatus_Fail; + uint32_t i2c_timeout = I2CT_LONG_TIMEOUT; + + + /* subAddress = 0x00, data = pBuffer ӻ + ʼźstart + 豸ַslaveaddress(w д) + + ͻtx data buffer + ֹͣźstop */ + + masterXfer.slaveAddress = (ClientAddr>>1); + masterXfer.direction = kLPI2C_Write; + masterXfer.subaddress = (uint32_t)0; + masterXfer.subaddressSize = 0; + masterXfer.data = pBuffer; + masterXfer.dataSize = NumByteToWrite; + masterXfer.flags = kLPI2C_TransferDefaultFlag; + + /* λɱ־ */ + g_MasterCompletionFlag = false; + + reVal = LPI2C_MasterTransferNonBlocking(GTP_I2C_MASTER, &g_m_handle, &masterXfer); + if (reVal != kStatus_Success) + { + return 1; + } + + /* ȴ */ + while (!g_MasterCompletionFlag) + { + if((i2c_timeout--) == 0) + return I2C_Timeout_Callback(1); + } + g_MasterCompletionFlag = false; + + return 0; + +} + +/** + * @brief IICȴʱñϢ + * @param None. + * @retval 0xffʾIICȡʧ + */ +static uint32_t I2C_Timeout_Callback(uint8_t errorCode) +{ + /* Block communication and all processes */ + KPrintf("I2C timeout!errorCode = %d\n",errorCode); + + return 0xFF; +} + +/** +* @brief I2C贫ɵĻص +* @param +* @retval +*/ +static void I2C_Master_Callback(LPI2C_Type *base, lpi2c_master_handle_t *handle, status_t status, void *userData) +{ + /* յkStatus_Success־ + g_MasterCompletionFlag־ɹ */ + if (status == kStatus_Success) + { + g_MasterCompletionFlag = true; + } +} + + + +/** +* @brief żоƬʼ +* @param +* @retval +*/ +void I2C_Touch_Init(void) +{ + +// /* ʼI2C蹤ģʽ */ + GTP_I2C_ModeInit(); + + /* λоƬõַ */ + GTP_ResetChip(); +} + + +/***************************ж******************************/ +/** +* @brief оƬTOUCH_PAD_INT_GPIO_PINŵжϷ +* @param +* @retval +*/ +//void TOUCH_PAD_IRQHANDLER(void) +extern int touch_sem; +void GT9xx_PEN_IRQHandler(int irqn, void *arg) +{ + DisableIRQ(GT9xx_PEN_IRQ); + /* ȷǴоƬж */ + if(GPIO_GetPinsInterruptFlags(TOUCH_PAD_INT_GPIO) & 1U << TOUCH_PAD_INT_GPIO_PIN) + { + /* жϱ־ */ + GPIO_PortClearInterruptFlags(TOUCH_PAD_INT_GPIO, 1U << TOUCH_PAD_INT_GPIO_PIN); + /* л״̬־ */ + g_TouchPadInputSignal = true; + if(!SemReleaseFlag) + { + KSemaphoreAbandon(touch_sem); + SemReleaseFlag = true; + } + } + EnableIRQ(GT9xx_PEN_IRQ); +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +DECLARE_HW_IRQ(GT9xx_PEN_IRQ, GT9xx_PEN_IRQHandler, NONE); + + +/** + * i2c_transfer - execute a single or combined I2C message + * @msgs: One or more messages to execute before STOP is issued to + * terminate the operation; each message begins with a START. + * @num: Number of messages to be executed. + */ +int I2C_Transfer( struct i2c_msg *msgs,int num) +{ + int im = 0; + int ret = 0; + + //GTP_DEBUG_FUNC(); + + for (im = 0; ret == 0 && im != num; im++) + { + if ((msgs[im].flags&I2C_M_RD)) //flagжǶݻд + { + ret = I2C_ReadBytes(msgs[im].addr, msgs[im].buf, msgs[im].len); //IICȡ + } else + { + ret = I2C_WriteBytes(msgs[im].addr, msgs[im].buf, msgs[im].len); //IICд + } + } + + if(ret) + return ret; + + return im; //ɵĴṹ +} + + + + + + + + + + + + +/*********************************************END OF FILE**********************/ diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/i2c_touch.h b/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/i2c_touch.h new file mode 100644 index 000000000..24759ba03 --- /dev/null +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/touch/i2c_touch.h @@ -0,0 +1,67 @@ +#ifndef __I2C_TOUCH_H +#define __I2C_TOUCH_H + +#include "fsl_common.h" +#include "fsl_lpi2c.h" +#include "board.h" +#include +extern lpi2c_master_handle_t g_m_handle; +extern volatile bool g_MasterCompletionFlag ; +extern volatile bool g_TouchPadInputSignal; +extern volatile bool SemReleaseFlag; + + + +/* Select USB1 PLL (480 MHz) as master lpi2c clock source */ +#define LPI2C_CLOCK_SOURCE_SELECT (0U) +/* Clock divider for master lpi2c clock source */ +#define LPI2C_CLOCK_SOURCE_DIVIDER (5U) +/* Get frequency of lpi2c clock */ +#define LPI2C_CLOCK_FREQUENCY ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U)) + +#define LPI2C_MASTER_CLOCK_FREQUENCY LPI2C_CLOCK_FREQUENCY + +#define GTP_I2C_MASTER_BASE (LPI2C1_BASE) +#define GTP_I2C_MASTER ((LPI2C_Type *)GTP_I2C_MASTER_BASE) + +#define GTP_I2C_BAUDRATE 400000U + +/* ȴʱʱ */ +#define I2CT_FLAG_TIMEOUT ((uint32_t)0x10000) +#define I2CT_LONG_TIMEOUT ((uint32_t)(10 * I2CT_FLAG_TIMEOUT)) + + +/*! @brief оƬŶ */ + +#define TOUCH_PAD_SCL_IOMUXC IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL +#define TOUCH_PAD_SDA_IOMUXC IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA + + +#define TOUCH_PAD_RST_GPIO GPIO1 +#define TOUCH_PAD_RST_GPIO_PIN (27U) +#define TOUCH_PAD_RST_IOMUXC IOMUXC_GPIO_AD_B1_11_GPIO1_IO27//IOMUXC_GPIO_AD_B1_11_GPIO1_IO27 + +#define TOUCH_PAD_INT_GPIO GPIO2 +#define TOUCH_PAD_INT_GPIO_PIN (30U) +#define TOUCH_PAD_INT_IOMUXC IOMUXC_GPIO_AD_B0_11_GPIO1_IO11 + +#define GT9xx_PEN_IRQ GPIO2_Combined_16_31_IRQn +#define GT9xx_PEN_IRQHandler GPIO2_Combined_16_31_IRQHandler + + + +//ӿ +int32_t GTP_I2C_ReadBytes(uint8_t client_addr, uint8_t *buf, int32_t len); + +void I2C_Touch_Init(void); +void GtpI2cDeinit(void); +uint32_t I2C_WriteBytes(uint8_t ClientAddr,uint8_t* pBuffer, uint8_t NumByteToWrite); +uint32_t I2C_ReadBytes(uint8_t ClientAddr,uint8_t* pBuffer, uint16_t NumByteToRead); +void GTP_ResetChip(void); +void GTP_IRQDisable(void); +void GTP_IRQEnable(void); +int I2C_Transfer( struct i2c_msg *msgs,int num); + + + +#endif /* __I2C_TOUCH_H */ diff --git a/Ubiquitous/XiZi/kernel/thread/msgqueue.c b/Ubiquitous/XiZi/kernel/thread/msgqueue.c index 950a265ac..8d2be3c79 100644 --- a/Ubiquitous/XiZi/kernel/thread/msgqueue.c +++ b/Ubiquitous/XiZi/kernel/thread/msgqueue.c @@ -96,7 +96,6 @@ static x_err_t _MsgQueueSend(struct MsgQueue *mq, tick_delta = 0; task = GetKTaskDescriptor(); - if(WAITING_FOREVER == msec) timeout = WAITING_FOREVER; else diff --git a/Ubiquitous/XiZi/kernel/thread/semaphore.c b/Ubiquitous/XiZi/kernel/thread/semaphore.c index 935f1f72b..ac6f6eeb3 100644 --- a/Ubiquitous/XiZi/kernel/thread/semaphore.c +++ b/Ubiquitous/XiZi/kernel/thread/semaphore.c @@ -94,12 +94,10 @@ static int32 _SemaphoreObtain(struct Semaphore *sem, int32 msec) struct TaskDescriptor *task = NONE; NULL_PARAM_CHECK(sem); - if(WAITING_FOREVER == msec) wait_time = WAITING_FOREVER; else wait_time = CalculteTickFromTimeMs(msec); - lock = CriticalAreaLock(); SYS_KDEBUG_LOG(KDBG_IPC, ("obtain semaphore: id %d, value %d, by task %s\n",