diff --git a/.gitmodules b/.gitmodules index d882a1488..dcc3b8dd1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [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 diff --git a/APP_Framework/Applications/control_app/opcua_demo/opcua_demo.c b/APP_Framework/Applications/control_app/opcua_demo/opcua_demo.c index e1edcf29a..6cabf185c 100755 --- a/APP_Framework/Applications/control_app/opcua_demo/opcua_demo.c +++ b/APP_Framework/Applications/control_app/opcua_demo/opcua_demo.c @@ -21,7 +21,6 @@ #include #include #include "board.h" -#include #include "open62541.h" #include "ua_api.h" @@ -40,6 +39,9 @@ /******************************************************************************* * Variables ******************************************************************************/ +// to count test +static int test_cnt = 0; +static int fail_cnt = 0; // count failure times char test_ua_ip[] = {192, 168, 250, 2}; @@ -50,37 +52,56 @@ char test_ua_ip[] = {192, 168, 250, 2}; static void UaConnectTestTask(void* arg) { struct netif net; - UA_StatusCode retval; - char ua_uri[UA_URL_SIZE]; - memset(ua_uri, 0, sizeof(ua_uri)); + UA_StatusCode ret; + char url[UA_URL_SIZE]; + memset(url, 0, sizeof(url)); + UA_Client* client = UA_Client_new(); if(client == NULL) { - ua_print("ua: [%s] tcp client null\n", __func__); + ua_error("ua: [%s] tcp client null\n", __func__); return; } UA_ClientConfig* config = UA_Client_getConfig(client); - UA_ClientConfig_setDefault(config); - snprintf(ua_uri, sizeof(ua_uri), "opc.tcp://%d.%d.%d.%d:4840", - test_ua_ip[0], test_ua_ip[1], test_ua_ip[2], test_ua_ip[3]); - ua_notice("ua uri: %d %s\n", strlen(ua_uri), ua_uri); - retval = UA_Client_connect(client,ua_uri); - if(retval != UA_STATUSCODE_GOOD) + UA_ClientConfig_setDefault(config); + + snprintf(url, sizeof(url), "opc.tcp://%d.%d.%d.%d:4840", + test_ua_ip[0], test_ua_ip[1], test_ua_ip[2], test_ua_ip[3]); + + ua_notice("ua connect cnt %d fail %d\n", test_cnt++, fail_cnt ++); + ua_notice("ua connect uri: %.*s\n", strlen(url), url); + + ret = UA_Client_connect(client, url); + + if(ret != UA_STATUSCODE_GOOD) { - ua_notice("ua: [%s] connected failed %x\n", __func__, retval); + ua_error("ua: [%s] connected failed %x\n", __func__, ret); UA_Client_delete(client); + fail_cnt++; return; } - ua_notice("ua: [%s] connected ok!\n", __func__); + ua_notice("ua connected ok!\n"); UA_Client_delete(client); } -void UaConnectTest(void* arg) +static void UaConnectTest(int argc, char *argv[]) { + if(argc == 2) + { + if(isdigit(argv[1][0])) + { + if(sscanf(argv[1], "%d.%d.%d.%d", &test_ua_ip[0], &test_ua_ip[1], &test_ua_ip[2], &test_ua_ip[3]) == EOF) + { + lw_notice("input wrong ip\n"); + return; + } + } + } + lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip); sys_thread_new("ua test", UaConnectTestTask, NULL, UA_STACK_SIZE, UA_TASK_PRIO); } @@ -90,10 +111,10 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | void UaBrowserObjectsTestTask(void* param) { - static int test_cnt = 0; - UA_Client* client = UA_Client_new(); ua_notice("ua: [%s] start %d ...\n", __func__, test_cnt++); + UA_Client* client = UA_Client_new(); + if(client == NULL) { ua_error("ua: [%s] tcp client NULL\n", __func__); @@ -102,25 +123,26 @@ void UaBrowserObjectsTestTask(void* param) UA_ClientConfig* config = UA_Client_getConfig(client); UA_ClientConfig_setDefault(config); - UA_StatusCode retval = UA_Client_connect(client, opc_server_url); + UA_StatusCode ret = UA_Client_connect(client, opc_server_url); - if(retval != UA_STATUSCODE_GOOD) + if(ret != UA_STATUSCODE_GOOD) { - ua_error("ua: [%s] connect failed %#x\n", __func__, retval); + ua_error("ua: [%s] connect failed %#x\n", __func__, ret); UA_Client_delete(client); return; } ua_notice("--- start read time ---\n", __func__); - ua_read_time(client); + UaGetServerTime(client); + ua_notice("--- get server info ---\n", __func__); - ua_test_browser_objects(client); + UaTestBrowserObjects(client); /* Clean up */ UA_Client_delete(client); /* Disconnects the client internally */ } -void* UaBrowserObjectsTest(int argc, char* argv[]) +static void* UaBrowserObjectsTest(int argc, char* argv[]) { if(argc == 2) { @@ -140,35 +162,33 @@ void* UaBrowserObjectsTest(int argc, char* argv[]) } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), - UaObj, UaBrowserObjectsTest, UaObj [IP]); + UaObject, UaBrowserObjectsTest, UaObject [IP]); void UaGetInfoTestTask(void* param) { UA_Client* client = UA_Client_new(); - ua_notice("ua: [%s] start ...\n", __func__); + ua_notice("--- Get OPUCA objects ---\n", __func__); if(client == NULL) { - ua_print("ua: [%s] tcp client null\n", __func__); + ua_error("ua: [%s] tcp client null\n", __func__); return; } UA_ClientConfig* config = UA_Client_getConfig(client); UA_ClientConfig_setDefault(config); - UA_StatusCode retval = UA_Client_connect(client, opc_server_url); + UA_StatusCode ret = UA_Client_connect(client, opc_server_url); - if(retval != UA_STATUSCODE_GOOD) + if(ret != UA_STATUSCODE_GOOD) { - ua_print("ua: [%s] connect failed %#x\n", __func__, retval); + ua_error("ua: [%s] connect failed %#x\n", __func__, ret); UA_Client_delete(client); return; } - ua_print("ua: [%s] connect ok!\n", __func__); ua_notice("--- interactive server ---\n", __func__); - ua_test_interact_server(client); - /* Clean up */ - UA_Client_disconnect(client); + UaTestInteractServer(client); + UA_Client_delete(client); /* Disconnects the client internally */ } @@ -201,26 +221,24 @@ void UaAddNodesTask(void* param) if(client == NULL) { - ua_print("ua: [%s] tcp client null\n", __func__); + ua_error("ua: [%s] client null\n", __func__); return; } UA_ClientConfig* config = UA_Client_getConfig(client); UA_ClientConfig_setDefault(config); - UA_StatusCode retval = UA_Client_connect(client, opc_server_url); + UA_StatusCode ret = UA_Client_connect(client, opc_server_url); - if(retval != UA_STATUSCODE_GOOD) + if(ret != UA_STATUSCODE_GOOD) { - ua_print("ua: [%s] connect failed %#x\n", __func__, retval); + ua_print("ua: [%s] connect failed %#x\n", __func__, ret); UA_Client_delete(client); return; } - ua_print("ua: [%s] connect ok!\n", __func__); ua_notice("--- add nodes ---\n", __func__); - ua_add_nodes(client); - /* Clean up */ - UA_Client_disconnect(client); + UaAddNodes(client); + UA_Client_delete(client); /* Disconnects the client internally */ } diff --git a/APP_Framework/Applications/control_app/plc_demo/plc_control_demo.c b/APP_Framework/Applications/control_app/plc_demo/plc_control_demo.c index 64cb7d913..fed4063bf 100755 --- a/APP_Framework/Applications/control_app/plc_demo/plc_control_demo.c +++ b/APP_Framework/Applications/control_app/plc_demo/plc_control_demo.c @@ -30,12 +30,49 @@ struct PlcChannel plc_demo_ch; struct PlcDriver plc_demo_drv; struct PlcDevice plc_demo_dev; +int plc_test_flag = 0; + PlcCtrlParamType plc_ctrl_param; UA_NodeId test_nodeid = {4, UA_NODEIDTYPE_NUMERIC, 5}; /******************************************************************************/ +void PlcDelay(int sec) +{ + volatile uint32_t i = 0; + for (i = 0; i < 100000000 * sec; ++i) + { + __asm("NOP"); /* delay */ + } +} + +// get NodeId from str +void PlcGetTestNodeId(char *str, UA_NodeId *id) +{ + static char node_str[UA_NODE_LEN]; + memset(node_str, 0, sizeof(node_str)); + + plc_print("plc: arg %s\n", str); + + if(sscanf(str, PLC_NS_FORMAT, &id->namespaceIndex, node_str) != EOF) + { + if(isdigit(node_str[0])) + { + id->identifierType = UA_NODEIDTYPE_NUMERIC; + id->identifier.numeric = atoi(node_str); + plc_print("ns %d num %d\n", id->namespaceIndex, id->identifier.numeric); + } + else + { + id->identifierType = UA_NODEIDTYPE_STRING; + id->identifier.string.length = strlen(node_str); + id->identifier.string.data = node_str; + plc_print("ns %d str %s\n", id->namespaceIndex, id->identifier.string.data); + } + } +} + void PlcDemoChannelDrvInit(void) { static uint8_t init_flag = 0; @@ -52,33 +89,42 @@ void PlcDemoChannelDrvInit(void) memset(&plc_demo_dev, 0, sizeof(plc_demo_dev)); } +static void PlcGetDemoDev(PlcDeviceType *dev, UA_NodeId *id) +{ + // register plc device + dev->state = CHDEV_INIT; + strcpy(dev->name, "UA Demo"); + dev->info.product = "CPU 1215C"; + dev->info.vendor = "SIEMENS"; + dev->info.model = "S7-1200"; + dev->info.id = 123; + dev->net = PLC_IND_ENET_OPCUA; + + // register UA parameter + if(!dev->priv_data) + { + dev->priv_data = (UaParamType*)malloc(sizeof(UaParamType)); + } + UaParamType* ua_ptr = dev->priv_data; + memset(ua_ptr, 0, sizeof(UaParamType)); + strcpy(ua_ptr->ua_remote_ip, opc_server_url); + ua_ptr->act = UA_ACT_ATTR; + memcpy(&ua_ptr->ua_id, id, sizeof(*id)); +} + static void PlcCtrlDemoInit(void) { static uint8_t init_flag = 0; PlcDemoChannelDrvInit(); - // register plc device - plc_demo_dev.state = CHDEV_INIT; - strcpy(plc_demo_dev.name, "UA Demo"); - plc_demo_dev.info.product = "CPU 1215C"; - plc_demo_dev.info.vendor = "SIEMENS"; - plc_demo_dev.info.model = "S7-1200"; - plc_demo_dev.info.id = 123; - plc_demo_dev.net = PLC_IND_ENET_OPCUA; - // register UA parameter - if(!plc_demo_dev.priv_data) - { - plc_demo_dev.priv_data = (UaParamType*)malloc(sizeof(UaParamType)); - } - UaParamType* ua_ptr = plc_demo_dev.priv_data; - memset(ua_ptr, 0, sizeof(UaParamType)); - strcpy(ua_ptr->ua_remote_ip, opc_server_url); - ua_ptr->act = UA_ACT_ATTR; - memcpy(&ua_ptr->ua_id, &test_nodeid, sizeof(test_nodeid)); + // register plc device + PlcGetDemoDev(&plc_demo_dev, &test_nodeid); if(init_flag) + { return; + } init_flag = 1; if(PlcDevRegister(&plc_demo_dev, NULL, plc_demo_dev.name) != EOK) @@ -114,38 +160,21 @@ void PlcReadUATask(void* arg) ops->close(&plc_demo_dev); } -void PlcReadTest(int argc, char* argv[]) +void PlcReadTestShell(int argc, char* argv[]) { static char node_str[UA_NODE_LEN]; memset(node_str, 0, sizeof(node_str)); if(argc > 1) { - plc_print("plc: arg %s\n", argv[1]); - - if(sscanf(argv[1], PLC_NS_FORMAT, &test_nodeid.namespaceIndex, node_str) != EOF) - { - if(isdigit(node_str[0])) - { - test_nodeid.identifierType = UA_NODEIDTYPE_NUMERIC; - test_nodeid.identifier.numeric = atoi(node_str); - plc_print("ns %d num %d\n", test_nodeid.namespaceIndex, test_nodeid.identifier.numeric); - } - else - { - test_nodeid.identifierType = UA_NODEIDTYPE_STRING; - test_nodeid.identifier.string.length = strlen(node_str); - test_nodeid.identifier.string.data = node_str; - plc_print("ns %d str %s\n", test_nodeid.namespaceIndex, test_nodeid.identifier.string.data); - } - } + PlcGetTestNodeId(argv[1], &test_nodeid); } sys_thread_new("plc read", PlcReadUATask, NULL, PLC_STACK_SIZE, PLC_TASK_PRIO); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), - PlcRead, PlcReadTest, Read PLC); + PlcRead, PlcReadTestShell, Read PLC); void PlcWriteUATask(void* arg) { @@ -168,13 +197,13 @@ void PlcWriteUATask(void* arg) if(EOK != ret) { - plc_print("plc: [%s] read failed\n", __func__); + plc_print("plc: [%s] write failed\n", __func__); } ops->close(&plc_demo_dev); } -void PlcWriteTest(int argc, char* argv[]) +void PlcWriteTestShell(int argc, char* argv[]) { static char node_str[UA_NODE_LEN]; static char val_param[UA_NODE_LEN]; @@ -183,35 +212,143 @@ void PlcWriteTest(int argc, char* argv[]) if(argc > 1) { - plc_print("plc: arg %s\n", argv[1]); + PlcGetTestNodeId(argv[1], &test_nodeid); + } - if(sscanf(argv[1], PLC_NS_FORMAT, &test_nodeid.namespaceIndex, node_str) != EOF) - { - if(isdigit(node_str[0])) - { - test_nodeid.identifierType = UA_NODEIDTYPE_NUMERIC; - test_nodeid.identifier.numeric = atoi(node_str); - plc_print("ns %d num %d\n", test_nodeid.namespaceIndex, test_nodeid.identifier.numeric); - } - else - { - test_nodeid.identifierType = UA_NODEIDTYPE_STRING; - test_nodeid.identifier.string.length = strlen(node_str); - test_nodeid.identifier.string.data = node_str; - plc_print("ns %d str %s\n", test_nodeid.namespaceIndex, test_nodeid.identifier.string.data); - } - } - - if(argc > 2) - { - strcpy(val_param, argv[2]); - plc_print("write value %s\n", val_param); - } + if(argc > 2) + { + strcpy(val_param, argv[2]); + plc_print("write value %s\n", val_param); } sys_thread_new("plc write", PlcWriteUATask, val_param, PLC_STACK_SIZE, PLC_TASK_PRIO); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), - PlcWrite, PlcWriteTest, Read PLC); + PlcWrite, PlcWriteTestShell, Read PLC); + +// test motor +// clear parameter +// PlcWrite n4,2 0b +// PlcWrite n4,3 0b +// PlcWrite n4,4 0b +// PlcWrite n4,5 0b +// +// enable +// PlcWrite n4,2 1b +// +// set rotate speed +// PlcWrite n4,3 50 +// +// positive turn +// PlcWrite n4,4 1b +// +// reversal turn +// PlcWrite n4,5 1b + +static int plc_test_speed = 50; +static int plc_test_dir = 1; // direction positive: 1 reversal: 0 + +void PlcMotorTestTask(void* arg) +{ + //support node id + char *test_nodeid[] = {"n4,2", "n4,3", "n4,4", "n4,5", "n4,7"}; + // enable -> speed -> positive dir or inversal dir -> stop -> enable + char test_sort[] = {0, 4, 2, 1, 0}; + char test_cmd[][4] = {"1b", "50", "1b", "1b", "0b"}; + char *test_notice[] = {"Enable Motor", "Set Speed", "Set Forward", "Set Reverse", "Stop Motor"}; + + int ret = 0; + struct PlcOps* ops = NULL; + char buf[PLC_BUF_SIZE]; + memset(buf, 0, sizeof(buf)); + + PlcCtrlDemoInit(); + ops = plc_demo_dev.ops; + ret = ops->open(&plc_demo_dev); + + if(EOK != ret) + { + plc_print("plc: [%s] open failed %#x\n", __func__, ret); + return; + } + + UaParamType* ua_ptr = plc_demo_dev.priv_data; + + // initialize step + for(int i = 0; i < 5; i++) + { + plc_print("###\n### Clear %s\n###\n", test_notice[i]); + PlcGetTestNodeId(test_nodeid[i], &ua_ptr->ua_id); + ret = ops->write(&plc_demo_dev, "0b", PLC_BUF_SIZE); + if(EOK != ret) + { + plc_print("plc: [%s] %d write failed\n", __func__, __LINE__); + } + PlcDelay(1); + } + + if(plc_test_speed != 50) + { + snprintf(test_cmd[1], 4, "%d", plc_test_speed); + } + + if(plc_test_dir == 0) // if not postive, next running + test_sort[2] = 3; + + for(int i = 0; i < sizeof(test_sort)/sizeof(test_sort[0]); i++) + { + PlcGetTestNodeId(test_nodeid[test_sort[i]], &ua_ptr->ua_id); + plc_print("###\n### %s\n###\n", test_notice[i]); + ret = ops->write(&plc_demo_dev, test_cmd[i], PLC_BUF_SIZE); + if(EOK != ret) + { + plc_print("plc: [%s] %d write failed\n", __func__, __LINE__); + } + PlcDelay(1); + if(i == 2) // postive + { + PlcDelay(10); + } + } + ops->close(&plc_demo_dev); + plc_test_flag = 0; +} + +// get parameter from +void PlcGetMotorParam(char *str) +{ + static char node_str[UA_NODE_LEN]; + memset(node_str, 0, sizeof(node_str)); + + plc_print("plc: arg %s\n", str); + + sscanf(str, "speed=%d", &plc_test_speed); + sscanf(str, "dir=%d", &plc_test_dir); + plc_print("speed is %d\n", plc_test_speed); + plc_print("dir is %d\n", plc_test_dir); +} + +void PlcMotorTestShell(int argc, char* argv[]) +{ + if(plc_test_flag) + { + plc_print("PLC Motor testing!\n"); + return; + } + plc_test_flag = 1; + + if(argc > 1) + { + for(int i = 0; i < argc; i++) + { + PlcGetMotorParam(argv[i]); + } + } + + sys_thread_new("plc motor", PlcMotorTestTask, NULL, PLC_STACK_SIZE, PLC_TASK_PRIO); +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), + PlcMotorTest, PlcMotorTestShell, Run motor); diff --git a/APP_Framework/Applications/sensor_app/pm10_0_ps5308.c b/APP_Framework/Applications/sensor_app/pm10_0_ps5308.c index 7b1559d16..5d6408808 100644 --- a/APP_Framework/Applications/sensor_app/pm10_0_ps5308.c +++ b/APP_Framework/Applications/sensor_app/pm10_0_ps5308.c @@ -11,7 +11,7 @@ */ /** - * @filepm10_0_ps5308 + * @file pm10_0_ps5308.c * @brief PS5308 PM10.0 example * @version 1.0 * @author AIIT XUOS Lab diff --git a/APP_Framework/Applications/sensor_app/pm2_5_ps5308.c b/APP_Framework/Applications/sensor_app/pm2_5_ps5308.c index a2de9ee31..23aaca509 100644 --- a/APP_Framework/Applications/sensor_app/pm2_5_ps5308.c +++ b/APP_Framework/Applications/sensor_app/pm2_5_ps5308.c @@ -11,7 +11,7 @@ */ /** - * @file pm2_5_ps5308 + * @file pm2_5_ps5308.c * @brief PS5308 PM2.5 example * @version 1.0 * @author AIIT XUOS Lab diff --git a/APP_Framework/Framework/connection/Kconfig b/APP_Framework/Framework/connection/Kconfig index ea22c5fb2..43094d28f 100644 --- a/APP_Framework/Framework/connection/Kconfig +++ b/APP_Framework/Framework/connection/Kconfig @@ -62,12 +62,6 @@ if SUPPORT_CONNECTION_FRAMEWORK default n if CONNECTION_ADAPTER_ETHERNET source "$APP_DIR/Framework/connection/ethernet/Kconfig" - config CONNECTION_ADAPTER_ETHERCAT - bool "Using ethercat on ethernet adapter device" - default n - if CONNECTION_ADAPTER_ETHERCAT - source "$APP_DIR/Framework/connection/ethercat/Kconfig" - endif endif menuconfig CONNECTION_ADAPTER_BLUETOOTH diff --git a/APP_Framework/Framework/connection/Makefile b/APP_Framework/Framework/connection/Makefile index b9afa159a..01b5b6eaa 100644 --- a/APP_Framework/Framework/connection/Makefile +++ b/APP_Framework/Framework/connection/Makefile @@ -41,10 +41,6 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_DIR += ethernet endif - ifeq ($(CONFIG_CONNECTION_ADAPTER_ETHERCAT),y) - SRC_DIR += ethercat - endif - ifeq ($(CONFIG_CONNECTION_ADAPTER_BLUETOOTH),y) SRC_DIR += bluetooth endif diff --git a/APP_Framework/Framework/connection/industrial_ethernet/Kconfig b/APP_Framework/Framework/connection/industrial_ethernet/Kconfig index e69de29bb..0826acf22 100644 --- a/APP_Framework/Framework/connection/industrial_ethernet/Kconfig +++ b/APP_Framework/Framework/connection/industrial_ethernet/Kconfig @@ -0,0 +1,7 @@ +config CONNECTION_ADAPTER_ETHERCAT + bool "Using ethercat on industrial_ethernet adapter device" + default n + + if CONNECTION_ADAPTER_ETHERCAT + source "$APP_DIR/Framework/connection/industrial_ethernet/ethercat/Kconfig" + endif diff --git a/APP_Framework/Framework/connection/industrial_ethernet/Makefile b/APP_Framework/Framework/connection/industrial_ethernet/Makefile index 98aa92bfb..e9ec8be90 100644 --- a/APP_Framework/Framework/connection/industrial_ethernet/Makefile +++ b/APP_Framework/Framework/connection/industrial_ethernet/Makefile @@ -1,2 +1,5 @@ +ifeq ($(CONFIG_CONNECTION_ADAPTER_ETHERCAT),y) + SRC_DIR += ethercat +endif include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/Framework/connection/ethercat/Kconfig b/APP_Framework/Framework/connection/industrial_ethernet/ethercat/Kconfig similarity index 72% rename from APP_Framework/Framework/connection/ethercat/Kconfig rename to APP_Framework/Framework/connection/industrial_ethernet/ethercat/Kconfig index 0193e6a80..b294c337a 100644 --- a/APP_Framework/Framework/connection/ethercat/Kconfig +++ b/APP_Framework/Framework/connection/industrial_ethernet/ethercat/Kconfig @@ -5,6 +5,7 @@ config ADAPTER_HFA21_ETHERCAT bool "Using ethercat on ethernet adapter device HFA21" default n -if ADAPTER_HFA21_ETHERCAT - source "$APP_DIR/Framework/connection/ethercat/hfa21_ethercat/Kconfig" -endif + if ADAPTER_HFA21_ETHERCAT + source "$APP_DIR/Framework/connection/industrial_ethernet/ethercat/hfa21_ethercat/Kconfig" + endif + diff --git a/APP_Framework/Framework/connection/ethercat/Makefile b/APP_Framework/Framework/connection/industrial_ethernet/ethercat/Makefile similarity index 100% rename from APP_Framework/Framework/connection/ethercat/Makefile rename to APP_Framework/Framework/connection/industrial_ethernet/ethercat/Makefile diff --git a/APP_Framework/Framework/connection/ethercat/adapter_ethercat.c b/APP_Framework/Framework/connection/industrial_ethernet/ethercat/adapter_ethercat.c similarity index 100% rename from APP_Framework/Framework/connection/ethercat/adapter_ethercat.c rename to APP_Framework/Framework/connection/industrial_ethernet/ethercat/adapter_ethercat.c diff --git a/APP_Framework/Framework/connection/ethercat/ethercat.h b/APP_Framework/Framework/connection/industrial_ethernet/ethercat/ethercat.h similarity index 100% rename from APP_Framework/Framework/connection/ethercat/ethercat.h rename to APP_Framework/Framework/connection/industrial_ethernet/ethercat/ethercat.h diff --git a/APP_Framework/Framework/connection/ethercat/hfa21_ethercat/Kconfig b/APP_Framework/Framework/connection/industrial_ethernet/ethercat/hfa21_ethercat/Kconfig similarity index 100% rename from APP_Framework/Framework/connection/ethercat/hfa21_ethercat/Kconfig rename to APP_Framework/Framework/connection/industrial_ethernet/ethercat/hfa21_ethercat/Kconfig diff --git a/APP_Framework/Framework/connection/ethercat/hfa21_ethercat/Makefile b/APP_Framework/Framework/connection/industrial_ethernet/ethercat/hfa21_ethercat/Makefile similarity index 100% rename from APP_Framework/Framework/connection/ethercat/hfa21_ethercat/Makefile rename to APP_Framework/Framework/connection/industrial_ethernet/ethercat/hfa21_ethercat/Makefile diff --git a/APP_Framework/Framework/connection/ethercat/hfa21_ethercat/hfa21_ethercat.c b/APP_Framework/Framework/connection/industrial_ethernet/ethercat/hfa21_ethercat/hfa21_ethercat.c similarity index 100% rename from APP_Framework/Framework/connection/ethercat/hfa21_ethercat/hfa21_ethercat.c rename to APP_Framework/Framework/connection/industrial_ethernet/ethercat/hfa21_ethercat/hfa21_ethercat.c diff --git a/APP_Framework/Framework/control/plc/interoperability/opcua/open62541.c b/APP_Framework/Framework/control/plc/interoperability/opcua/open62541.c index fc525aa8d..fd3507a01 100755 --- a/APP_Framework/Framework/control/plc/interoperability/opcua/open62541.c +++ b/APP_Framework/Framework/control/plc/interoperability/opcua/open62541.c @@ -23,6 +23,19 @@ * @date 2021.12.15 */ +/************************************************* +File name: open62541.c +Description: Support OPCUA protocol +Others: take https://github.com/open62541/open62541.git +History: +1. Date: 2021-12-15 +Author: AIIT XUOS Lab +Modification: +1. added debug information for locate +2. avoid calling client NEW at same time +3. fixed the bug of free twice when receiveResponse timeout +*************************************************/ + #ifndef UA_DYNAMIC_LINKING_EXPORT # define UA_DYNAMIC_LINKING_EXPORT # define MDNSD_DYNAMIC_LINKING @@ -36,6 +49,8 @@ #include "open62541.h" #include "ua_api.h" +int ua_run_flag = 0; + #if LWIP_DNS #else @@ -7482,10 +7497,6 @@ Array_encodeBinary(const void *src, size_t length, const UA_DataType *type, Ctx } UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); - //tst by wly - ua_debug("ua: [%s] src %p len %d %d type %p <%d> <%d> %p ret %d\n", __func__, - src, length, signed_length, *type, type->typeKind, type->overlayable, ctx, ret); - return ret; } @@ -8330,24 +8341,9 @@ encodeBinaryStruct(const void *src, const UA_DataType *type, Ctx *ctx) { if(mt->typeKind > UA_DATATYPEKINDS) { - ua_debug("ua: [%s] %d type %d %p ptr %p failed\n", __func__, i, mt->typeKind, m->memberType, ptr); return ret; } - ua_debug("ua: [%s] > %d < %d mt %p %d %d dep %d msg %p %p:<%x> <%d> isArry %d ret %d\n", __func__, - i, - type->membersSize, - mt, - mt->typeKind, - mt->memSize, - ctx->depth, - ptr, - src, - ((UA_TcpMessageHeader *)src)->messageTypeAndChunkType, - ((UA_TcpMessageHeader *)src)->messageSize, - m->isArray, - ret); - /* Array. Buffer-exchange is done inside Array_encodeBinary if required. */ if(m->isArray) { const size_t length = *((const size_t*)ptr); @@ -8362,20 +8358,6 @@ encodeBinaryStruct(const void *src, const UA_DataType *type, Ctx *ctx) { ret = encodeWithExchangeBuffer((const void*)ptr, mt, ctx); UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); - ua_debug("ua: [%s] >> %d < %d mt %p %d %d dep %d msg %p %p:<%x> <%d> isArry %d ret %d\n", __func__, - i, - type->membersSize, - mt, - mt->typeKind, - mt->memSize, - ctx->depth, - ptr, - src, - ((UA_TcpMessageHeader *)src)->messageTypeAndChunkType, - ((UA_TcpMessageHeader *)src)->messageSize, - m->isArray, - ret); - ptr += mt->memSize; } @@ -8614,68 +8596,23 @@ decodeBinaryStructure(void *dst, const UA_DataType *type, Ctx *ctx) { if(mt->typeKind >= UA_DATATYPEKINDS) { - ua_debug("ua: [%s] fail %d < %d mt %p %d %d dep %d msg %p %p:<%x> <%d>\n", __func__, - i, - membersSize, - mt, - mt->typeKind, - mt->memSize, - ctx->depth, - ptr, - dst, - ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, - ((UA_TcpMessageHeader *)dst)->messageSize); - return ret; } - ua_debug("ua: [%s] > %d < %d mt %p %d %d dep %d msg %p %p:<%x> <%d> isArry %d ret %d\n", __func__, - i, - membersSize, - mt, - mt->typeKind, - mt->memSize, - ctx->depth, - ptr, - dst, - ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, - ((UA_TcpMessageHeader *)dst)->messageSize, - m->isArray, - ret); - /* Array */ if(m->isArray) { size_t *length = (size_t*)ptr; ptr += sizeof(size_t); ret = Array_decodeBinary((void *UA_RESTRICT *UA_RESTRICT)ptr, length, mt , ctx); ptr += sizeof(void*); - ua_debug("ua: [%s] %d ret %d ptr %p len %d\n", __func__, i, ret, ptr, length); continue; } /* Scalar */ ret = decodeBinaryJumpTable[mt->typeKind]((void *UA_RESTRICT)ptr, mt, ctx); ptr += mt->memSize; - - ua_debug("ua: [%s] >> %d < %d dep %d msg %p %p:<%x> <%d> ret %d\n", __func__, - i, - membersSize, - ctx->depth, - ptr, - dst, - ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, - ((UA_TcpMessageHeader *)dst)->messageSize, - ret); } - ua_debug("ua: [%s] >>> dep %d msg %p %p:<%x> <%d> ret %d\n", __func__, - ctx->depth, - ptr, - dst, - ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, - ((UA_TcpMessageHeader *)dst)->messageSize, - ret); - ctx->depth--; return ret; } @@ -8818,17 +8755,8 @@ UA_decodeBinaryInternal(const UA_ByteString *src, size_t *offset, /* Decode */ memset(dst, 0, type->memSize); /* Initialize the value */ - ua_debug("ua: [%s] t %d mem %d len %d off %d pos %d end %d dst %p type %x size %x\n", __func__, - type->typeKind, type->memSize, src->length, *offset, *ctx.pos, *ctx.end, - dst, ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, - ((UA_TcpMessageHeader *)dst)->messageSize); - status ret = decodeBinaryJumpTable[type->typeKind](dst, type, &ctx); - ua_debug("ua: [%s] -> t %d dst %p type %x size %x ret %d\n", __func__, - type->typeKind, dst, ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, - ((UA_TcpMessageHeader *)dst)->messageSize, ret); - if(UA_LIKELY(ret == UA_STATUSCODE_GOOD)) { /* Set the new offset */ *offset = (size_t)(ctx.pos - src->data) / sizeof(u8); @@ -8836,16 +8764,8 @@ UA_decodeBinaryInternal(const UA_ByteString *src, size_t *offset, /* Clean up */ UA_clear(dst, type); memset(dst, 0, type->memSize); - - ua_debug("ua: [%s] => t %d dst %p type %x size %x\n", __func__, - type->typeKind, dst, ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, - ((UA_TcpMessageHeader *)dst)->messageSize); } - ua_debug("ua: [%s] #> off %d %p %p t %d dst %p type %x size %x\n", __func__, *offset, - ctx.pos, src->data, - type->typeKind, dst, ((UA_TcpMessageHeader *)dst)->messageTypeAndChunkType, - ((UA_TcpMessageHeader *)dst)->messageSize); return ret; } @@ -17969,6 +17889,11 @@ UA_SecureChannel_close(UA_SecureChannel *channel) { /* Set the status to closed */ channel->state = UA_SECURECHANNELSTATE_CLOSED; + if(channel->connection == 0) + { + ua_error("ua: [%s] conn null return!\n", __func__); + return; + } /* Detach from the connection and close the connection */ if(channel->connection) { if(channel->connection->state != UA_CONNECTIONSTATE_CLOSED) @@ -18613,12 +18538,6 @@ processChunks(UA_SecureChannel *channel, void *application, channel->decryptedChunksCount > channel->config.localMaxChunkCount) || (channel->config.localMaxMessageSize != 0 && channel->decryptedChunksLength > channel->config.localMaxMessageSize)) { - ua_print("ua: [%s] count %d max %d len %d mess %d\n", - channel->decryptedChunksCount, - channel->config.localMaxChunkCount, - channel->decryptedChunksLength, - channel->config.localMaxMessageSize - ); return UA_STATUSCODE_BADTCPMESSAGETOOLARGE; } @@ -18656,9 +18575,6 @@ extractCompleteChunk(UA_SecureChannel *channel, const UA_ByteString *buffer, UA_decodeBinaryInternal(buffer, &initial_offset, &hdr, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER], NULL); - ua_debug("ua: [%s] res %d buf %p offset %d hdr %d size %d\n", __func__, res, buffer, *offset, - hdr.messageTypeAndChunkType, hdr.messageSize); - UA_assert(res == UA_STATUSCODE_GOOD); (void)res; /* pacify compilers if assert is ignored */ UA_MessageType msgType = (UA_MessageType) @@ -18671,7 +18587,6 @@ extractCompleteChunk(UA_SecureChannel *channel, const UA_ByteString *buffer, return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; if(hdr.messageSize > channel->config.recvBufferSize) { - ua_debug("lw: [%s] msg size %d rec %d\n", __func__, hdr.messageSize, channel->config.recvBufferSize); return UA_STATUSCODE_BADTCPMESSAGETOOLARGE; } @@ -43657,6 +43572,8 @@ UA_Client_delete(UA_Client* client) { UA_Client_clear(client); UA_ClientConfig_clear(&client->config); UA_free(client); + client = NULL; + ua_run_flag = 0; } void @@ -43976,7 +43893,7 @@ receiveResponse(UA_Client *client, void *response, const UA_DataType *responseTy "Receiving the response failed with StatusCode %s", UA_StatusCode_name(retval)); ua_print("ua: [%s] state %d ret %d %#x\n", __func__, client->channel.state, retval, retval); - closeSecureChannel(client); +// closeSecureChannel(client); retval = UA_STATUSCODE_BADCONNECTIONCLOSED; break; } @@ -44244,7 +44161,7 @@ UA_Client_run_iterate(UA_Client *client, UA_UInt32 timeout) { client->sessionState < UA_SESSIONSTATE_ACTIVATED) { retval = connectIterate(client, timeout); notifyClientState(client); - ua_print("lw: [%s] ret %d timeout %d state %d ch %d\n", __func__, retval, timeout, + ua_print("lw: [%s] ret %x timeout %d state %d ch %d\n", __func__, retval, timeout, client->sessionState, client->channel.state); return retval; } @@ -45187,9 +45104,6 @@ connectIterate(UA_Client *client, UA_UInt32 timeout) { return UA_STATUSCODE_BADCONNECTIONCLOSED; } - ua_debug("ua: [%s] conn %d state %d handle %p\n", __func__, client->connectStatus, - client->connection.state, client->connection.handle); - /* The connection is closed. Reset the SecureChannel and open a new TCP * connection */ if(client->connection.state == UA_CONNECTIONSTATE_CLOSED) @@ -45200,11 +45114,6 @@ connectIterate(UA_Client *client, UA_UInt32 timeout) { client->connectStatus = client->config.pollConnectionFunc(&client->connection, timeout, &client->config.logger); - - ua_debug("ua: [%s] exit conn %x %d time %d handle %p\n", __func__, - client->connectStatus, - client->connection.state, timeout, client->connection.handle); - return client->connectStatus; } @@ -45399,8 +45308,6 @@ connectSync(UA_Client *client) { UA_DateTime now = UA_DateTime_nowMonotonic(); UA_DateTime maxDate = now + ((UA_DateTime)client->config.timeout * UA_DATETIME_MSEC); - ua_print("ua; [%s] time %d\n", __func__, (UA_DateTime)client->config.timeout); - UA_StatusCode retval = initConnect(client); if(retval != UA_STATUSCODE_GOOD) return retval; @@ -70300,16 +70207,30 @@ UA_ServerConfig_setDefaultWithSecurityPolicies(UA_ServerConfig *conf, UA_Client * UA_Client_new() { UA_ClientConfig config; + UA_Client *ret = NULL; + + if(ua_run_flag) + { + return NULL; + } + memset(&config, 0, sizeof(UA_ClientConfig)); config.logger.log = UA_Log_Stdout_log; config.logger.context = NULL; config.logger.clear = UA_Log_Stdout_clear; - return UA_Client_newWithConfig(&config); + + ret = UA_Client_newWithConfig(&config); + + if(ret) + { + ua_run_flag = 1; + } + return ret; } UA_StatusCode UA_ClientConfig_setDefault(UA_ClientConfig *config) { - config->timeout = 20000; + config->timeout = 5000; config->secureChannelLifeTime = 10 * 60 * 1000; /* 10 minutes */ if(!config->logger.log) { @@ -71205,7 +71126,6 @@ ServerNetworkLayerTCP_add(UA_ServerNetworkLayer *nl, ServerNetworkLayerTCP *laye static UA_StatusCode addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) { /* Create the server socket */ - ua_print("ua: [%s] %d %d %d\n", __func__, ai->ai_family, ai->ai_socktype, ai->ai_protocol); UA_SOCKET newsock = UA_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if(newsock == UA_INVALID_SOCKET) { @@ -71341,18 +71261,12 @@ ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_Logger *logger, int retcode = UA_getaddrinfo(customHostname->length ? hostname : NULL, portno, &hints, &res); - ua_print("ua: [%s] host %s pro %d ret %d\n", __func__, hostname, portno, retcode); - if(retcode != 0) { UA_LOG_SOCKET_ERRNO_GAI_WRAP(UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, "getaddrinfo lookup of %s failed with error %d - %s", hostname, retcode, errno_str)); return UA_STATUSCODE_BADINTERNALERROR; } - ua_print("ua: [%s] res %p fam %d len %d %s\n", __func__, res, res->ai_family, - customHostname->length, - customHostname->data); - /* There might be serveral addrinfos (for different network cards, * IPv4/IPv6). Add a server socket for all of them. */ struct addrinfo *ai = res; @@ -71597,6 +71511,12 @@ typedef struct TCPClientConnection { static void ClientNetworkLayerTCP_close(UA_Connection *connection) { + if(connection == NULL) + { + ua_error("connection NULL!\n"); + return; + } + if(connection->state == UA_CONNECTIONSTATE_CLOSED) return; @@ -71637,10 +71557,6 @@ UA_ClientConnectionTCP_poll(UA_Connection *connection, UA_UInt32 timeout, return UA_STATUSCODE_BADDISCONNECT; } - ua_print("ua: [%s] conn handle %p fam %d sa %d\n", __func__, - connection->handle, tcpConnection->server->ai_family, - tcpConnection->server->ai_addr->sa_family); - /* Get a socket and connect (only once) if not already done in a previous * call. On win32, calling connect multiple times is not recommended on * non-blocking sockets @@ -71651,27 +71567,17 @@ UA_ClientConnectionTCP_poll(UA_Connection *connection, UA_UInt32 timeout, * and getsockopt using SO_ERROR on win32 and posix. */ if(connection->sockfd == UA_INVALID_SOCKET) { - ua_print("ua: [%s] start socket %p ai %d sa %d\n", __func__, - tcpConnection->server, - tcpConnection->server->ai_family, - tcpConnection->server->ai_addr->sa_family); + connection->sockfd = UA_socket(tcpConnection->server->ai_family, tcpConnection->server->ai_socktype, tcpConnection->server->ai_protocol); if(connection->sockfd == UA_INVALID_SOCKET) { - ua_print("ua: [%s] %s\n", __func__, strerror(UA_ERRNO)); UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, "Could not create client socket: %s", strerror(UA_ERRNO)); ClientNetworkLayerTCP_close(connection); return UA_STATUSCODE_BADDISCONNECT; } - ua_print("ua: [%s] socket fd %d %p fam %d sa %d\n", __func__, - connection->sockfd, - tcpConnection->server, - tcpConnection->server->ai_family, - tcpConnection->server->ai_addr->sa_family); - /* Non blocking connect to be able to timeout */ if(UA_socket_set_nonblocking(connection->sockfd) != UA_STATUSCODE_GOOD) { UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, @@ -71680,11 +71586,6 @@ UA_ClientConnectionTCP_poll(UA_Connection *connection, UA_UInt32 timeout, return UA_STATUSCODE_BADDISCONNECT; } - ua_print("ua: [%s] check fd %d %p fam %d sa %d\n", __func__, - connection->sockfd, - tcpConnection->server, - tcpConnection->server->ai_family, - tcpConnection->server->ai_addr->sa_family); /* Don't have the socket create interrupt signals */ #ifdef SO_NOSIGPIPE int val = 1; @@ -71693,12 +71594,6 @@ UA_ClientConnectionTCP_poll(UA_Connection *connection, UA_UInt32 timeout, if(sso_result < 0) UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, "Couldn't set SO_NOSIGPIPE"); #endif - ua_print("ua: [%s] connect ai %d sa fam %d len %d %x addr len %d\n", __func__, - tcpConnection->server->ai_family, - tcpConnection->server->ai_addr->sa_family, - tcpConnection->server->ai_addr->sa_len, - tcpConnection->server->ai_addr->sa_data[0], - tcpConnection->server->ai_addrlen); int error = UA_connect(connection->sockfd, tcpConnection->server->ai_addr, tcpConnection->server->ai_addrlen); @@ -71708,7 +71603,6 @@ UA_ClientConnectionTCP_poll(UA_Connection *connection, UA_UInt32 timeout, connection->state = UA_CONNECTIONSTATE_ESTABLISHED; return UA_STATUSCODE_GOOD; } - ua_print("ua: [%s] connected failed %d\n", __func__, error); /* The connection failed */ if((UA_ERRNO != UA_ERR_CONNECTION_PROGRESS)) { @@ -71772,6 +71666,7 @@ UA_ClientConnectionTCP_poll(UA_Connection *connection, UA_UInt32 timeout, (int)tcpConnection->endpointUrl.length, tcpConnection->endpointUrl.data, strerror(UA_ERRNO)); ClientNetworkLayerTCP_close(connection); + ua_error("ua: [%s] line %d failed\n", __func__, __LINE__); return UA_STATUSCODE_BADDISCONNECT; } @@ -71802,6 +71697,7 @@ UA_ClientConnectionTCP_poll(UA_Connection *connection, UA_UInt32 timeout, LocalFree(errno_str); #endif ClientNetworkLayerTCP_close(connection); + ua_error("ua: [%s] line %d failed\n", __func__, __LINE__); return UA_STATUSCODE_BADDISCONNECT; } @@ -71831,14 +71727,11 @@ UA_ClientConnectionTCP_init(UA_ConnectionConfig config, const UA_String endpoint connection.releaseSendBuffer = connection_releasesendbuffer; connection.releaseRecvBuffer = connection_releaserecvbuffer; - ua_print("ua: [%s] endpoint url (%d)%.28s %d\n", __func__, endpointUrl.length, endpointUrl.data, - sizeof(TCPClientConnection)); - TCPClientConnection *tcpClientConnection = (TCPClientConnection*) UA_malloc(sizeof(TCPClientConnection)); if(!tcpClientConnection) { connection.state = UA_CONNECTIONSTATE_CLOSED; - ua_print("ua: [%s] malloc %d failed\n", __func__, sizeof(TCPClientConnection)); + ua_error("ua: [%s] malloc %d failed\n", __func__, sizeof(TCPClientConnection)); return connection; } memset(tcpClientConnection, 0, sizeof(TCPClientConnection)); @@ -71850,8 +71743,6 @@ UA_ClientConnectionTCP_init(UA_ConnectionConfig config, const UA_String endpoint char hostname[512]; tcpClientConnection->connStart = UA_DateTime_nowMonotonic(); - ua_print("ua: [%s] line %d!\n", __func__, __LINE__); - UA_String_copy(&endpointUrl, &tcpClientConnection->endpointUrl); UA_StatusCode parse_retval = @@ -71864,8 +71755,6 @@ UA_ClientConnectionTCP_init(UA_ConnectionConfig config, const UA_String endpoint return connection; } - ua_print("ua: [%s] line %d!\n", __func__, __LINE__); - memcpy(hostname, hostnameString.data, hostnameString.length); hostname[hostnameString.length] = 0; @@ -71875,22 +71764,16 @@ UA_ClientConnectionTCP_init(UA_ConnectionConfig config, const UA_String endpoint "No port defined, using default port %" PRIu16, port); } - ua_print("ua: [%s] line %d!\n", __func__, __LINE__); - memset(&tcpClientConnection->hints, 0, sizeof(tcpClientConnection->hints)); tcpClientConnection->hints.ai_family = AF_UNSPEC; tcpClientConnection->hints.ai_socktype = SOCK_STREAM; char portStr[6]; UA_snprintf(portStr, 6, "%d", port); -// ua_print("ua: [%s] host %s port %s fam %d\n", __func__, hostname, portStr, -// tcpClientConnection->server->ai_addr->sa_family); - #if LWIP_DNS int error = UA_getaddrinfo(hostname, portStr, &tcpClientConnection->hints, &tcpClientConnection->server); if(error != 0 || !tcpClientConnection->server) { - ua_print("ua: [%s] host %s error %d\n", __func__, hostname, error); UA_LOG_SOCKET_ERRNO_GAI_WRAP(UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, "DNS lookup of %s failed with error %d - %s", hostname, error, errno_str)); diff --git a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.c b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.c index 4512368be..7115ca1c3 100755 --- a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.c +++ b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.c @@ -22,7 +22,7 @@ #include #include "ua_api.h" -int ua_open(void *dev) +int UaDevOpen(void *dev) { UaParamType *param = (UaParamType *)dev; @@ -32,7 +32,7 @@ int ua_open(void *dev) if (param->client == NULL) { - ua_print("ua: [%s] tcp client null\n", __func__); + ua_error("ua: [%s] tcp client null\n", __func__); return EEMPTY; } @@ -43,28 +43,29 @@ int ua_open(void *dev) UA_StatusCode retval = UA_Client_connect(param->client, param->ua_remote_ip); if(retval != UA_STATUSCODE_GOOD) { - ua_notice("ua: [%s] deleted ret %x!\n", __func__, retval); + ua_error("ua: [%s] deleted ret %x!\n", __func__, retval); return (int)retval; } return EOK; } -void ua_close(void *dev) +void UaDevClose(void *dev) { UaParamType *param = (UaParamType *)dev; + ua_notice("ua: [%s] close %s!\n", __func__, param->ua_remote_ip); UA_Client_delete(param->client); /* Disconnects the client internally */ } -int ua_read(void *dev, void *buf, size_t len) +int UaDevRead(void *dev, void *buf, size_t len) { UaParamType *param = (UaParamType *)dev; switch(param->act) { case UA_ACT_ATTR: - ua_read_nodeid_value(param->client, param->ua_id, buf); + UaReadNodeValue(param->client, param->ua_id, buf); break; case UA_ACT_OBJ: - ua_test_browser_objects(param->client); + UaTestBrowserObjects(param->client); break; default: break; @@ -72,17 +73,17 @@ int ua_read(void *dev, void *buf, size_t len) return EOK; } -int ua_write(void *dev, const void *buf, size_t len) +int UaDevWrite(void *dev, const void *buf, size_t len) { UaParamType *param = (UaParamType *)dev; switch(param->act) { case UA_ACT_ATTR: - ua_write_nodeid_value(param->client, param->ua_id, (char *)buf); + UaWriteNodeValue(param->client, param->ua_id, (char *)buf); break; case UA_ACT_OBJ: - ua_test_browser_objects(param->client); + UaTestBrowserObjects(param->client); break; default: break; @@ -90,7 +91,7 @@ int ua_write(void *dev, const void *buf, size_t len) return EOK; } -int ua_ioctl(void *dev, int cmd, void *arg) +int UaDevIoctl(void *dev, int cmd, void *arg) { return EOK; } diff --git a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.h b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.h index 7da7a4faa..30c785525 100755 --- a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.h +++ b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_api.h @@ -42,32 +42,31 @@ typedef struct UaParam }UaParamType; #define ua_print //KPrintf -#define ua_trace() //KPrintf("ua: [%s] line %d checked!\n", __func__, __LINE__) #define ua_notice KPrintf -#define ua_debug //KPrintf #define ua_error KPrintf extern const char *opc_server_url; extern char test_ua_ip[]; -int ua_server_connect(void); -void ua_browser_nodes(UA_Client *client); -void ua_browser_id(UA_Client *client, UA_NodeId id); -void ua_read_time(UA_Client *client); -void ua_add_nodes(UA_Client *client); +int UaServerRun(void); +void UaBrowserNodes(UA_Client *client); +void UaBrowserNodeId(UA_Client *client, UA_NodeId id); +void UaGetServerTime(UA_Client *client); +void UaAddNodes(UA_Client *client); -int ua_open(void *dev); // open and connect PLC device -void ua_close(void* dev); // close and disconnect PLC device -int ua_read(void* dev, void *buf, size_t len); // read data from PLC -int ua_write(void* dev, const void *buf, size_t len); // write data from PLC -int ua_ioctl(void* dev, int cmd, void *arg); // send control command to PLC +int UaDevOpen(void *dev); // open and connect PLC device +void UaDevClose(void* dev); // close and disconnect PLC device +int UaDevRead(void* dev, void *buf, size_t len); // read data from PLC +int UaDevWrite(void* dev, const void *buf, size_t len); // write data from PLC +int UaDevIoctl(void* dev, int cmd, void *arg); // send control command to PLC -char *ua_get_nodeid_str(UA_NodeId *node_id); -void ua_read_nodeid_value(UA_Client *client, UA_NodeId id, UA_Int32 *value); -void ua_write_nodeid_value(UA_Client *client, UA_NodeId id, char* value); -void ua_test_attr(UA_Client *client); -UA_StatusCode ua_read_array_value(UA_Client *client, int array_size, UA_ReadValueId *array); -void ua_test_browser_objects(UA_Client *client); -int ua_test_interact_server(UA_Client *client); +char *UaGetNodeIdString(UA_NodeId *node_id); +void UaReadNodeValue(UA_Client *client, UA_NodeId id, UA_Int32 *value); +void UaWriteNodeValue(UA_Client *client, UA_NodeId id, char* value); +UA_StatusCode UaReadArrayValue(UA_Client *client, int array_size, UA_ReadValueId *array); +int UaGetNodeIdArray(UA_Client* client, UA_NodeId id, int array_size, int *id_array); + +void UaTestBrowserObjects(UA_Client *client); +int UaTestInteractServer(UA_Client *client); #endif diff --git a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_client.c b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_client.c index 749025f75..b903be86d 100755 --- a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_client.c +++ b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_client.c @@ -27,14 +27,14 @@ const char *opc_server_url = {"opc.tcp://192.168.250.2:4840"}; #ifdef UA_ENABLE_SUBSCRIPTIONS -static void handler_TheAnswerChanged(UA_Client* client, UA_UInt32 subId, void* subContext, +static void UaAnswerChangedHandler(UA_Client* client, UA_UInt32 subId, void* subContext, UA_UInt32 monId, void* monContext, UA_DataValue* value) { - ua_print("The Answer has changed!\n"); + ua_notice("Answer changed!\n"); } #endif -static UA_StatusCode nodeIter(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId, void* handle) +static UA_StatusCode UaShowNodeIdIterate(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId, void* handle) { if(isInverse) { @@ -49,7 +49,7 @@ static UA_StatusCode nodeIter(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId return UA_STATUSCODE_GOOD; } -int ua_get_points(UA_Client* client) +int UaGetEndPoints(UA_Client* client) { /* Listing endpoints */ UA_EndpointDescription* endpointArray = NULL; @@ -76,7 +76,7 @@ int ua_get_points(UA_Client* client) return EXIT_SUCCESS; } -void ua_print_value(UA_Variant* val) +static void UaShowNodeValue(UA_Variant* val) { if(val->type == &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]) { @@ -103,6 +103,16 @@ void ua_print_value(UA_Variant* val) UA_Int16* ptr = (UA_Int16*)val->data; ua_notice("%d (Int16)\n", *ptr); } + else if(val->type == &UA_TYPES[UA_TYPES_FLOAT]) + { + UA_Float* ptr = (UA_Float*)val->data; + printf("%f (Float)\n", *ptr); + } + else if(val->type == &UA_TYPES[UA_TYPES_DOUBLE]) + { + UA_Double* ptr = (UA_Double*)val->data; + printf("%f (Double)\n", *ptr); + } else if(val->type == &UA_TYPES[UA_TYPES_STRING]) { UA_String* ptr = (UA_String*)val->data; @@ -117,7 +127,7 @@ void ua_print_value(UA_Variant* val) } } -char *ua_get_nodeid_str(UA_NodeId *node_id) +char *UaGetNodeIdString(UA_NodeId *node_id) { static char nodeid_str[UA_NODE_LEN] = {0}; @@ -139,7 +149,7 @@ char *ua_get_nodeid_str(UA_NodeId *node_id) return nodeid_str; } -void ua_print_nodeid(UA_NodeId *node_id) +static void UaShowNodeId(UA_NodeId *node_id) { switch(node_id->identifierType) { @@ -158,7 +168,7 @@ void ua_print_nodeid(UA_NodeId *node_id) } } -void ua_print_object(UA_BrowseResponse* res) +static void UaShowObject(UA_BrowseResponse* res) { ua_notice("%-9s %-16s %-16s %-16s\n", "NAMESPACE", "NODEID", "BROWSE NAME", "DISPLAY NAME"); @@ -191,7 +201,7 @@ void ua_print_object(UA_BrowseResponse* res) ua_notice("\n"); } -UA_StatusCode ua_read_array_value(UA_Client* client, int array_size, UA_ReadValueId* array) +UA_StatusCode UaReadArrayValue(UA_Client* client, int array_size, UA_ReadValueId* array) { UA_ReadRequest request; UA_ReadRequest_init(&request); @@ -209,14 +219,19 @@ UA_StatusCode ua_read_array_value(UA_Client* client, int array_size, UA_ReadValu } UA_StatusCode* arr_ret = malloc(array_size * sizeof(UA_StatusCode)); + if(arr_ret == NULL) + { + ua_error("ua: [%s] malloc %d failed!\n", __func__, array_size * sizeof(UA_StatusCode)); + return UA_STATUSCODE_BADOUTOFMEMORY; + } for(int i = 0; i < array_size; ++i) { if((response.results[i].status == UA_STATUSCODE_GOOD) && (response.results[i].hasValue)) { - ua_notice("node %s: ", ua_get_nodeid_str(&array[i].nodeId)); - ua_print_value(&response.results[i].value); + ua_notice("node %s: ", UaGetNodeIdString(&array[i].nodeId)); + UaShowNodeValue(&response.results[i].value); } } ua_notice("\n"); @@ -226,32 +241,82 @@ UA_StatusCode ua_read_array_value(UA_Client* client, int array_size, UA_ReadValu return UA_STATUSCODE_GOOD; } -void ua_browser_id(UA_Client* client, UA_NodeId id) +void UaBrowserNodeId(UA_Client* client, UA_NodeId id) { + UA_BrowseRequest ua_req; + UA_BrowseResponse ua_resp; + /* Browse some objects */ ua_notice("Browsing nodes in objects folder:\n"); - UA_BrowseRequest bReq; - UA_BrowseRequest_init(&bReq); - bReq.requestedMaxReferencesPerNode = 0; - bReq.nodesToBrowse = UA_BrowseDescription_new(); - bReq.nodesToBrowseSize = 1; - bReq.nodesToBrowse[0].nodeId = id; /* browse objects folder */ - bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; /* return everything */ - UA_BrowseResponse res = UA_Client_Service_browse(client, bReq); - ua_print_object(&res); - UA_BrowseResponse_clear(&res); -// UA_BrowseRequest_clear(&bReq); + + UA_BrowseRequest_init(&ua_req); + + ua_req.requestedMaxReferencesPerNode = 0; + ua_req.nodesToBrowse = UA_BrowseDescription_new(); + ua_req.nodesToBrowseSize = 1; + ua_req.nodesToBrowse[0].nodeId = id; /* browse objects folder */ + ua_req.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; /* return everything */ + + ua_resp = UA_Client_Service_browse(client, ua_req); + + UaShowObject(&ua_resp); + + UA_BrowseResponse_clear(&ua_resp); } -void ua_browser_nodes(UA_Client* client) + +int UaGetNodeIdArray(UA_Client* client, UA_NodeId id, int array_size, int *id_array) +{ + int i, j; + int array_cnt = 0;// return array number + UA_BrowseRequest ua_req; + UA_BrowseResponse ua_resp; + + /* Browse some objects */ + ua_notice("Browsing nodes in objects folder:\n"); + + UA_BrowseRequest_init(&ua_req); + + ua_req.requestedMaxReferencesPerNode = 0; + ua_req.nodesToBrowse = UA_BrowseDescription_new(); + ua_req.nodesToBrowseSize = 1; + ua_req.nodesToBrowse[0].nodeId = id; /* browse objects folder */ + ua_req.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; /* return everything */ + + ua_resp = UA_Client_Service_browse(client, ua_req); + + for(i = 0; i < ua_resp.resultsSize; ++i) + { + for(j = 0; j < ua_resp.results[i].referencesSize; ++j) + { + UA_ReferenceDescription* ref = &(ua_resp.results[i].references[j]); + + if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC) + { + *(id_array + array_cnt) = ref->nodeId.nodeId.identifier.numeric; + array_cnt ++; + if(array_cnt >= array_size) + { + UA_BrowseResponse_clear(&ua_resp); + return array_cnt; + } + } + } + } + + UA_BrowseResponse_clear(&ua_resp); + return array_cnt; +} + +void UaBrowserNodes(UA_Client* client) { UA_NodeId* parent = UA_NodeId_new(); *parent = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); - UA_Client_forEachChildNodeCall(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), nodeIter, (void*) parent); + UA_Client_forEachChildNodeCall(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UaShowNodeIdIterate, (void*) parent); UA_NodeId_delete(parent); } -UA_UInt32 ua_start_sub(UA_Client* client, UA_NodeId node_id) +UA_UInt32 UaStartSubscription(UA_Client* client, UA_NodeId node_id) { /* Create a subscription */ UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default(); @@ -274,7 +339,7 @@ UA_UInt32 ua_start_sub(UA_Client* client, UA_NodeId node_id) UA_MonitoredItemCreateResult monResponse = UA_Client_MonitoredItems_createDataChange(client, response.subscriptionId, UA_TIMESTAMPSTORETURN_BOTH, - monRequest, NULL, handler_TheAnswerChanged, NULL); + monRequest, NULL, UaAnswerChangedHandler, NULL); if(monResponse.statusCode == UA_STATUSCODE_GOOD) { @@ -290,7 +355,7 @@ UA_UInt32 ua_start_sub(UA_Client* client, UA_NodeId node_id) return subId; } -void ua_write_nodeid_value(UA_Client* client, UA_NodeId id, char* value) +void UaWriteNodeValue(UA_Client* client, UA_NodeId id, char* value) { UA_Boolean bool_val; uint32_t integer_val; @@ -332,24 +397,17 @@ void ua_write_nodeid_value(UA_Client* client, UA_NodeId id, char* value) UA_WriteRequest_clear(&wReq); UA_WriteResponse_clear(&wResp); - -// /* Write node attribute (using the highlevel API) */ -// value++; -// UA_Variant *myVariant = UA_Variant_new(); -// UA_Variant_setScalarCopy(myVariant, &value, &UA_TYPES[UA_TYPES_INT32]); -// UA_Client_writeValueAttribute(client, UA_NODEID_STRING(1, UA_NODE_STR), myVariant); -// UA_Variant_delete(myVariant); } /* Read attribute */ -void ua_read_nodeid_value(UA_Client* client, UA_NodeId id, UA_Int32 *value) +void UaReadNodeValue(UA_Client* client, UA_NodeId id, UA_Int32 *value) { UA_Variant* val = UA_Variant_new(); UA_StatusCode ret = UA_Client_readValueAttribute(client, id, val); if(ret == UA_STATUSCODE_GOOD) { - ua_print_value(val); + UaShowNodeValue(val); if(UA_Variant_isScalar(val)) { if(val->type == &UA_TYPES[UA_TYPES_BOOLEAN]) @@ -370,7 +428,7 @@ void ua_read_nodeid_value(UA_Client* client, UA_NodeId id, UA_Int32 *value) UA_Variant_delete(val); } -void ua_call_remote(UA_Client* client) +void UaCallRemote(UA_Client* client) { /* Call a remote method */ UA_Variant input; @@ -397,7 +455,7 @@ void ua_call_remote(UA_Client* client) } -void ua_add_nodes(UA_Client* client) +void UaAddNodes(UA_Client* client) { /* Add new nodes*/ /* New ReferenceType */ @@ -477,7 +535,7 @@ void ua_add_nodes(UA_Client* client) } } -void ua_read_time(UA_Client* client) +void UaGetServerTime(UA_Client* client) { UA_Variant value; UA_Variant_init(&value); diff --git a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_server.c b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_server.c index b3d24eba7..548a357ce 100755 --- a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_server.c +++ b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_server.c @@ -10,29 +10,29 @@ * See the Mulan PSL v2 for more details. */ +/** + * @file ua_server.c + * @brief Server for OpcUa function + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2021.11.11 + */ #include "open62541.h" -#include -#include +UA_Boolean ua_server_flag = true; -UA_Boolean running = true; - -static void stopHandler(int sign) { - UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "received ctrl-c"); - running = false; -} - -int ua_server_connect(void) +int UaRunServer(void) { - signal(SIGINT, stopHandler); - signal(SIGTERM, stopHandler); + UA_StatusCode ret; UA_Server *server = UA_Server_new(); + UA_ServerConfig_setDefault(UA_Server_getConfig(server)); - UA_StatusCode retval = UA_Server_run(server, &running); + + ret = UA_Server_run(server, &ua_server_flag); UA_Server_delete(server); - return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE; + return ret; } diff --git a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_test.c b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_test.c index d11b86896..1b9ed8427 100755 --- a/APP_Framework/Framework/control/plc/interoperability/opcua/ua_test.c +++ b/APP_Framework/Framework/control/plc/interoperability/opcua/ua_test.c @@ -27,72 +27,60 @@ #define UA_TEST_BROWSER_NODEID1 UA_NODEID_NUMERIC(4, 1) #define UA_TEST_WRITE_NODEID UA_NODEID_NUMERIC(4, 5) +#define UA_TEST_NODE_ARRAY_NUM 10 -static UA_StatusCode ua_test_read_array(UA_Client *client) +static UA_StatusCode UaTestReadArrayValue(UA_Client *client, UA_NodeId id) { - const int item_size = 4; - UA_ReadValueId test_item[item_size]; + int i; + int array_size = 0; + int test_id[UA_TEST_NODE_ARRAY_NUM]; + UA_ReadValueId test_array[UA_TEST_NODE_ARRAY_NUM]; - for (int i = 0; i < item_size; i++) + for(i = 0; i < UA_TEST_NODE_ARRAY_NUM; i++) { - UA_ReadValueId_init(&test_item[i]); - test_item[i].attributeId = UA_ATTRIBUTEID_VALUE; + UA_ReadValueId_init(&test_array[i]); + test_array[i].attributeId = UA_ATTRIBUTEID_VALUE; } - test_item[0].nodeId = UA_NODEID_NUMERIC(4, 2); - test_item[1].nodeId = UA_NODEID_NUMERIC(4, 3); - test_item[2].nodeId = UA_NODEID_NUMERIC(4, 4); - test_item[3].nodeId = UA_NODEID_NUMERIC(4, 5); + array_size = UaGetNodeIdArray(client, id, UA_TEST_NODE_ARRAY_NUM, test_id); - return ua_read_array_value(client, item_size, test_item); + for(i = 0; i < array_size; i++) + { + test_array[i].nodeId = UA_NODEID_NUMERIC(id.namespaceIndex, test_id[i]); + } + + return UaReadArrayValue(client, array_size, test_array); } -void ua_test_browser_objects(UA_Client *client) +void UaTestBrowserObjects(UA_Client *client) { UA_NodeId test_id; - ua_browser_id(client, UA_TEST_BROWSER_NODEID); - ua_browser_id(client, UA_TEST_BROWSER_NODEID1); + UaBrowserNodeId(client, UA_TEST_BROWSER_NODEID); + UaBrowserNodeId(client, UA_TEST_BROWSER_NODEID1); test_id = UA_TEST_BROWSER_NODEID1; - ua_notice("Show values in %s:\n", ua_get_nodeid_str(&test_id)); - ua_test_read_array(client); + ua_notice("Show values in %s:\n", UaGetNodeIdString(&test_id)); + UaTestReadArrayValue(client, test_id); return; } -void ua_test_write_attr(UA_Client *client) +static void UaTestWriteNodeValue(UA_Client *client) { UA_Int32 value; char val_str[UA_NODE_LEN]; UA_NodeId id = UA_TEST_WRITE_NODEID; - ua_notice("--- Test write %s ---\n", ua_get_nodeid_str(&id)); - ua_read_nodeid_value(client, id, &value); - ua_write_nodeid_value(client, id, itoa(value + 1, val_str, 10)); - ua_read_nodeid_value(client, id, &value); + ua_notice("--- Test write %s ---\n", UaGetNodeIdString(&id)); + UaReadNodeValue(client, id, &value); + UaWriteNodeValue(client, id, itoa(value + 1, val_str, 10)); + UaReadNodeValue(client, id, &value); ua_notice("\n"); } -int ua_test_interact_server(UA_Client *client) +int UaTestInteractServer(UA_Client *client) { - ua_read_time(client); - ua_test_browser_objects(client); - ua_test_write_attr(client); - return EXIT_SUCCESS; -} - -int16 ua_test(void) -{ - UA_Client *client = UA_Client_new(); - UA_StatusCode retval = UA_Client_connect(client, opc_server_url); - if(retval != UA_STATUSCODE_GOOD) { - UA_Client_delete(client); - return (int)retval; - } - - ua_read_time(client); - - /* Clean up */ - UA_Client_disconnect(client); - UA_Client_delete(client); /* Disconnects the client internally */ + UaGetServerTime(client); + UaTestBrowserObjects(client); + UaTestWriteNodeValue(client); return EXIT_SUCCESS; } diff --git a/APP_Framework/Framework/control/plc/shared/plc_channel.c b/APP_Framework/Framework/control/plc/shared/plc_channel.c index 3fe084514..7959a42e1 100755 --- a/APP_Framework/Framework/control/plc/shared/plc_channel.c +++ b/APP_Framework/Framework/control/plc/shared/plc_channel.c @@ -322,7 +322,7 @@ ChDevType ChannelFindDevice(struct Channel *ch, const char *device_name) * @param dev_recv_callback - callback function * @return successful:EOK,failed:ERROR */ -uint32 ChannelDevRecvCallback(struct ChDev *dev, int (*dev_recv_callback) (void *dev, x_size_t length)) +uint32 ChannelDevRecvCallback(struct ChDev *dev, int (*dev_recv_callback) (void *dev, size_t length)) { CHECK_CH_PARAM(dev ); diff --git a/APP_Framework/Framework/control/plc/shared/plc_channel.h b/APP_Framework/Framework/control/plc/shared/plc_channel.h index a00262bf1..9d0075687 100755 --- a/APP_Framework/Framework/control/plc/shared/plc_channel.h +++ b/APP_Framework/Framework/control/plc/shared/plc_channel.h @@ -12,7 +12,7 @@ /** * @file plc_channel.h -* @brief define ch driver framework function and common API +* @brief define channel driver framework function and common API * @version 1.0 * @author AIIT XUOS Lab * @date 2022-03-01 @@ -23,9 +23,6 @@ #include "list.h" -#define x_OffPos uint32 -#define x_size_t size_t - #ifdef __cplusplus extern "C" { #endif @@ -97,27 +94,19 @@ struct ChConfigInfo struct ChReadParam { - x_OffPos pos; + uint32 pos; void* buffer; - x_size_t size; - x_size_t read_length; + size_t size; + size_t read_length; }; struct ChWriteParam { - x_OffPos pos; + uint32 pos; const void* buffer; - x_size_t size; + size_t size; }; -//struct ChHalDevBlockParam -//{ -// uint32 cmd; -////tst by wly -//// struct DeviceBlockArrange dev_block; -//// struct DeviceBlockAddr *dev_addr; -//}; - struct ChHalDevDone { uint32 (*open) (void *dev); @@ -134,8 +123,7 @@ struct ChDev const struct ChHalDevDone *dev_done; - int (*dev_recv_callback) (void *dev, x_size_t length); -// int (*dev_block_control) (struct ChDev *dev, struct ChHalDevBlockParam *block_param); + int (*dev_recv_callback) (void *dev, size_t length); struct Channel *owner_ch; void *private_data; @@ -220,7 +208,7 @@ ChDrvType ChannelFindDriver(struct Channel *ch, const char *driver_name); ChDevType ChannelFindDevice(struct Channel *ch, const char *device_name); /*Dev receive data callback function*/ -uint32 ChannelDevRecvCallback(struct ChDev *dev, int (*dev_recv_callback) (void *dev, x_size_t length)); +uint32 ChannelDevRecvCallback(struct ChDev *dev, int (*dev_recv_callback) (void *dev, size_t length)); /*Open the device of the channel*/ uint32 ChannelDevOpen(struct ChDev *dev); diff --git a/APP_Framework/Framework/control/plc/shared/plc_device.c b/APP_Framework/Framework/control/plc/shared/plc_device.c index 670452e2a..8860aea37 100755 --- a/APP_Framework/Framework/control/plc/shared/plc_device.c +++ b/APP_Framework/Framework/control/plc/shared/plc_device.c @@ -40,7 +40,7 @@ static int PlcDeviceOpen(void *dev) if(plc_dev->net == PLC_IND_ENET_OPCUA) { - return ua_open(plc_dev->priv_data); + return UaDevOpen(plc_dev->priv_data); } return EOK; @@ -54,7 +54,7 @@ static void PlcDeviceClose(void *dev) if(plc_dev->net == PLC_IND_ENET_OPCUA) { - ua_close(plc_dev->priv_data); + UaDevClose(plc_dev->priv_data); } } @@ -67,7 +67,7 @@ static int PlcDeviceWrite(void *dev, const void *buf, size_t len) if(plc_dev->net == PLC_IND_ENET_OPCUA) { - ret = ua_write(plc_dev->priv_data, buf, len); + ret = UaDevWrite(plc_dev->priv_data, buf, len); } return ret; @@ -83,7 +83,7 @@ static int PlcDeviceRead(void *dev, void *buf, size_t len) if(plc_dev->net == PLC_IND_ENET_OPCUA) { - ret = ua_read(plc_dev->priv_data, buf, len); + ret = UaDevRead(plc_dev->priv_data, buf, len); } return ret; diff --git a/APP_Framework/Framework/transform_layer/nuttx/transform.c b/APP_Framework/Framework/transform_layer/nuttx/transform.c index 7b8553a1a..1a176fddb 100644 --- a/APP_Framework/Framework/transform_layer/nuttx/transform.c +++ b/APP_Framework/Framework/transform_layer/nuttx/transform.c @@ -92,10 +92,11 @@ void PrivTaskQuit(void *value_ptr) int PrivTaskDelay(int32_t ms) { - return usleep(ms); + return usleep(1000 * ms); } -uint32_t PrivGetTickTime(){ +uint32_t PrivGetTickTime(void) +{ struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; diff --git a/APP_Framework/Framework/transform_layer/nuttx/transform.h b/APP_Framework/Framework/transform_layer/nuttx/transform.h index e99456053..49603f4ab 100644 --- a/APP_Framework/Framework/transform_layer/nuttx/transform.h +++ b/APP_Framework/Framework/transform_layer/nuttx/transform.h @@ -192,7 +192,7 @@ int PrivTaskStartup(pthread_t *thread); int PrivTaskDelete(pthread_t thread, int sig); void PrivTaskQuit(void *value_ptr); int PrivTaskDelay(int32_t ms); -uint32_t PrivGetTickTime(); +uint32_t PrivGetTickTime(void); /*********************driver*************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/Kconfig index 27b484b4c..e9b8024af 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/Kconfig @@ -24,4 +24,64 @@ config XIDATONG_SDRAM ---help--- Activate DCD configuration of SDRAM +config XIDATONG_SDIO_AUTOMOUNT + 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" + +config XIDATONG_SDIO_AUTOMOUNT_BLKDEV + string "SD card block device" + default "/dev/mmcsd0" + +config XIDATONG_SDIO_AUTOMOUNT_MOUNTPOINT + string "SD card mount point" + default "/mnt/sdcard" + +config XIDATONG_SDIO_AUTOMOUNT_DDELAY + int "SD card debounce delay (milliseconds)" + default 1000 + +config XIDATONG_SDIO_AUTOMOUNT_UDELAY + 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 + +if XIDATONG_USB_AUTOMOUNT + +config XIDATONG_USB_AUTOMOUNT_FSTYPE + string "USB file system type" + default "vfat" + +config XIDATONG_USB_AUTOMOUNT_BLKDEV + string "USB block device prefix" + default "/dev/sd" + +config XIDATONG_USB_AUTOMOUNT_MOUNTPOINT + 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 + +config XIDATONG_USB_AUTOMOUNT_UDELAY + int "USB unmount retry delay (milliseconds)" + default 2000 + +endif # XIDATONG_USB_AUTOMOUNT + + endif 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 e0cd4e51b..62ba4cf76 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/knsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/knsh/defconfig @@ -44,4 +44,5 @@ CONFIG_START_DAY=8 CONFIG_START_MONTH=6 CONFIG_SYSTEM_NSH=y CONFIG_SYS_RESERVED=9 +CONFIG_DEV_GPIO=y CONFIG_USER_ENTRYPOINT="nsh_main" 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 a38942cd3..149feb1ce 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/libcxxtest/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/libcxxtest/defconfig @@ -43,4 +43,5 @@ CONFIG_SCHED_WAITPID=y CONFIG_START_DAY=14 CONFIG_START_MONTH=3 CONFIG_SYSTEM_NSH=y +CONFIG_DEV_GPIO=y 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 974ab7dd8..b85c81a33 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/netnsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/netnsh/defconfig @@ -65,4 +65,5 @@ CONFIG_START_MONTH=3 CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_PING6=y CONFIG_SYSTEM_PING=y +CONFIG_DEV_GPIO=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 78b8bbd2d..4dd3554b8 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/nsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/nsh/defconfig @@ -41,4 +41,5 @@ CONFIG_SCHED_WAITPID=y CONFIG_START_DAY=14 CONFIG_START_MONTH=3 CONFIG_SYSTEM_NSH=y +CONFIG_DEV_GPIO=y CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/usdhc/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/sdionsh/defconfig similarity index 87% rename from Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/usdhc/defconfig rename to Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/sdionsh/defconfig index c22671e64..eeccb4f50 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/usdhc/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/sdionsh/defconfig @@ -20,11 +20,6 @@ CONFIG_ARMV7M_ICACHE=y CONFIG_ARMV7M_USEBASEPRI=y CONFIG_BOARD_LOOPSPERMSEC=104926 CONFIG_BUILTIN=y -CONFIG_DEBUG_FEATURES=y -CONFIG_DEBUG_FULLOPT=y -CONFIG_DEBUG_SYMBOLS=y -CONFIG_DEV_URANDOM=y -CONFIG_DEV_ZERO=y CONFIG_FAT_LCNAMES=y CONFIG_CLOCK_MONOTONIC=y CONFIG_FAT_LFN=y @@ -32,9 +27,9 @@ CONFIG_FS_FAT=y CONFIG_FS_PROCFS=y CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_EXAMPLES_HELLO=y -CONFIG_IMXRT1020_EVK_QSPI_FLASH=y -CONFIG_IMXRT_GPIO1_0_15_IRQ=y +CONFIG_IMXRT_GPIO2_16_31_IRQ=y CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_DEV_GPIO=y CONFIG_IMXRT_LPUART1=y CONFIG_IMXRT_USDHC1=y CONFIG_IMXRT_USDHC1_WIDTH_D1_D4=y @@ -42,9 +37,7 @@ CONFIG_INTELHEX_BINARY=y CONFIG_IOB_NBUFFERS=24 CONFIG_IOB_NCHAINS=8 CONFIG_LIBC_STRERROR=y -CONFIG_LPUART1_RXBUFSIZE=1024 CONFIG_LPUART1_SERIAL_CONSOLE=y -CONFIG_LPUART1_TXBUFSIZE=1024 CONFIG_MMCSD=y CONFIG_MMCSD_SDIO=y CONFIG_MM_IOB=y @@ -69,5 +62,6 @@ CONFIG_START_DAY=14 CONFIG_START_MONTH=3 CONFIG_SYSTEM_CLE_CMD_HISTORY=y CONFIG_SYSTEM_COLOR_CLE=y +CONFIG_FS_AUTOMOUNTER=y CONFIG_SYSTEM_NSH=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 new file mode 100644 index 000000000..5f71e3f57 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/configs/usbnsh/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_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_LPUART1=y +CONFIG_INTELHEX_BINARY=y +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_NCHAINS=8 +CONFIG_LIBC_STRERROR=y +CONFIG_LPUART1_SERIAL_CONSOLE=y +CONFIG_MM_IOB=y +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_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_RAM_SIZE=524288 +CONFIG_RAM_START=0x20200000 +CONFIG_RAW_BINARY=y +CONFIG_SCHED_CHILD_STATUS=y +CONFIG_SCHED_HAVE_PARENT=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_START_DAY=14 +CONFIG_START_MONTH=3 +CONFIG_SYSTEM_CLE_CMD_HISTORY=y +CONFIG_SYSTEM_COLOR_CLE=y +CONFIG_SYSTEM_NSH=y +CONFIG_IMXRT_USBOTG=y +CONFIG_IMXRT_USBDEV=y +CONFIG_USBDEV=y +CONFIG_USBHOST=y +CONFIG_USBHOST_MSC=y +CONFIG_USBHOST_MSC_NOTIFIER=y +CONFIG_DEV_GPIO=y +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/include/board.h index e6021288c..46d73d22a 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/include/board.h @@ -128,6 +128,7 @@ #define IMXRT_SYS_PLL_SELECT CCM_ANALOG_PLL_SYS_DIV_SELECT_22 #define IMXRT_USB1_PLL_DIV_SELECT CCM_ANALOG_PLL_USB1_DIV_SELECT_20 +#define IMXRT_USB2_PLL_DIV_SELECT CCM_ANALOG_PLL_USB2_DIV_SELECT_20 // #define BOARD_CPU_FREQUENCY \ // (BOARD_XTAL_FREQUENCY * (IMXRT_ARM_PLL_DIV_SELECT / 2)) / IMXRT_ARM_PODF_DIVIDER @@ -214,9 +215,8 @@ #define PIN_USDHC1_D3 (GPIO_USDHC1_DATA3_1 | IOMUX_USDHC1_DATAX_DEFAULT) /* GPIO_SD_B0_05 */ #define PIN_USDHC1_DCLK (GPIO_USDHC1_CLK_1 | IOMUX_USDHC1_CLK_DEFAULT) /* GPIO_SD_B0_01 */ #define PIN_USDHC1_CMD (GPIO_USDHC1_CMD_1 | IOMUX_USDHC1_CMD_DEFAULT) /* GPIO_SD_B0_00 */ -//#define PIN_USDHC1_CD (GPIO_USDHC1_CD_2 | IOMUX_USDHC1_CLK_DEFAULT) -#define PIN_USDHC1_CD_GPIO (IOMUX_VSD_DEFAULT | GPIO_PORT2 | GPIO_PIN28) /* GPIO_B1_12 */ +#define PIN_USDHC1_CD (GPIO_USDHC1_CD_2 | IOMUX_USDHC1_CLK_DEFAULT) /* GPIO_B1_12 */ /* 386 KHz for initial inquiry stuff */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/readme.md b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/readme.md index 4dd1f3e84..01a71f401 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/readme.md +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/readme.md @@ -137,8 +137,9 @@ source build.sh 执行完毕会自动进入./Ubiquitous/Nuttx_Fusion_XiUOS/nuttx下,继续执行 -sudo ./tools/configure.sh xidatong:nsh -sudo make menuconfig +./tools/configure.sh xidatong:nsh +make menuconfig +视情况而定,如果需要前面加sudo ``` 2.在menuconfig界面配置需要关闭和开启的功能,按回车键进入下级菜单,按Y键选中需要开启的功能,按N键选中需要关闭的功能,配置结束后保存并退出(本例旨在演示简单的输出例程,所以没有需要配置的选项,双击快捷键ESC退出配置) @@ -152,9 +153,9 @@ sudo make menuconfig 3.继续执行以下命令,进行编译 ```shell -sudo make +make 或 -sudo make -j8 +make -j8 ``` make时加上V=1参数可以看到较为详细的编译信息,但是编译过程会比较慢。 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/Makefile index 06e625952..6ab31a006 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/Makefile +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/Makefile @@ -66,4 +66,16 @@ ifeq ($(CONFIG_XIDATONG_SDRAM),y) CSRCS += imxrt_sdram_ini_dcd.c endif +ifeq ($(CONFIG_USBHOST),y) +CSRCS += imxrt_usbhost.c +endif + +ifeq ($(CONFIG_IMXRT_USDHC),y) +CSRCS += imxrt_mmcsd.c +endif + +ifeq ($(CONFIG_XIDATONG_SDIO_AUTOMOUNT),y) +CSRCS += imxrt_mmcsd_automount.c +endif + include $(TOPDIR)/boards/Board.mk 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 eda38f3b0..2aab9d081 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 @@ -43,8 +43,8 @@ #include #include -#ifdef CONFIG_IMXRT_USDHC -# include "imxrt_usdhc.h" +#ifdef CONFIG_USBMONITOR +# include #endif #include "xidatong.h" @@ -90,38 +90,6 @@ static void imxrt_i2c_register(int bus) } #endif -#ifdef CONFIG_IMXRT_USDHC -static int nsh_sdmmc_initialize(void) -{ - struct sdio_dev_s *sdmmc; - int ret = 0; - - /* Get an instance of the SDIO interface */ - - sdmmc = imxrt_usdhc_initialize(0); - if (!sdmmc) - { - syslog(LOG_ERR, "ERROR: Failed to initialize SD/MMC\n"); - } - else - { - /* Bind the SDIO interface to the MMC/SD driver */ - - ret = mmcsd_slotinitialize(0, sdmmc); - if (ret != OK) - { - syslog(LOG_ERR, - "ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", - ret); - } - } - - return OK; -} -#else -# define nsh_sdmmc_initialize() (OK) -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -175,6 +143,25 @@ int imxrt_bringup(void) } #endif +#if defined(CONFIG_IMXRT_USBOTG) || defined(CONFIG_USBHOST) + ret = imxrt_usbhost_initialize(); + if (ret != OK) + { + syslog(LOG_ERR, "ERROR: Failed to start USB host services: %d\n", ret); + return ret; + } +#endif + +#ifdef CONFIG_USBMONITOR + /* Start the USB Monitor */ + + ret = usbmonitor_start(); + if (ret != OK) + { + syslog(LOG_ERR, "ERROR: Failed to start USB monitor: %d\n", ret); + } +#endif + #ifdef CONFIG_DEV_GPIO ret = imxrt_gpio_initialize(); if (ret < 0) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_gpio.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_gpio.c index c5909edd2..4f92668ce 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_gpio.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_gpio.c @@ -110,10 +110,8 @@ static const struct gpio_operations_s gpout_ops = static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] = { - GPIO_GOUT1, - GPIO_GOUT2, - GPIO_GOUT3, - GPIO_GOUT4, + GPIO_E220_M0, + GPIO_E220_M1, }; static struct imxrtgpio_dev_s g_gpout[BOARD_NGPIOOUT]; @@ -177,10 +175,11 @@ static int gpout_write(FAR struct gpio_dev_s *dev, bool value) int imxrt_gpio_initialize(void) { - int pincount = 0; + int pincount; int i; #if BOARD_NGPIOIN > 0 + pincount = 0; for (i = 0; i < BOARD_NGPIOIN; i++) { /* Setup and register the GPIO pin */ @@ -200,6 +199,7 @@ int imxrt_gpio_initialize(void) #endif #if BOARD_NGPIOOUT > 0 + pincount = 0; for (i = 0; i < BOARD_NGPIOOUT; i++) { /* Setup and register the GPIO pin */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_mmcsd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_mmcsd.c new file mode 100644 index 000000000..be2238c36 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_mmcsd.c @@ -0,0 +1,79 @@ +/* +* 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_sdhc_automount.c + * @brief imxrt board sd card automount + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.04.12 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include "xidatong.h" + +#ifdef CONFIG_IMXRT_USDHC + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_sdmmc_initialize + * + * Description: + * Initialize the SDHC SD card slot + * + ****************************************************************************/ + +int nsh_sdmmc_initialize(void) +{ + struct sdio_dev_s *sdmmc; + int ret = 0; + + /* Get an instance of the SDIO interface */ + + sdmmc = imxrt_usdhc_initialize(0); + if (!sdmmc) + { + syslog(LOG_ERR, "ERROR: Failed to initialize SD/MMC\n"); + return -ENODEV; + } + /* Bind the SDIO interface to the MMC/SD driver */ + + ret = mmcsd_slotinitialize(0, sdmmc); + if (ret != OK) + { + syslog(LOG_ERR, "ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + +#ifdef CONFIG_XIDATONG_SDIO_AUTOMOUNT + imxrt_automount_initialize(); + imxrt_usdhc_set_sdio_card_isr(sdmmc, imxrt_sdhc_automount_event, NULL); +#else + imxrt_usdhc_set_sdio_card_isr(sdmmc, NULL, NULL); +#endif + + return OK; +} +#endif \ No newline at end of file diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_mmcsd_automount.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_mmcsd_automount.c new file mode 100644 index 000000000..84b8e539b --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_mmcsd_automount.c @@ -0,0 +1,330 @@ +/* +* 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_sdhc_automount.c + * @brief imxrt board sd card automount + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.04.07 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#if defined(CONFIG_FS_AUTOMOUNTER_DEBUG) && !defined(CONFIG_DEBUG_FS) +# define CONFIG_DEBUG_FS 1 +#endif + +#include +#include + +#include +#include +#include +#include "hardware/imxrt_pinmux.h" +#include "xidatong.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef NULL +# define NULL (FAR void *)0 +#endif + +#ifndef OK +# define OK 0 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure represents the changeable state of the automounter */ + +struct imxrt_automount_state_s +{ + volatile automount_handler_t handler; /* Upper half handler */ + FAR void *arg; /* Handler argument */ + bool enable; /* Fake interrupt enable */ + bool pending; /* Set if there an event while disabled */ +}; + +/* This structure represents the static configuration of an automounter */ + +struct imxrt_automount_config_s +{ + /* This must be first thing in structure so that we can simply cast from + * struct automount_lower_s to struct imxrt_automount_config_s + */ + + struct automount_lower_s lower; /* Publicly visible part */ + FAR struct imxrt_automount_state_s *state; /* Changeable state */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int imxrt_sdhc_attach(FAR const struct automount_lower_s *lower, + automount_handler_t isr, FAR void *arg); +static void imxrt_sdhc_enable(FAR const struct automount_lower_s *lower, + bool enable); +static bool imxrt_sdhc_inserted(FAR const struct automount_lower_s *lower); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct imxrt_automount_state_s g_sdhc_state; +static const struct imxrt_automount_config_s g_sdhc_config = +{ + .lower = + { + .fstype = CONFIG_XIDATONG_SDIO_AUTOMOUNT_FSTYPE, + .blockdev = CONFIG_XIDATONG_SDIO_AUTOMOUNT_BLKDEV, + .mountpoint = CONFIG_XIDATONG_SDIO_AUTOMOUNT_MOUNTPOINT, + .ddelay = MSEC2TICK(CONFIG_XIDATONG_SDIO_AUTOMOUNT_DDELAY), + .udelay = MSEC2TICK(CONFIG_XIDATONG_SDIO_AUTOMOUNT_UDELAY), + .attach = imxrt_sdhc_attach, + .enable = imxrt_sdhc_enable, + .inserted = imxrt_sdhc_inserted + }, + .state = &g_sdhc_state +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_sdhc_attach + * + * Description: + * Attach a new SDHC event handler + * + * Input Parameters: + * lower - An instance of the auto-mounter lower half state structure + * isr - The new event handler to be attach + * arg - Client data to be provided when the event handler is invoked. + * + * Returned Value: + * Always returns OK + * + ****************************************************************************/ + +static int imxrt_sdhc_attach(FAR const struct automount_lower_s *lower, + automount_handler_t isr, FAR void *arg) +{ + FAR const struct imxrt_automount_config_s *config; + FAR struct imxrt_automount_state_s *state; + + /* Recover references to our structure */ + + config = (FAR struct imxrt_automount_config_s *)lower; + DEBUGASSERT(config != NULL && config->state != NULL); + + state = config->state; + + /* Save the new handler info (clearing the handler first to eliminate race + * conditions). + */ + + state->handler = NULL; + state->pending = false; + state->arg = arg; + state->handler = isr; + return OK; +} + +/**************************************************************************** + * Name: imxrt_sdhc_enable + * + * Description: + * Enable card insertion/removal event detection + * + * Input Parameters: + * lower - An instance of the auto-mounter lower half state structure + * enable - True: enable event detection; False: disable + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void imxrt_sdhc_enable(FAR const struct automount_lower_s *lower, + bool enable) +{ + FAR const struct imxrt_automount_config_s *config; + FAR struct imxrt_automount_state_s *state; + irqstate_t flags; + + /* Recover references to our structure */ + + config = (FAR struct imxrt_automount_config_s *)lower; + DEBUGASSERT(config != NULL && config->state != NULL); + + state = config->state; + + /* Save the fake enable setting */ + + flags = enter_critical_section(); + state->enable = enable; + + /* Did an interrupt occur while interrupts were disabled? */ + + if (enable && state->pending) + { + /* Yes.. perform the fake interrupt if the interrutp is attached */ + + if (state->handler) + { + uint8_t inserted = imxrt_gpio_read(PIN_USDHC1_CD); + if (0 == inserted) + { + state->handler(&config->lower, state->arg, true); + } + else + { + state->handler(&config->lower, state->arg, false); + } + } + + state->pending = false; + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: imxrt_sdhc_inserted + * + * Description: + * Check if a card is inserted into the slot. + * + * Input Parameters: + * lower - An instance of the auto-mounter lower half state structure + * + * Returned Value: + * True if the card is inserted; False otherwise + * + ****************************************************************************/ + +static bool imxrt_sdhc_inserted(FAR const struct automount_lower_s *lower) +{ + uint8_t inserted = imxrt_gpio_read(PIN_USDHC1_CD); + if (0 == inserted) + { + return true; + } + + return false; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_sdhc_automount_event + * + * Description: + * The SDHC card detection logic has detected an insertion or removal + * event. + * It has already scheduled the MMC/SD block driver operations. + * Now we need to schedule the auto-mount event which will occur with a + * substantial delay to make sure that everything has settle down. + * + * Input Parameters: + * slotno - Identifies the SDHC0 slot: SDHC0_SLOTNO or SDHC1_SLOTNO. + * There is a terminology problem here: Each SDHC supports two slots, + * slot A and slot B. Only slot A is used. + * So this is not a really a slot, but an HSCMI peripheral number. + * inserted - True if the card is inserted in the slot. False otherwise. + * + * Returned Value: + * None + * + * Assumptions: + * Interrupts are disabled. + * + ****************************************************************************/ + +int imxrt_sdhc_automount_event(void *arg) +{ + FAR const struct imxrt_automount_config_s *config = &g_sdhc_config; + FAR struct imxrt_automount_state_s *state = &g_sdhc_state; + + /* Is the auto-mounter interrupt attached? */ + + if (state->handler) + { + /* Yes.. Have we been asked to hold off interrupts? */ + + if (!state->enable) + { + /* Yes.. just remember that there is a pending interrupt. We will + * deliver the interrupt when interrupts are "re-enabled." + */ + + state->pending = true; + } + else + { + /* No.. forward the event to the handler */ + + uint8_t inserted = imxrt_gpio_read(PIN_USDHC1_CD); + if (0 == inserted) + { + state->handler(&config->lower, state->arg, true); + } + else + { + state->handler(&config->lower, state->arg, false); + } + } + } + return 0; +} + +/**************************************************************************** + * Name: imxrt_automount_initialize + * + * Description: + * Configure auto-mounters for each enable and so configured SDHC + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void imxrt_automount_initialize(void) +{ + FAR void *handle; + + finfo("Initializing automounter(s)\n"); + + /* Initialize the SDHC0 auto-mounter */ + + handle = automount_initialize(&g_sdhc_config.lower); + if (!handle) + { + ferr("ERROR: Failed to initialize auto-mounter for SDHC0\n"); + } +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_usbhost.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_usbhost.c new file mode 100644 index 000000000..f0f96f800 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/imxrt_usbhost.c @@ -0,0 +1,468 @@ +/**************************************************************************** + * boards/arm/imxrt/imxrt1020-evk/src/imxrt_usbhost.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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "hardware/imxrt_pinmux.h" +#include "hardware/imxrt_usbotg.h" +#include "imxrt_periphclks.h" +#include "xidatong.h" + +#include /* Must always be included last */ + +#if defined(CONFIG_IMXRT_USBOTG) || defined(CONFIG_USBHOST) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_USBHOST_DEFPRIO +# define CONFIG_USBHOST_DEFPRIO 50 +#endif + +#ifndef CONFIG_USBHOST_STACKSIZE +# ifdef CONFIG_USBHOST_HUB +# define CONFIG_USBHOST_STACKSIZE 1536 +# else +# define CONFIG_USBHOST_STACKSIZE 1024 +# endif +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Retained device driver handle */ + +static struct usbhost_connection_s *g_ehciconn; + +#ifdef CONFIG_XIDATONG_USB_AUTOMOUNT +/* Unmount retry timer */ + +static struct wdog_s g_umount_tmr[CONFIG_XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ehci_waiter + * + * Description: + * Wait for USB devices to be connected to the EHCI root hub. + * + ****************************************************************************/ + +static int ehci_waiter(int argc, char *argv[]) +{ + FAR struct usbhost_hubport_s *hport; + + uinfo("ehci_waiter: Running\n"); + for (; ; ) + { + /* Wait for the device to change state */ + + DEBUGVERIFY(CONN_WAIT(g_ehciconn, &hport)); + syslog(LOG_INFO, "ehci_waiter: %s\n", + hport->connected ? "connected" : "disconnected"); + + /* Did we just become connected? */ + + if (hport->connected) + { + /* Yes.. enumerate the newly connected device */ + + CONN_ENUMERATE(g_ehciconn, hport); + } + } + + /* Keep the compiler from complaining */ + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_XIDATONG_USB_AUTOMOUNT +/**************************************************************************** + * Name: usb_msc_connect + * + * Description: + * Mount the USB mass storage device + * + ****************************************************************************/ + +static void usb_msc_connect(FAR void *arg) +{ + int index = (int)arg; + char sdchar = 'a' + index; + int ret; + + char blkdev[32]; + char mntpnt[32]; + + DEBUGASSERT(index >= 0 && + index < CONFIG_XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV); + + wd_cancel(&g_umount_tmr[index]); + + /* Resetup the event. */ + + usbhost_msc_notifier_setup(usb_msc_connect, WORK_USB_MSC_CONNECT, + sdchar, arg); + + snprintf(blkdev, sizeof(blkdev), "%s%c", + CONFIG_XIDATONG_USB_AUTOMOUNT_BLKDEV, sdchar); + snprintf(mntpnt, sizeof(mntpnt), "%s%c", + CONFIG_XIDATONG_USB_AUTOMOUNT_MOUNTPOINT, sdchar); + + /* Mount */ + + ret = nx_mount((FAR const char *)blkdev, (FAR const char *)mntpnt, + CONFIG_XIDATONG_USB_AUTOMOUNT_FSTYPE, 0, NULL); + if (ret < 0) + { + ferr("ERROR: Mount failed: %d\n", ret); + } +} + +/**************************************************************************** + * Name: unmount_retry_timeout + * + * Description: + * A previous unmount failed because the volume was busy... busy meaning + * the volume could not be unmounted because there are open references + * the files or directories in the volume. When this failure occurred, + * the unmount logic setup a delay and this function is called as a result + * of that delay timeout. + * + * This function will attempt the unmount again. + * + * Input Parameters: + * Standard wdog timeout parameters + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void unmount_retry_timeout(wdparm_t arg) +{ + int index = arg; + char sdchar = 'a' + index; + + finfo("Timeout!\n"); + DEBUGASSERT(index >= 0 && + index < CONFIG_XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV); + + /* Resend the notification. */ + + usbhost_msc_notifier_signal(WORK_USB_MSC_DISCONNECT, sdchar); +} + +/**************************************************************************** + * Name: usb_msc_disconnect + * + * Description: + * Unmount the USB mass storage device + * + ****************************************************************************/ + +static void usb_msc_disconnect(FAR void *arg) +{ + int index = (int)arg; + char sdchar = 'a' + index; + int ret; + + char mntpnt[32]; + + DEBUGASSERT(index >= 0 && + index < CONFIG_XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV); + + wd_cancel(&g_umount_tmr[index]); + + /* Resetup the event. */ + + usbhost_msc_notifier_setup(usb_msc_disconnect, WORK_USB_MSC_DISCONNECT, + sdchar, arg); + + snprintf(mntpnt, sizeof(mntpnt), "%s%c", + CONFIG_XIDATONG_USB_AUTOMOUNT_MOUNTPOINT, sdchar); + + /* Unmount */ + + ret = nx_umount2((FAR const char *)mntpnt, MNT_FORCE); + if (ret < 0) + { + /* We expect the error to be EBUSY meaning that the volume could + * not be unmounted because there are currently reference via open + * files or directories. + */ + + if (ret == -EBUSY) + { + finfo("WARNING: Volume is busy, try again later\n"); + + /* Start a timer to retry the umount2 after a delay */ + + ret = wd_start(&g_umount_tmr[index], + MSEC2TICK(CONFIG_XIDATONG_USB_AUTOMOUNT_UDELAY), + unmount_retry_timeout, index); + if (ret < 0) + { + ferr("ERROR: wd_start failed: %d\n", ret); + } + } + + /* Other errors are fatal */ + + else + { + ferr("ERROR: Unmount failed!\n"); + } + } +} +#endif /* CONFIG_XIDATONG_USB_AUTOMOUNT */ + + +/**************************************************************************** + * Name: imxrt_usbhost_initialize + * + * Description: + * Called at application startup time to initialize the USB host + * functionality. + * This function will start a thread that will monitor for device + * connection/disconnection events. + * + ****************************************************************************/ + +int imxrt_usbhost_initialize(void) +{ + pid_t pid; + int ret; +#ifdef CONFIG_XIDATONG_USB_AUTOMOUNT + int index; +#endif + + imxrt_clockall_usboh3(); + + /* Make sure we don't accidentally switch on USB bus power */ + + *((uint32_t *)IMXRT_USBNC_USB_OTG2_CTRL) = USBNC_PWR_POL; + *((uint32_t *)0x400d9030) = (1 << 21); + *((uint32_t *)0x400d9000) = 0; + + /* Setup pins, with power initially off */ + + imxrt_config_gpio(GPIO_USBOTG_ID); + + /* First, register all of the class drivers needed to support the drivers + * that we care about + */ + +#ifdef CONFIG_USBHOST_HUB + /* Initialize USB hub support */ + + ret = usbhost_hub_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: usbhost_hub_initialize failed: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_MSC + /* Register the USB host Mass Storage Class */ + +#ifdef CONFIG_XIDATONG_USB_AUTOMOUNT + /* Initialize the notifier listener for automount */ + + for (index = 0; index < CONFIG_XIDATONG_USB_AUTOMOUNT_NUM_BLKDEV; index++) + { + char sdchar = 'a' + index; + + usbhost_msc_notifier_setup(usb_msc_connect, + WORK_USB_MSC_CONNECT, sdchar, (FAR void *)(intptr_t)index); + usbhost_msc_notifier_setup(usb_msc_disconnect, + WORK_USB_MSC_DISCONNECT, sdchar, (FAR void *)(intptr_t)index); + } +#endif + + ret = usbhost_msc_initialize(); + if (ret != OK) + { + syslog(LOG_ERR, + "ERROR: Failed to register the mass storage class: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_CDCACM + /* Register the CDC/ACM serial class */ + + ret = usbhost_cdcacm_initialize(); + if (ret != OK) + { + uerr("ERROR: Failed to register the CDC/ACM serial class\n"); + } +#endif + +#ifdef CONFIG_USBHOST_HIDKBD + /* Register the USB host HID keyboard class driver */ + + ret = usbhost_kbdinit(); + if (ret != OK) + { + uerr("ERROR: Failed to register the KBD class\n"); + } +#endif + + /* Then get an instance of the USB EHCI interface. */ + + g_ehciconn = imxrt_ehci_initialize(0); + + if (!g_ehciconn) + { + uerr("ERROR: imxrt_ehci_initialize failed\n"); + return -ENODEV; + } + + /* Start a thread to handle device connection. */ + + pid = kthread_create("EHCI Monitor", CONFIG_USBHOST_DEFPRIO, + CONFIG_USBHOST_STACKSIZE, + (main_t)ehci_waiter, (FAR char * const *)NULL); + if (pid < 0) + { + uerr("ERROR: Failed to create ehci_waiter task: %d\n", ret); + return -ENODEV; + } + + return OK; +} + +/**************************************************************************** + * Name: imxrt_usbhost_vbusdrive + * + * Description: + * Enable/disable driving of VBUS 5V output. This function must be + * provided by each platform that implements the OHCI or EHCI host + * interface + * + * Input Parameters: + * rhport - Selects root hub port to be powered host interface. + * Since the IMXRT has only a downstream port, zero is + * the only possible value for this parameter. + * enable - true: enable VBUS power; false: disable VBUS power + * + * Returned Value: + * None + * + ****************************************************************************/ + +#define HCOR ((volatile struct ehci_hcor_s *)IMXRT_USBOTG_HCOR_BASE) + +void imxrt_usbhost_vbusdrive(int rhport, bool enable) +{ + uint32_t regval; + + uinfo("RHPort%d: enable=%d\n", rhport + 1, enable); + + /* The IMXRT has only a single root hub port */ + + if (rhport == 0) + { + /* Then enable or disable VBUS power */ + + regval = HCOR->portsc[rhport]; + regval &= ~EHCI_PORTSC_PP; + if (enable) + { + regval |= EHCI_PORTSC_PP; + } + + HCOR->portsc[rhport] = regval; + } +} + +/**************************************************************************** + * Name: imxrt_setup_overcurrent + * + * Description: + * Setup to receive an interrupt-level callback if an overcurrent condition + * is detected. + * + * Input Parameters: + * handler - New overcurrent interrupt handler + * arg - The argument that will accompany the interrupt + * + * Returned Value: + * Zero (OK) returned on success; a negated errno value is returned on + * failure. + * + ****************************************************************************/ + +#if 0 /* Not ready yet */ +int imxrt_setup_overcurrent(xcpt_t handler, void *arg) +{ + irqstate_t flags; + + /* Disable interrupts until we are done. This guarantees that the + * following operations are atomic. + */ + + flags = enter_critical_section(); + + /* Configure the interrupt */ + +#warning Missing logic + + leave_critical_section(flags); + return OK; +} +#endif /* 0 */ + +#endif /* CONFIG_IMXRT_USBOTG || CONFIG_USBHOST */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/xidatong.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/xidatong.h index d8828d756..f4a88b1e2 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/xidatong.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong/src/xidatong.h @@ -41,9 +41,13 @@ #include #include +#include +#include #include "imxrt_gpio.h" #include "imxrt_iomuxc.h" +#include "imxrt_usdhc.h" +#include /**************************************************************************** * Pre-processor Definitions @@ -63,21 +67,15 @@ /* Test Pins ****************************************************************/ #define BOARD_NGPIOIN 0 /* Amount of GPIO Input pins */ -#define BOARD_NGPIOOUT 4 /* Amount of GPIO Output pins */ +#define BOARD_NGPIOOUT 2 /* Amount of GPIO Output pins */ #define BOARD_NGPIOINT 0 /* Amount of GPIO Input w/ Interruption pins */ -#define GPIO_GOUT1 (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_GOUT_DEFAULT | \ - GPIO_PORT1 | GPIO_PIN19) - -#define GPIO_GOUT2 (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_GOUT_DEFAULT | \ - GPIO_PIN18 | GPIO_PORT1) - -#define GPIO_GOUT3 (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_GOUT_DEFAULT | \ - GPIO_PIN10 | GPIO_PORT1) - -#define GPIO_GOUT4 (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_GOUT_DEFAULT | \ +#define GPIO_E220_M0 (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_GOUT_DEFAULT | \ GPIO_PIN9 | GPIO_PORT1) +#define GPIO_E220_M1 (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | IOMUX_GOUT_DEFAULT | \ + GPIO_PIN11 | GPIO_PORT1) + /* Backlight */ #define GPIO_LCD_BL (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | GPIO_PORT2 | \ @@ -119,6 +117,10 @@ #define GPIO_MMCSD_EN (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | \ GPIO_PORT3 | GPIO_PIN2 | IOMUX_MMCSD_EN) +/* USB OTG ID Pin: GPIO_AD_B1_01 */ + +#define GPIO_USBOTG_ID (GPIO_USB_OTG1_ID_2 | IOMUX_USBOTG_ID_DEFAULT) /* GPIO_AD_B1_01 */ + /**************************************************************************** * Public Types ****************************************************************************/ @@ -198,5 +200,20 @@ void imxrt_autoled_initialize(void); int imxrt_gpio_initialize(void); #endif +#if defined(CONFIG_IMXRT_USBOTG) || defined(CONFIG_USBHOST) +int imxrt_usbhost_initialize(void); +#endif + +#ifdef CONFIG_IMXRT_USDHC +int nsh_sdmmc_initialize(void); +#else +# define nsh_sdmmc_initialize() (OK) +#endif + +#if defined(CONFIG_IMXRT_USDHC) && defined(CONFIG_XIDATONG_SDIO_AUTOMOUNT) +int imxrt_sdhc_automount_event(void *arg); +void imxrt_automount_initialize(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __BOARDS_ARM_IMXRT_XIDATONG_SRC_XIDATONG_H */ 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 f84148ed5..7b7c97034 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig @@ -652,7 +652,7 @@ config NSH_DISABLE_RECVZIGBEE default n config NSH_DISABLE_ADAPTER_LORATEST - bool "Disable sx128 AdapterLoraTest." + bool "Disable sx1278 AdapterLoraTest." default n config NSH_DISABLE_K210_FFT diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/build.sh b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/build.sh index c8bb5ca86..89b0edaf3 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/build.sh +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/build.sh @@ -11,7 +11,6 @@ git submodule update Ubiquitous/Nuttx_Fusion_XiUOS/apps git submodule update Ubiquitous/Nuttx_Fusion_XiUOS/nuttx cd $current -chmod -R +x $top find $top -name Kconfig -exec dos2unix -q {} \; cp -rf $current/nuttx $nuttx diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/hardware/imxrt_usbotg.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/hardware/imxrt_usbotg.h new file mode 100644 index 000000000..3d83733ce --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/hardware/imxrt_usbotg.h @@ -0,0 +1,739 @@ +/**************************************************************************** + * arch/arm/src/imxrt/hardware/imxrt_usbotg.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT_USBOTG_H +#define __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT_USBOTG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IMXRT_EHCI_NRHPORT 1 /* There is only a single root hub port */ + +/* USBOTG register offsets (with respect to IMXRT_USB_BASE) *****************/ + + /* 0x000 - 0x0ff: Reserved */ + +/* Device/host capability registers */ + +#define IMXRT_USBOTG_HCCR_OFFSET 0x100 /* Offset to EHCI Host Controller Capabiliy registers */ +#define IMXRT_USBOTG_CAPLENGTH_OFFSET 0x100 /* Capability register length (8-bit) */ +#define IMXRT_USBHOST_HCIVERSION_OFFSET 0x102 /* Host interface version number (16-bit) */ +#define IMXRT_USBHOST_HCSPARAMS_OFFSET 0x104 /* Host controller structural parameters */ +#define IMXRT_USBHOST_HCCPARAMS_OFFSET 0x108 /* Host controller capability parameters */ +#define IMXRT_USBDEV_DCIVERSION_OFFSET 0x120 /* Device interface version number */ +#define IMXRT_USBDEV_DCCPARAMS_OFFSET 0x124 /* Device controller capability parameters */ + +/* Device/host/OTG operational registers */ + +#define IMXRT_USBOTG_HCOR_OFFSET 0x140 /* Offset to EHCI Host Controller Operational Registers */ +#define IMXRT_USBOTG_USBCMD_OFFSET 0x140 /* USB command (both) */ +#define IMXRT_USBOTG_USBSTS_OFFSET 0x144 /* USB status (both) */ +#define IMXRT_USBOTG_USBINTR_OFFSET 0x148 /* USB interrupt enable (both) */ +#define IMXRT_USBOTG_FRINDEX_OFFSET 0x14c /* USB frame index (both) */ + /* EHCI 4G Segment Selector (not supported) */ +#define IMXRT_USBOTG_PERIODICLIST_OFFSET 0x154 /* Frame list base address (host) */ +#define IMXRT_USBOTG_DEVICEADDR_OFFSET 0x154 /* USB device address (device) */ +#define IMXRT_USBOTG_ASYNCLISTADDR_OFFSET 0x158 /* Next asynchronous list address (host) */ +#define IMXRT_USBOTG_ENDPOINTLIST_OFFSET 0x158 /* Address of endpoint list in memory (device) */ +#define IMXRT_USBOTG_TTCTRL_OFFSET 0x15c /* Asynchronous buffer status for embedded TT (host) */ +#define IMXRT_USBOTG_BURSTSIZE_OFFSET 0x160 /* Programmable burst size (both) */ +#define IMXRT_USBOTG_TXFILLTUNING_OFFSET 0x164 /* Host transmit pre-buffer packet tuning (host) */ +#define IMXRT_USBOTG_BINTERVAL_OFFSET 0x174 /* Length of virtual frame (both) */ +#define IMXRT_USBOTG_ENDPTNAK_OFFSET 0x178 /* Endpoint NAK (device) */ +#define IMXRT_USBOTG_ENDPTNAKEN_OFFSET 0x17c /* Endpoint NAK Enable (device) */ +#define IMXRT_USBOTG_CONFIGFLAG_OFFSET 0x180 /* Configured flag register (not used in lpc313x) */ +#define IMXRT_USBOTG_PORTSC1_OFFSET 0x184 /* Port status/control 1 (both) */ +#define IMXRT_USBOTG_OTGSC_OFFSET 0x1a4 /* OTG status and control (otg) */ +#define IMXRT_USBOTG_USBMODE_OFFSET 0x1a8 /* USB device mode (both) */ + +#define IMXRT_USBDEV_USBCMD_OFFSET 0x140 /* USB command (both) */ +#define IMXRT_USBDEV_USBSTS_OFFSET 0x144 /* USB status (both) */ +#define IMXRT_USBDEV_USBINTR_OFFSET 0x148 /* USB interrupt enable (both) */ +#define IMXRT_USBDEV_FRINDEX_OFFSET 0x14c /* USB frame index (both) */ +#define IMXRT_USBDEV_DEVICEADDR_OFFSET 0x154 /* USB device address (device) */ +#define IMXRT_USBDEV_ENDPOINTLIST_OFFSET 0x158 /* Address of endpoint list in memory (device) */ +#define IMXRT_USBDEV_BURSTSIZE_OFFSET 0x160 /* Programmable burst size (both) */ +#define IMXRT_USBDEV_BINTERVAL_OFFSET 0x174 /* Length of virtual frame (both) */ +#define IMXRT_USBDEV_ENDPTNAK_OFFSET 0x178 /* Endpoint NAK (device) */ +#define IMXRT_USBDEV_ENDPTNAKEN_OFFSET 0x17c /* Endpoint NAK Enable (device) */ +#define IMXRT_USBDEV_PORTSC1_OFFSET 0x184 /* Port status/control 1 (both) */ +#define IMXRT_USBDEV_USBMODE_OFFSET 0x1a8 /* USB device mode (both) */ + +#define IMXRT_USBHOST_USBCMD_OFFSET 0x140 /* USB command (both) */ +#define IMXRT_USBHOST_USBSTS_OFFSET 0x144 /* USB status (both) */ +#define IMXRT_USBHOST_USBINTR_OFFSET 0x148 /* USB interrupt enable (both) */ +#define IMXRT_USBHOST_FRINDEX_OFFSET 0x14c /* USB frame index (both) */ +#define IMXRT_USBHOST_PERIODICLIST_OFFSET 0x154 /* Frame list base address (host) */ +#define IMXRT_USBHOST_ASYNCLISTADDR_OFFSET 0x158 /* Next asynchronous list address (host) */ +#define IMXRT_USBHOST_TTCTRL_OFFSET 0x15c /* Asynchronous buffer status for embedded TT (host) */ +#define IMXRT_USBHOST_BURSTSIZE_OFFSET 0x160 /* Programmable burst size (both) */ +#define IMXRT_USBHOST_TXFILLTUNING_OFFSET 0x164 /* Host transmit pre-buffer packet tuning (host) */ +#define IMXRT_USBHOST_BINTERVAL_OFFSET 0x174 /* Length of virtual frame (both) */ +#define IMXRT_USBHOST_PORTSC1_OFFSET 0x184 /* Port status/control 1 (both) */ +#define IMXRT_USBHOST_USBMODE_OFFSET 0x1a8 /* USB device mode (both) */ + +/* Device endpoint registers */ + +#define IMXRT_USBDEV_ENDPTSETUPSTAT_OFFSET 0x1ac /* Endpoint setup status */ +#define IMXRT_USBDEV_ENDPTPRIME_OFFSET 0x1b0 /* Endpoint initialization */ +#define IMXRT_USBDEV_ENDPTFLUSH_OFFSET 0x1b4 /* Endpoint de-initialization */ +#define IMXRT_USBDEV_ENDPTSTATUS_OFFSET 0x1b8 /* Endpoint status */ +#define IMXRT_USBDEV_ENDPTCOMPLETE_OFFSET 0x1bc /* Endpoint complete */ + +#define IMXRT_USBDEV_ENDPTCTRL_OFFSET(n) (IMXRT_USBDEV_ENDPTCTRL0_OFFSET + ((n) * 4)) +#define IMXRT_USBDEV_ENDPTCTRL0_OFFSET 0x1c0 /* Endpoint control 0 */ +#define IMXRT_USBDEV_ENDPTCTRL1_OFFSET 0x1c4 /* Endpoint control 1 */ +#define IMXRT_USBDEV_ENDPTCTRL2_OFFSET 0x1c8 /* Endpoint control 2 */ +#define IMXRT_USBDEV_ENDPTCTRL3_OFFSET 0x1cc /* Endpoint control 3 */ +#define IMXRT_USBDEV_ENDPTCTRL4_OFFSET 0x1d0 /* Endpoint control 4 */ +#define IMXRT_USBDEV_ENDPTCTRL5_OFFSET 0x1d4 /* Endpoint control 5 */ +#define IMXRT_USBDEV_ENDPTCTRL6_OFFSET 0x1d8 /* Endpoint control 6 */ +#define IMXRT_USBDEV_ENDPTCTRL7_OFFSET 0x1dc /* Endpoint control 7 */ + +/* USB Non-core memory map & register definition */ + +#define IMXRT_USBNC_USB_OTG1_CTRL_OFFSET 0x0800 /* OTG1 Control Register */ +#define IMXRT_USBNC_USB_OTG2_CTRL_OFFSET 0x0800 /* OTG2 Control Register */ +#define IMXRT_USBNC_USB_OTG1_PHY_CTRL_0_OFFSET 0x0818 /* OTG1 Phy Control Register */ +#define IMXRT_USBNC_USB_OTG2_PHY_CTRL_0_OFFSET 0x0818 /* OTG2 Phy Control Register */ + +/* USBOTG register (virtual) addresses **************************************/ + +/* Device/host capability registers */ + +#define IMXRT_USBOTG_HCCR_BASE (IMXRT_USB_BASE + IMXRT_USBOTG_HCCR_OFFSET) +#define IMXRT_USBOTG_CAPLENGTH (IMXRT_USB_BASE + IMXRT_USBOTG_CAPLENGTH_OFFSET) +#define IMXRT_USBHOST_HCIVERSION (IMXRT_USB_BASE + IMXRT_USBHOST_HCIVERSION_OFFSET) +#define IMXRT_USBHOST_HCSPARAMS (IMXRT_USB_BASE + IMXRT_USBHOST_HCSPARAMS_OFFSET) +#define IMXRT_USBHOST_HCCPARAMS (IMXRT_USB_BASE + IMXRT_USBHOST_HCCPARAMS_OFFSET) +#define IMXRT_USBDEV_DCIVERSION (IMXRT_USB_BASE + IMXRT_USBDEV_DCIVERSION_OFFSET) +#define IMXRT_USBDEV_DCCPARAMS (IMXRT_USB_BASE + IMXRT_USBDEV_DCCPARAMS_OFFSET) + +/* Device/host operational registers */ + +#define IMXRT_USBOTG_HCOR_BASE (IMXRT_USB_BASE + IMXRT_USBOTG_HCOR_OFFSET) +#define IMXRT_USBOTG_USBCMD (IMXRT_USB_BASE + IMXRT_USBOTG_USBCMD_OFFSET) +#define IMXRT_USBOTG_USBSTS (IMXRT_USB_BASE + IMXRT_USBOTG_USBSTS_OFFSET) +#define IMXRT_USBOTG_USBINTR (IMXRT_USB_BASE + IMXRT_USBOTG_USBINTR_OFFSET) +#define IMXRT_USBOTG_FRINDEX (IMXRT_USB_BASE + IMXRT_USBOTG_FRINDEX_OFFSET) +#define IMXRT_USBOTG_PERIODICLIST (IMXRT_USB_BASE + IMXRT_USBOTG_PERIODICLIST_OFFSET) +#define IMXRT_USBOTG_DEVICEADDR (IMXRT_USB_BASE + IMXRT_USBOTG_DEVICEADDR_OFFSET) +#define IMXRT_USBOTG_ASYNCLISTADDR (IMXRT_USB_BASE + IMXRT_USBOTG_ASYNCLISTADDR_OFFSET) +#define IMXRT_USBOTG_ENDPOINTLIST (IMXRT_USB_BASE + IMXRT_USBOTG_ENDPOINTLIST_OFFSET) +#define IMXRT_USBOTG_TTCTRL (IMXRT_USB_BASE + IMXRT_USBOTG_TTCTRL_OFFSET) +#define IMXRT_USBOTG_BURSTSIZE (IMXRT_USB_BASE + IMXRT_USBOTG_BURSTSIZE_OFFSET) +#define IMXRT_USBOTG_TXFILLTUNING (IMXRT_USB_BASE + IMXRT_USBOTG_TXFILLTUNING_OFFSET) +#define IMXRT_USBOTG_BINTERVAL (IMXRT_USB_BASE + IMXRT_USBOTG_BINTERVAL_OFFSET) +#define IMXRT_USBOTG_ENDPTNAK (IMXRT_USB_BASE + IMXRT_USBOTG_ENDPTNAK_OFFSET) +#define IMXRT_USBOTG_ENDPTNAKEN (IMXRT_USB_BASE + IMXRT_USBOTG_ENDPTNAKEN_OFFSET) +#define IMXRT_USBOTG_PORTSC1 (IMXRT_USB_BASE + IMXRT_USBOTG_PORTSC1_OFFSET) +#define IMXRT_USBOTG_OTGSC (IMXRT_USB_BASE + IMXRT_USBOTG_OTGSC_OFFSET) +#define IMXRT_USBOTG_USBMODE (IMXRT_USB_BASE + IMXRT_USBOTG_USBMODE_OFFSET) + +#define IMXRT_USBDEV_USBCMD (IMXRT_USB_BASE + IMXRT_USBDEV_USBCMD_OFFSET) +#define IMXRT_USBDEV_USBSTS (IMXRT_USB_BASE + IMXRT_USBDEV_USBSTS_OFFSET) +#define IMXRT_USBDEV_USBINTR (IMXRT_USB_BASE + IMXRT_USBDEV_USBINTR_OFFSET) +#define IMXRT_USBDEV_FRINDEX (IMXRT_USB_BASE + IMXRT_USBDEV_FRINDEX_OFFSET) +#define IMXRT_USBDEV_DEVICEADDR (IMXRT_USB_BASE + IMXRT_USBDEV_DEVICEADDR_OFFSET) +#define IMXRT_USBDEV_ENDPOINTLIST (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPOINTLIST_OFFSET) +#define IMXRT_USBDEV_BURSTSIZE (IMXRT_USB_BASE + IMXRT_USBDEV_BURSTSIZE_OFFSET) +#define IMXRT_USBDEV_BINTERVAL (IMXRT_USB_BASE + IMXRT_USBDEV_BINTERVAL_OFFSET) +#define IMXRT_USBDEV_ENDPTNAK (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTNAK_OFFSET) +#define IMXRT_USBDEV_ENDPTNAKEN (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTNAKEN_OFFSET) +#define IMXRT_USBDEV_PORTSC1 (IMXRT_USB_BASE + IMXRT_USBDEV_PORTSC1_OFFSET) +#define IMXRT_USBDEV_USBMODE (IMXRT_USB_BASE + IMXRT_USBDEV_USBMODE_OFFSET) + +#define IMXRT_USBHOST_USBCMD (IMXRT_USB_BASE + IMXRT_USBHOST_USBCMD_OFFSET) +#define IMXRT_USBHOST_USBSTS (IMXRT_USB_BASE + IMXRT_USBHOST_USBSTS_OFFSET) +#define IMXRT_USBHOST_USBINTR (IMXRT_USB_BASE + IMXRT_USBHOST_USBINTR_OFFSET) +#define IMXRT_USBHOST_FRINDEX (IMXRT_USB_BASE + IMXRT_USBHOST_FRINDEX_OFFSET) +#define IMXRT_USBHOST_PERIODICLIST (IMXRT_USB_BASE + IMXRT_USBHOST_PERIODICLIST_OFFSET) +#define IMXRT_USBHOST_ASYNCLISTADDR (IMXRT_USB_BASE + IMXRT_USBHOST_ASYNCLISTADDR_OFFSET) +#define IMXRT_USBHOST_TTCTRL (IMXRT_USB_BASE + IMXRT_USBHOST_TTCTRL_OFFSET) +#define IMXRT_USBHOST_BURSTSIZE (IMXRT_USB_BASE + IMXRT_USBHOST_BURSTSIZE_OFFSET) +#define IMXRT_USBHOST_TXFILLTUNING (IMXRT_USB_BASE + IMXRT_USBHOST_TXFILLTUNING_OFFSET) +#define IMXRT_USBHOST_BINTERVAL (IMXRT_USB_BASE + IMXRT_USBHOST_BINTERVAL_OFFSET) +#define IMXRT_USBHOST_PORTSC1 (IMXRT_USB_BASE + IMXRT_USBHOST_PORTSC1_OFFSET) +#define IMXRT_USBHOST_USBMODE (IMXRT_USB_BASE + IMXRT_USBHOST_USBMODE_OFFSET) + +/* Device endpoint registers */ + +#define IMXRT_USBDEV_ENDPTSETUPSTAT (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTSETUPSTAT_OFFSET) +#define IMXRT_USBDEV_ENDPTPRIME (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTPRIME_OFFSET) +#define IMXRT_USBDEV_ENDPTFLUSH (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTFLUSH_OFFSET) +#define IMXRT_USBDEV_ENDPTSTATUS (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTSTATUS_OFFSET) +#define IMXRT_USBDEV_ENDPTCOMPLETE (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTCOMPLETE_OFFSET) + +#define IMXRT_USBDEV_ENDPTCTRL(n) (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTCTRL_OFFSET(n)) +#define IMXRT_USBDEV_ENDPTCTRL0 (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTCTRL0_OFFSET) +#define IMXRT_USBDEV_ENDPTCTRL1 (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTCTRL1_OFFSET) +#define IMXRT_USBDEV_ENDPTCTRL2 (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTCTRL2_OFFSET) +#define IMXRT_USBDEV_ENDPTCTRL3 (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTCTRL3_OFFSET) +#define IMXRT_USBDEV_ENDPTCTRL4 (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTCTRL4_OFFSET) +#define IMXRT_USBDEV_ENDPTCTRL5 (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTCTRL5_OFFSET) +#define IMXRT_USBDEV_ENDPTCTRL6 (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTCTRL6_OFFSET) +#define IMXRT_USBDEV_ENDPTCTRL7 (IMXRT_USB_BASE + IMXRT_USBDEV_ENDPTCTRL7_OFFSET) + +/* Device non-core registers */ + +#define IMXRT_USBNC_USB_OTG1_CTRL (IMXRT_USB_BASE + IMXRT_USBNC_USB_OTG1_CTRL_OFFSET) +#define IMXRT_USBNC_USB_OTG1_PHY_CTRL_0 (IMXRT_USB_BASE + IMXRT_USBNC_USB_OTG1_PHY_CTRL_0_OFFSET) + +#define IMXRT_USBNC_USB_OTG2_CTRL (IMXRT_USB_BASE + IMXRT_USBNC_USB_OTG2_CTRL_OFFSET) +#define IMXRT_USBNC_USB_OTG2_PHY_CTRL_0 (IMXRT_USB_BASE + IMXRT_USBNC_USB_OTG2_PHY_CTRL_0_OFFSET) + +/* USBOTG register bit definitions ******************************************/ + +/* Device/host capability registers */ + +/* CAPLENGTH */ + +#define USBOTG_CAPLENGTH_SHIFT (0) /* Bits 0-7: Offset from register base to operational regs */ +#define USBOTG_CAPLENGTH_MASK (0xff << USBOTG_CAPLENGTH_SHIFT) + +/* HCIVERSION */ + +#define USBHOST_HCIVERSION_SHIFT (0) /* Bits 0-15: BCD encoding of the EHCI revision number */ +#define USBHOST_HCIVERSION_MASK (0xffff << USBHOST_HCIVERSION_SHIFT) + +/* HCSPARAMS */ + +#define USBHOST_HCSPARAMS_NTT_SHIFT (24) /* Bits 24-27: Number of Transaction Translators */ +#define USBHOST_HCSPARAMS_NTT_MASK (15 << USBHOST_HCSPARAMS_NTT_SHIFT) +#define USBHOST_HCSPARAMS_NPTT_SHIFT (20) /* Bits 20-23: Number of Ports per Transaction Translator */ +#define USBHOST_HCSPARAMS_NPTT_MASK (15 << USBHOST_HCSPARAMS_NPTT_SHIFT) +#define USBHOST_HCSPARAMS_PI (1 >> 16) /* Bit 16: Port indicators */ +#define USBHOST_HCSPARAMS_NCC_SHIFT (15) /* Bits 12-15: Number of Companion Controller */ +#define USBHOST_HCSPARAMS_NCC_MASK (15 << USBHOST_HCSPARAMS_NCC_SHIFT) +#define USBHOST_HCSPARAMS_NPCC_SHIFT (8) /* Bits 8-11: Number of Ports per Companion Controller */ +#define USBHOST_HCSPARAMS_NPCC_MASK (15 << USBHOST_HCSPARAMS_NPCC_SHIFT) +#define USBHOST_HCSPARAMS_PPC (1 >> 4) /* Bit 4: Port Power Control */ +#define USBHOST_HCSPARAMS_NPORTS_SHIF (0) /* Bits 0-3: Number of downstream ports */ +#define USBHOST_HCSPARAMS_NPORTS_MASK (15 << USBHOST_HCSPARAMS_NPORTS_SHIFT) + +/* HCCPARAMS */ + +#define USBHOST_HCCPARAMS_EECP_SHIFT (8) /* Bits 8-15: EHCI Extended Capabilities Pointer */ +#define USBHOST_HCCPARAMS_EECP_MASK (255 << USBHOST_HCCPARAMS_EECP_SHIFT) +#define USBHOST_HCCPARAMS_IST_SHIFT (4) /* Bits 4-7: Isochronous Scheduling Threshold */ +#define USBHOST_HCCPARAMS_IST_MASK (15 << USBHOST_HCCPARAMS_IST_SHIFT) +#define USBHOST_HCCPARAMS_ASP (1 >> 2) /* Bit 2: Asynchronous Schedule Park Capability */ +#define USBHOST_HCCPARAMS_PFL (1 >> 1) /* Bit 1: Programmable Frame List Flag */ +#define USBHOST_HCCPARAMS_ADC (1 >> 0) /* Bit 0: 64-bit Addressing Capability */ + +/* DCIVERSION */ + +#define USBDEV_DCIVERSION_SHIFT (0) /* Bits 0-15: BCD encoding of the device interface */ +#define USBDEV_DCIVERSION_MASK (0xffff << USBDEV_DCIVERSION_SHIFT) + +/* DCCPARAMS */ + +#define USBDEV_DCCPARAMS_HC (1 >> 8) /* Bit 8: Host Capable */ +#define USBDEV_DCCPARAMS_DC (1 >> 7) /* Bit 7: Device Capable */ +#define USBDEV_DCCPARAMS_DEN_SHIFT (0) /* Bits 0-4: DEN Device Endpoint Number */ +#define USBDEV_DCCPARAMS_DEN_MASK (31 << USBDEV_DCCPARAMS_DEN_SHIFT) + +/* Device/host operational registers */ + +/* USB Command register USBCMD -- Device Mode */ + +#define USBDEV_USBCMD_ITC_SHIFT (16) /* Bits 16-23: Interrupt threshold control */ +#define USBDEV_USBCMD_ITC_MASK (255 << USBDEV_USBCMD_ITC_SHIFT) +# define USBDEV_USBCMD_ITCIMME (0 << USBDEV_USBCMD_ITC_SHIFT) /* Immediate (no threshold) */ +# define USBDEV_USBCMD_ITC1UF (1 << USBDEV_USBCMD_ITC_SHIFT) /* 1 micro frame */ +# define USBDEV_USBCMD_ITC2UF (2 << USBDEV_USBCMD_ITC_SHIFT) /* 2 micro frames */ +# define USBDEV_USBCMD_ITC4UF (4 << USBDEV_USBCMD_ITC_SHIFT) /* 4 micro frames */ +# define USBDEV_USBCMD_ITC8UF (8 << USBDEV_USBCMD_ITC_SHIFT) /* 8 micro frames */ +# define USBDEV_USBCMD_ITC16UF (16 << USBDEV_USBCMD_ITC_SHIFT) /* 16 micro frames */ +# define USBDEV_USBCMD_ITC32UF (32 << USBDEV_USBCMD_ITC_SHIFT) /* 32 micro frames */ +# define USBDEV_USBCMD_ITC64UF (64 << USBDEV_USBCMD_ITC_SHIFT) /* 64 micro frames */ + +#define USBDEV_USBCMD_ATDTW (1 << 14) /* Bit 14: Add dTD trip wire */ +#define USBDEV_USBCMD_SUTW (1 << 13) /* Bit 13: Setup trip wire */ +#define USBDEV_USBCMD_RST (1 << 1) /* Bit 1: 1 Controller reset */ +#define USBDEV_USBCMD_RS (1 << 0) /* Bit 0: 0 Run/Stop */ + +/* USB Command register USBCMD -- Host Mode */ + +#define USBHOST_USBCMD_ITC_SHIFT (16) /* Bits 16-13: Interrupt threshold control */ +#define USBHOST_USBCMD_ITC_MASK (255 << USBHOST_USBCMD_ITC_SHIFT) +# define USBHOST_USBCMD_ITCIMMED (0 << USBHOST_USBCMD_ITC_SHIFT) /* Immediate (no threshold) */ +# define USBHOST_USBCMD_ITC1UF (1 << USBHOST_USBCMD_ITC_SHIFT) /* 1 micro frame */ +# define USBHOST_USBCMD_ITC2UF (2 << USBHOST_USBCMD_ITC_SHIFT) /* 2 micro frames */ +# define USBHOST_USBCMD_ITC4UF (4 << USBHOST_USBCMD_ITC_SHIFT) /* 4 micro frames */ +# define USBHOST_USBCMD_ITC8UF (8 << USBHOST_USBCMD_ITC_SHIFT) /* 8 micro frames */ +# define USBHOST_USBCMD_ITC16UF (16 << USBHOST_USBCMD_ITC_SHIFT) /* 16 micro frames */ +# define USBHOST_USBCMD_ITC32UF (32 << USBHOST_USBCMD_ITC_SHIFT) /* 32 micro frames */ +# define USBHOST_USBCMD_ITC64UF (64 << USBHOST_USBCMD_ITC_SHIFT) /* 64 micro frames */ + +#define USBHOST_USBCMD_FS2 (1 << 15) /* Bit 15: Bit 2 of the Frame List Size bits */ +#define USBHOST_USBCMD_ASPE (1 << 11) /* Bit 11: Asynchronous Schedule Park Mode Enable */ +#define USBHOST_USBCMD_ASP_SHIFT (8) /* Bits 8-9: Asynchronous schedule park mode */ +#define USBHOST_USBCMD_ASP_MASK (3 << USBHOST_USBCMD_ASP_SHIFT) +#define USBHOST_USBCMD_IAA (1 << 6) /* Bit 6: Interrupt next asynchronous schedule */ +#define USBHOST_USBCMD_ASE (1 << 5) /* Bit 5: Skips processing asynchronous schedule */ +#define USBHOST_USBCMD_PSE (1 << 4) /* Bit 4: Skips processing periodic schedule */ +#define USBHOST_USBCMD_FS1 (1 << 3) /* Bit 3: Bit 1 of the Frame List Size bits */ +#define USBHOST_USBCMD_FS0 (1 << 2) /* Bit 2: Bit 0 of the Frame List Size bits */ +#define USBHOST_USBCMD_RST (1 << 1) /* Bit 1: Controller reset */ +#define USBHOST_USBCMD_RS (1 << 0) /* Bit 0: Run/Stop */ + +/* USB Status register USBSTS -- Device Mode */ + +#define USBDEV_USBSTS_NAKI (1 << 16) /* Bit 16: NAK interrupt bit */ +#define USBDEV_USBSTS_SLI (1 << 8) /* Bit 8: DCSuspend */ +#define USBDEV_USBSTS_SRI (1 << 7) /* Bit 7: SOF received */ +#define USBDEV_USBSTS_URI (1 << 6) /* Bit 6: USB reset received */ +#define USBDEV_USBSTS_PCI (1 << 2) /* Bit 2: Port change detect */ +#define USBDEV_USBSTS_UEI (1 << 1) /* Bit 1: USB error interrupt */ +#define USBDEV_USBSTS_UI (1 << 0) /* Bit 0: USB interrupt */ + +/* USB Status register USBSTS -- Host Mode */ + +#define USBHOST_USBSTS_UPI (1 << 19) /* Bit 19: USB host periodic interrupt */ +#define USBHOST_USBSTS_UAI (1 << 18) /* Bit 18: USB host asynchronous interrupt */ +#define USBHOST_USBSTS_AS (1 << 15) /* Bit 15: Asynchronous schedule status */ +#define USBHOST_USBSTS_PS (1 << 14) /* Bit 14: Periodic schedule status */ +#define USBHOST_USBSTS_RCL (1 << 13) /* Bit 13: Reclamation */ +#define USBHOST_USBSTS_HCH (1 << 12) /* Bit 12: HCHalted */ +#define USBHOST_USBSTS_SRI (1 << 7) /* Bit 7: SOF received */ +#define USBHOST_USBSTS_AAI (1 << 5) /* Bit 5: Interrupt on async advance */ +#define USBHOST_USBSTS_FRI (1 << 3) /* Bit 3: Frame list roll-over */ +#define USBHOST_USBSTS_PCI (1 << 2) /* Bit 2: Port change detect */ +#define USBHOST_USBSTS_UEI (1 << 1) /* Bit 1: USB error interrupt */ +#define USBHOST_USBSTS_UI (1 << 0) /* Bit 0: USB interrupt */ + +/* USB interrupt register USBINTR -- Device Mode */ + +#define USBDEV_USBINTR_NAKE (1 << 16) /* Bit 16: NAK interrupt enable */ +#define USBDEV_USBINTR_SLE (1 << 8) /* Bit 8: Sleep enable */ +#define USBDEV_USBINTR_SRE (1 << 7) /* Bit 7: SOF received enable */ +#define USBDEV_USBINTR_URE (1 << 6) /* Bit 6: USB reset enable */ +#define USBDEV_USBINTR_PCE (1 << 2) /* Bit 2: Port change detect enable */ +#define USBDEV_USBINTR_UEE (1 << 1) /* Bit 1: USB error interrupt enable */ +#define USBDEV_USBINTR_UE (1 << 0) /* Bit 0: USB interrupt enable */ + +/* USB interrupt register USBINTR (address 0x19000148) -- Host Mode */ + +#define USBHOST_USBINTR_UPIA (1 << 19) /* Bit 19: USB host periodic interrupt enable */ +#define USBHOST_USBINTR_UAIE (1 << 18) /* Bit 18: USB host asynchronous interrupt enable */ +#define USBHOST_USBINTR_SRE (1 << 7) /* Bit 7: SOF timer interrupt enable */ +#define USBHOST_USBINTR_AAE (1 << 5) /* Bit 5: Interrupt on asynchronous advance enable */ +#define USBHOST_USBINTR_FRE (1 << 3) /* Bit 3: Frame list rollover enable */ +#define USBHOST_USBINTR_PCE (1 << 2) /* Bit 2: Port change detect enable */ +#define USBHOST_USBINTR_UEE (1 << 1) /* Bit 1: USB error interrupt enable */ +#define USBHOST_USBINTR_UE (1 << 0) /* Bit 0: USB interrupt enable */ + +/* Frame index register FRINDEX -- Device Mode */ + +#define USBDEV_FRINDEX_LFN_SHIFT (3) /* Bits 3-13: Frame number of last frame transmitted */ +#define USBDEV_FRINDEX_LFN_MASK (0x7ff << USBDEV_FRINDEX_LFN_SHIFT) +#define USBDEV_FRINDEX_CUFN_SHIFT (0) /* Bits 0-2: Current micro frame number */ +#define USBDEV_FRINDEX_CUFN_MASK (7 << USBDEV_FRINDEX_CUFN_SHIFT) + +/* Frame index register FRINDEX -- Host Mode */ + +#define USBHOST_FRINDEX_FLI_SHIFT (3) /* Bits 3-13: Frame list current index */ +#define USBHOST_FRINDEX_FLI_MASK(n) (0x7ff << ((n) + USBHOST_FRINDEX_FLI_SHIFT - 1) +#define USBHOST_FRINDEX_CUFN_SHIFT (0) /* Bits 0-2: Current micro frame number */ +#define USBHOST_FRINDEX_CUFN_MASK (7 << USBHOST_FRINDEX_CUFN_SHIFT) + +/* USB Device Address register DEVICEADDR -- Device Mode */ + +#define USBDEV_DEVICEADDR_SHIFT (25) /* Bits 25-31: USBADR USB device address */ +#define USBDEV_DEVICEADDR_MASK (0x3c << USBDEV_DEVICEADDR_SHIFT) +#define USBDEV_DEVICEADDR_USBADRA (1 << 24) /* Bit 24: Device address advance */ + +/* USB Periodic List Base register PERIODICLIST -- Host Mode */ + +#define USBHOST_PERIODICLIST_PERBASE_SHIFT (12) /* Bits 12-31: Base Address (Low) */ +#define USBHOST_PERIODICLIST_PERBASE_MASK (0x000fffff << USBHOST_PERIODICLIST_PERBASE_SHIFT) + +/* USB Endpoint List Address register ENDPOINTLISTADDR -- Device Mode */ + +#define USBDEV_ENDPOINTLIST_EPBASE_SHIFT (11) /* Bits 11-31: Endpoint list pointer (low) */ +#define USBDEV_ENDPOINTLIST_EPBASE_MASK (0x001fffff << USBDEV_ENDPOINTLIST_EPBASE_SHIFT) + +/* USB Asynchronous List Address register ASYNCLISTADDR -- Host Mode */ + +#define USBHOST_ASYNCLISTADDR_ASYBASE_SHIFT (5) /* Bits 5-31: Link pointer (Low) LPL */ +#define USBHOST_ASYNCLISTADDR_ASYBASE_MASK (0x07ffffff << USBHOST_ASYNCLISTADDR_ASYBASE_SHIFT) + +/* USB TT Control register TTCTRL (address 0x1900015c) -- Host Mode */ + +#define USBHOST_TTCTRL_TTHA_SHIFT (24) /* Bits 24-30: Hub address */ +#define USBHOST_TTCTRL_TTHA_MASK (0x7f << USBHOST_TTCTRL_TTHA_SHIFT) + +/* USB burst size register BURSTSIZE -- Device/Host Mode */ + +#define USBDEV_BURSTSIZE_TXPBURST_SHIFT (8) /* Bits 8-15: Programmable TX burst length */ +#define USBDEV_BURSTSIZE_TXPBURST_MASK (255 << USBDEV_BURSTSIZE_TXPBURST_SHIFT) +#define USBDEV_BURSTSIZE_RXPBURST_SHIFT (0) /* Bits 0-7: RXPBURST Programmable RX burst length */ +#define USBDEV_BURSTSIZE_RXPBURST_MASK (255 << USBDEV_BURSTSIZE_RXPBURST_SHIFT) + +#define USBHOST_BURSTSIZE_TXPBURST_SHIFT (8) /* Bits 8-15: Programmable TX burst length */ +#define USBHOST_BURSTSIZE_TXPBURST_MASK (255 << USBHOST_BURSTSIZE_TXPBURST_SHIFT) +#define USBHOST_BURSTSIZE_RXPBURST_SHIFT (0) /* Bits 0-7: RXPBURST Programmable RX burst length */ +#define USBHOST_BURSTSIZE_RXPBURST_MASK (255 << USBHOST_BURSTSIZE_RXPBURST_SHIFT) + +/* USB Transfer buffer Fill Tuning register TXFIFOFILLTUNING -- Host Mode */ + +#define USBHOST_TXFILLTUNING_FIFOTHRES_SHIFT (16) /* Bits 16-21: Scheduler overhead */ +#define USBHOST_TXFILLTUNING_FIFOTHRES_MASK (0x3c << USBHOST_TXFILLTUNING_FIFOTHRES_SHIFT) +#define USBHOST_TXFILLTUNING_SCHEATLTH_SHIFT (8) /* Bits 8-12: Scheduler health counter */ +#define USBHOST_TXFILLTUNING_SCHEATLTH_MASK (0x1f << USBHOST_TXFILLTUNING_SCHEATLTH_SHIFT) +#define USBHOST_TXFILLTUNING_SCHOH_SHIFT (0) /* Bits 0-7: FIFO burst threshold */ +#define USBHOST_TXFILLTUNING_SCHOH_MASK (0xff << USBHOST_TXFILLTUNING_SCHOH_SHIFT) + +/* USB BINTERVAL register BINTERVAL -- Device/Host Mode */ + +#define USBDEV_BINTERVAL_SHIFT (0) /* Bits 0-3: bInterval value */ +#define USBDEV_BINTERVAL_MASK (15 << USBDEV_BINTERVAL_SHIFT) + +#define USBHOST_BINTERVAL_SHIFT (0) /* Bits 0-3: bInterval value */ +#define USBHOST_BINTERVAL_MASK (15 << USBHOST_BINTERVAL_SHIFT) + +/* USB endpoint NAK register ENDPTNAK -- Device Mode */ + +#define USBDEV_ENDPTNAK_EPTN_SHIFT (16) /* Bits 16-19: Tx endpoint NAK */ +#define USBDEV_ENDPTNAK_EPTN_MASK (15 << USBDEV_ENDPTNAK_EPTN_SHIFT) +#define USBDEV_ENDPTNAK_EPRN_SHIFT (0) /* Bits 0-3: Rx endpoint NAK */ +#define USBDEV_ENDPTNAK_EPRN_MASK (15 << USBDEV_ENDPTNAK_EPRN_SHIFT) + +/* USB Endpoint NAK Enable register ENDPTNAKEN -- Device Mode */ + +#define USBDEV_ENDPTNAK_EPTNE_SHIFT (16) /* Bits 16-19: Tx endpoint NAK enable */ +#define USBDEV_ENDPTNAK_EPTNE_MASK (15 << USBDEV_ENDPTNAK_EPTNE_SHIFT) +#define USBDEV_ENDPTNAK_EPRNE_SHIFT (0) /* Bits 0-3: Rx endpoint NAK enable */ +#define USBDEV_ENDPTNAK_EPRNE_MASK (15 << USBDEV_ENDPTNAK_EPRNE_SHIFT) + +/* Port Status and Control register PRTSC1 -- Device Mode */ + +#define USBDEV_PRTSC1_PSPD_SHIFT (26) /* Bits 26-27: Port speed */ +#define USBDEV_PRTSC1_PSPD_MASK (3 << USBDEV_PRTSC1_PSPD_SHIFT) +# define USBDEV_PRTSC1_PSPD_FS (0 << USBDEV_PRTSC1_PSPD_SHIFT) /* Full-speed */ +# define USBDEV_PRTSC1_PSPD_LS (1 << USBDEV_PRTSC1_PSPD_SHIFT) /* Low-speed */ +# define USBDEV_PRTSC1_PSPD_HS (2 << USBDEV_PRTSC1_PSPD_SHIFT) /* High-speed */ + +#define USBDEV_PRTSC1_PFSC (1 << 24) /* Bit 24: Port force full speed connect */ +#define USBDEV_PRTSC1_PHCD (1 << 23) /* Bit 23: PHY low power suspend - clock disable (PLPSCD) */ +#define USBDEV_PRTSC1_PTC_SHIFT (16) /* Bits 16-19: 19: Port test control */ +#define USBDEV_PRTSC1_PTC_MASK (15 << USBDEV_PRTSC1_PTC_SHIFT) +# define USBDEV_PRTSC1_PTC_DISABLE (0 << USBDEV_PRTSC1_PTC_SHIFT) /* TEST_MODE_DISABLE */ +# define USBDEV_PRTSC1_PTC_JSTATE (1 << USBDEV_PRTSC1_PTC_SHIFT) /* J_STATE */ +# define USBDEV_PRTSC1_PTC_KSTATE (2 << USBDEV_PRTSC1_PTC_SHIFT) /* K_STATE */ +# define USBDEV_PRTSC1_PTC_SE0 (3 << USBDEV_PRTSC1_PTC_SHIFT) /* SE0 (host)/NAK (device) */ +# define USBDEV_PRTSC1_PTC_PACKET (4 << USBDEV_PRTSC1_PTC_SHIFT) /* Packet */ +# define USBDEV_PRTSC1_PTC_HS (5 << USBDEV_PRTSC1_PTC_SHIFT) /* FORCE_ENABLE_HS */ +# define USBDEV_PRTSC1_PTC_FS (6 << USBDEV_PRTSC1_PTC_SHIFT) /* FORCE_ENABLE_FS */ + +#define USBDEV_PRTSC1_PIC_SHIFT (14) /* Bits 14-15: Port indicator control */ +#define USBDEV_PRTSC1_PIC_MASK (3 << USBDEV_PRTSC1_PIC_SHIFT) +# define USBDEV_PRTSC1_PIC_OFF (0 << USBDEV_PRTSC1_PIC_SHIFT) /* 00 Port indicators are off */ +# define USBDEV_PRTSC1_PIC_AMBER (1 << USBDEV_PRTSC1_PIC_SHIFT) /* 01 amber */ +# define USBDEV_PRTSC1_PIC_GREEN (2 << USBDEV_PRTSC1_PIC_SHIFT) /* 10 green */ + +#define USBDEV_PRTSC1_HSP (1 << 9) /* Bit 9: High-speed status */ +#define USBDEV_PRTSC1_PR (1 << 8) /* Bit 8: Port reset */ +#define USBDEV_PRTSC1_SUSP (1 << 7) /* Bit 7: Suspend */ +#define USBDEV_PRTSC1_FPR (1 << 6) /* Bit 6: Force port resume */ +#define USBDEV_PRTSC1_PEC (1 << 3) /* Bit 3: Port enable/disable change */ +#define USBDEV_PRTSC1_PE (1 << 2) /* Bit 2: Port enable */ +#define USBDEV_PRTSC1_CCS (1 << 0) /* Bit 0: Current connect status */ + +/* Port Status and Control register PRTSC1 -- Host Mode */ + +#define USBHOST_PRTSC1_PSPD_SHIFT (26) /* Bits 26-27: Port speed */ +#define USBHOST_PRTSC1_PSPD_MASK (3 << USBHOST_PRTSC1_PSPD_SHIFT) +# define USBHOST_PRTSC1_PSPD_FS (0 << USBHOST_PRTSC1_PSPD_SHIFT) /* Full-speed */ +# define USBHOST_PRTSC1_PSPD_LS (1 << USBHOST_PRTSC1_PSPD_SHIFT) /* Low-speed */ +# define USBHOST_PRTSC1_PSPD_HS (2 << USBHOST_PRTSC1_PSPD_SHIFT) /* High-speed */ + +#define USBHOST_PRTSC1_PFSC (1 << 24) /* Bit 24: Port force full speed connect */ +#define USBHOST_PRTSC1_PHCD (1 << 23) /* Bit 23: PHY low power suspend - clock disable (PLPSCD) */ +#define USBHOST_PRTSC1_WKOC (1 << 22) /* Bit 22: Wake on over-current enable (WKOC_E) */ +#define USBHOST_PRTSC1_WKDC (1 << 21) /* Bit 21: Wake on disconnect enable (WKDSCNNT_E) */ +#define USBHOST_PRTSC1_WKCN (1 << 20) /* Bit 20: Wake on connect enable (WKCNNT_E) */ +#define USBHOST_PRTSC1_PTC_SHIFT (16) /* Bits 16-19: Port test control */ +#define USBHOST_PRTSC1_PTC_MASK (15 << USBHOST_PRTSC1_PTC_SHIFT) +# define USBHOST_PRTSC1_PTC_DISABLE (0 << USBHOST_PRTSC1_PTC_SHIFT) /* 0000 TEST_MODE_DISABLE */ +# define USBHOST_PRTSC1_PTC_JSTATE (1 << USBHOST_PRTSC1_PTC_SHIFT) /* 0001 J_STATE */ +# define USBHOST_PRTSC1_PTC_KSTATE (2 << USBHOST_PRTSC1_PTC_SHIFT) /* 0010 K_STATE */ +# define USBHOST_PRTSC1_PTC_SE0 (3 << USBHOST_PRTSC1_PTC_SHIFT) /* 0011 SE0 (host)/NAK (device) */ +# define USBHOST_PRTSC1_PTC_PACKET (4 << USBHOST_PRTSC1_PTC_SHIFT) /* 0100 Packet */ +# define USBHOST_PRTSC1_PTC_HS (5 << USBHOST_PRTSC1_PTC_SHIFT) /* 0101 FORCE_ENABLE_HS */ +# define USBHOST_PRTSC1_PTC_FS (6 << USBHOST_PRTSC1_PTC_SHIFT) /* 0110 FORCE_ENABLE_FS */ +# define USBHOST_PRTSC1_PTC_LS (7 << USBHOST_PRTSC1_PTC_SHIFT) /* 0111 FORCE_ENABLE_LS */ + +#define USBHOST_PRTSC1_PIC_SHIFT (14) /* Bits 14-15: Port indicator control */ +#define USBHOST_PRTSC1_PIC_MASK (3 << USBHOST_PRTSC1_PIC_SHIFT) +# define USBHOST_PRTSC1_PIC_OFF (0 << USBHOST_PRTSC1_PIC_SHIFT) /* 00 Port indicators are off */ +# define USBHOST_PRTSC1_PIC_AMBER (1 << USBHOST_PRTSC1_PIC_SHIFT) /* 01 Amber */ +# define USBHOST_PRTSC1_PIC_GREEN (2 << USBHOST_PRTSC1_PIC_SHIFT) /* 10 Green */ + +#define USBHOST_PRTSC1_PP (1 << 12) /* Bit 12: Port power control */ +#define USBHOST_PRTSC1_LS_SHIFT (10) /* Bits 10-11: Line status */ +#define USBHOST_PRTSC1_LS_MASK (3 << USBHOST_PRTSC1_LS_SHIFT) +# define USBHOST_PRTSC1_LS_SE0 (0 << USBHOST_PRTSC1_LS_SHIFT) /* SE0 (USB_DP and USB_DM LOW) */ +# define USBHOST_PRTSC1_LS_JSTATE (2 << USBHOST_PRTSC1_LS_SHIFT) /* J-state (USB_DP HIGH and USB_DM LOW) */ +# define USBHOST_PRTSC1_LS_KSTATE (1 << USBHOST_PRTSC1_LS_SHIFT) /* K-state (USB_DP LOW and USB_DM HIGH) */ + +#define USBHOST_PRTSC1_HSP (1 << 9) /* Bit 9: High-speed status */ +#define USBHOST_PRTSC1_PR (1 << 8) /* Bit 8: Port reset */ +#define USBHOST_PRTSC1_SUSP (1 << 7) /* Bit 7: Suspend */ +#define USBHOST_PRTSC1_FPR (1 << 6) /* Bit 6: Force port resume */ +#define USBHOST_PRTSC1_OCC (1 << 5) /* Bit 5: Over-current change */ +#define USBHOST_PRTSC1_OCA (1 << 4) /* Bit 4: Over-current active */ +#define USBHOST_PRTSC1_PEC (1 << 3) /* Bit 3: Port disable/enable change */ +#define USBHOST_PRTSC1_PE (1 << 2) /* Bit 2: Port enable */ +#define USBHOST_PRTSC1_CSC (1 << 1) /* Bit 1: Connect status change */ +#define USBHOST_PRTSC1_CCS (1 << 0) /* Bit 0: Current connect status */ + +/* OTG Status and Control register (OTGSC) */ + +/* OTG interrupt enable */ + +#define USBOTG_OTGSC_DPIE (1 << 30) /* Bit 30: Data pulse interrupt enable */ +#define USBOTG_OTGSC_1MSE (1 << 29) /* Bit 29: 1 millisecond timer interrupt enable */ +#define USBOTG_OTGSC_BSEIE (1 << 28) /* Bit 28: B-session end interrupt enable */ +#define USBOTG_OTGSC_BSVIE (1 << 27) /* Bit 27: B-session valid interrupt enable */ +#define USBOTG_OTGSC_ASVIE (1 << 26) /* Bit 26: A-session valid interrupt enable */ +#define USBOTG_OTGSC_AVVIE (1 << 25) /* Bit 25: A-VBUS valid interrupt enable */ +#define USBOTG_OTGSC_IDIE (1 << 24) /* Bit 24: USB ID interrupt enable */ + +/* OTG interrupt status */ + +#define USBOTG_OTGSC_DPIS (1 << 22) /* Bit 22: Data pulse interrupt status */ +#define USBOTG_OTGSC_1MSS (1 << 21) /* Bit 21: 1 millisecond timer interrupt status */ +#define USBOTG_OTGSC_BSEIS (1 << 20) /* Bit 20: B-Session end interrupt status */ +#define USBOTG_OTGSC_BSVIS (1 << 19) /* Bit 19: B-Session valid interrupt status */ +#define USBOTG_OTGSC_ASVIS (1 << 18) /* Bit 18: A-Session valid interrupt status */ +#define USBOTG_OTGSC_AVVIS (1 << 17) /* Bit 17: A-VBUS valid interrupt status */ +#define USBOTG_OTGSC_IDIS (1 << 16) /* Bit 16: USB ID interrupt status */ + +/* OTG status inputs */ + +#define USBOTG_OTGSC_DPS (1 << 14) /* Bit 14: Data bus pulsing status */ +#define USBOTG_OTGSC_1MST (1 << 13) /* Bit 13: 1 millisecond timer toggle */ +#define USBOTG_OTGSC_BSE (1 << 12) /* Bit 12: B-session end */ +#define USBOTG_OTGSC_BSV (1 << 11) /* Bit 11: B-session valid */ +#define USBOTG_OTGSC_ASV (1 << 10) /* Bit 10: A-session valid */ +#define USBOTG_OTGSC_AVV (1 << 9) /* Bit 9: A-VBUS valid */ +#define USBOTG_OTGSC_ID (1 << 8) /* Bit 8: USB ID */ + +/* OTG controls */ + +#define USBOTG_OTGSC_HABA (1 << 7) /* Bit 7: Hardware assist B-disconnect to A-connect */ +#define USBOTG_OTGSC_HADP (1 << 6) /* Bit 6: Hardware assist data pulse */ +#define USBOTG_OTGSC_IDPU (1 << 5) /* Bit 5: ID pull-up */ +#define USBOTG_OTGSC_DP (1 << 4) /* Bit 4: Data pulsing */ +#define USBOTG_OTGSC_OT (1 << 3) /* Bit 3: OTG termination */ +#define USBOTG_OTGSC_HAAR (1 << 2) /* Bit 2: Hardware assist auto_reset */ +#define USBOTG_OTGSC_VC (1 << 1) /* Bit 1: VBUS_Charge */ +#define USBOTG_OTGSC_VD (1 << 0) /* Bit 0: VBUS_Discharge */ + +/* USB Mode register USBMODE -- Device Mode */ + +#define USBDEV_USBMODE_SDIS (1 << 4) /* Bit 4: Stream disable mode */ +#define USBDEV_USBMODE_SLOM (1 << 3) /* Bit 3: Setup Lockout mode */ +#define USBDEV_USBMODE_ES (1 << 2) /* Bit 2: Endian select */ +#define USBDEV_USBMODE_CM_SHIFT (0) /* Bits 0-1: Controller mode */ +#define USBDEV_USBMODE_CM_MASK (3 << USBDEV_USBMODE_CM_SHIFT) +# define USBDEV_USBMODE_CM_IDLE (0 << USBDEV_USBMODE_CM_SHIFT) /* Idle */ +# define USBDEV_USBMODE_CM_DEVICE (2 << USBDEV_USBMODE_CM_SHIFT) /* Device controller */ +# define USBDEV_USBMODE_CM_HOST (3 << USBDEV_USBMODE_CM_SHIFT) /* Host controller */ + +/* USB Mode register USBMODE -- Device Mode */ + +#define USBHOST_USBMODE_VBPS (1 << 5) /* Bit 5: VBUS power select */ +#define USBHOST_USBMODE_SDIS (1 << 4) /* Bit 4: Stream disable mode */ +#define USBHOST_USBMODE_ES (1 << 2) /* Bit 2: Endian select */ +#define USBHOST_USBMODE_CM_SHIFT (0) /* Bits 0-1: Controller mode */ +#define USBHOST_USBMODE_CM_MASK (3 << USBHOST_USBMODE_CM_SHIFT) +# define USBHOST_USBMODE_CM_IDLE (0 << USBHOST_USBMODE_CM_SHIFT) /* Idle */ +# define USBHOST_USBMODE_CM_DEVICE (2 << USBHOST_USBMODE_CM_SHIFT) /* Device controller */ +# define USBHOST_USBMODE_CM_HOST (3 << USBHOST_USBMODE_CM_SHIFT) /* Host controller */ + +/* Device endpoint registers */ + +/* USB Endpoint Setup Status register ENDPTSETUPSTAT */ + +#define USBDEV_ENDPTSETSTAT_STAT15 (1 << 15) /* Bit 15: Setup EP status for logical EP 15 */ +#define USBDEV_ENDPTSETSTAT_STAT14 (1 << 14) /* Bit 14: Setup EP status for logical EP 14 */ +#define USBDEV_ENDPTSETSTAT_STAT13 (1 << 13) /* Bit 13: Setup EP status for logical EP 13 */ +#define USBDEV_ENDPTSETSTAT_STAT12 (1 << 12) /* Bit 12: Setup EP status for logical EP 12 */ +#define USBDEV_ENDPTSETSTAT_STAT11 (1 << 11) /* Bit 11: Setup EP status for logical EP 11 */ +#define USBDEV_ENDPTSETSTAT_STAT10 (1 << 10) /* Bit 10: Setup EP status for logical EP 10 */ +#define USBDEV_ENDPTSETSTAT_STAT9 (1 << 9) /* Bit 9: Setup EP status for logical EP 9 */ +#define USBDEV_ENDPTSETSTAT_STAT8 (1 << 8) /* Bit 8: Setup EP status for logical EP 8 */ +#define USBDEV_ENDPTSETSTAT_STAT7 (1 << 7) /* Bit 7: Setup EP status for logical EP 7 */ +#define USBDEV_ENDPTSETSTAT_STAT6 (1 << 6) /* Bit 6: Setup EP status for logical EP 6 */ +#define USBDEV_ENDPTSETSTAT_STAT5 (1 << 5) /* Bit 5: Setup EP status for logical EP 5 */ +#define USBDEV_ENDPTSETSTAT_STAT4 (1 << 4) /* Bit 4: Setup EP status for logical EP 4 */ +#define USBDEV_ENDPTSETSTAT_STAT3 (1 << 3) /* Bit 3: Setup EP status for logical EP 3 */ +#define USBDEV_ENDPTSETSTAT_STAT2 (1 << 2) /* Bit 2: Setup EP status for logical EP 2 */ +#define USBDEV_ENDPTSETSTAT_STAT1 (1 << 1) /* Bit 1: Setup EP status for logical EP 1 */ +#define USBDEV_ENDPTSETSTAT_STAT0 (1 << 0) /* Bit 0: Setup EP status for logical EP 0 */ + +/* USB Endpoint Prime register ENDPTPRIME */ + +#define USBDEV_ENDPTPRIM_PETB7 (1 << 23) /* Bit 23: Prime EP xmt buffer for physical IN EP 7 */ +#define USBDEV_ENDPTPRIM_PETB6 (1 << 22) /* Bit 22: Prime EP xmt buffer for physical IN EP 6 */ +#define USBDEV_ENDPTPRIM_PETB5 (1 << 21) /* Bit 21: Prime EP xmt buffer for physical IN EP 5 */ +#define USBDEV_ENDPTPRIM_PETB4 (1 << 20) /* Bit 20: Prime EP xmt buffer for physical IN EP 4 */ +#define USBDEV_ENDPTPRIM_PETB3 (1 << 19) /* Bit 19: Prime EP xmt buffer for physical IN EP 3 */ +#define USBDEV_ENDPTPRIM_PETB2 (1 << 18) /* Bit 18: Prime EP xmt buffer for physical IN EP 2 */ +#define USBDEV_ENDPTPRIM_PETB1 (1 << 17) /* Bit 17: Prime EP xmt buffer for physical IN EP 1 */ +#define USBDEV_ENDPTPRIM_PETB0 (1 << 16) /* Bit 16: Prime EP xmt buffer for physical IN EP 0 */ +#define USBDEV_ENDPTPRIM_PERB7 (1 << 7) /* Bit 7: Prime EP recv buffer for physical OUT EP 7 */ +#define USBDEV_ENDPTPRIM_PERB6 (1 << 6) /* Bit 6: Prime EP recv buffer for physical OUT EP 6 */ +#define USBDEV_ENDPTPRIM_PERB5 (1 << 5) /* Bit 5: Prime EP recv buffer for physical OUT EP 5 */ +#define USBDEV_ENDPTPRIM_PERB4 (1 << 4) /* Bit 4: Prime EP recv buffer for physical OUT EP 4 */ +#define USBDEV_ENDPTPRIM_PERB3 (1 << 3) /* Bit 3: Prime EP recv buffer for physical OUT EP 3 */ +#define USBDEV_ENDPTPRIM_PERB2 (1 << 2) /* Bit 2: Prime EP recv buffer for physical OUT EP 2 */ +#define USBDEV_ENDPTPRIM_PERB1 (1 << 1) /* Bit 1: Prime EP recv buffer for physical OUT EP 1 */ +#define USBDEV_ENDPTPRIM_PERB0 (1 << 0) /* Bit 0: Prime EP recv buffer for physical OUT EP 0 */ + +/* USB Endpoint Flush register ENDPTFLUSH */ + +#define USBDEV_ENDPTFLUSH_FETB7 (1 << 23) /* Bit 23: Flush EP xmt buffer for physical IN EP 7 */ +#define USBDEV_ENDPTFLUSH_FETB6 (1 << 22) /* Bit 22: Flush EP xmt buffer for physical IN EP 6 */ +#define USBDEV_ENDPTFLUSH_FETB5 (1 << 21) /* Bit 21: Flush EP xmt buffer for physical IN EP 5 */ +#define USBDEV_ENDPTFLUSH_FETB4 (1 << 20) /* Bit 20: Flush EP xmt buffer for physical IN EP 4 */ +#define USBDEV_ENDPTFLUSH_FETB3 (1 << 19) /* Bit 19: Flush EP xmt buffer for physical IN EP 3 */ +#define USBDEV_ENDPTFLUSH_FETB2 (1 << 18) /* Bit 18: Flush EP xmt buffer for physical IN EP 2 */ +#define USBDEV_ENDPTFLUSH_FETB1 (1 << 17) /* Bit 17: Flush EP xmt buffer for physical IN EP 1 */ +#define USBDEV_ENDPTFLUSH_FETB0 (1 << 16) /* Bit 16: Flush EP xmt buffer for physical IN EP 0 */ +#define USBDEV_ENDPTFLUSH_FERB7 (1 << 7) /* Bit 7: Flush EP recv buffer for physical OUT EP 7 */ +#define USBDEV_ENDPTFLUSH_FERB6 (1 << 6) /* Bit 6: Flush EP recv buffer for physical OUT EP 6 */ +#define USBDEV_ENDPTFLUSH_FERB5 (1 << 5) /* Bit 5: Flush EP recv buffer for physical OUT EP 5 */ +#define USBDEV_ENDPTFLUSH_FERB4 (1 << 4) /* Bit 4: Flush EP recv buffer for physical OUT EP 4 */ +#define USBDEV_ENDPTFLUSH_FERB3 (1 << 3) /* Bit 3: Flush EP recv buffer for physical OUT EP 3 */ +#define USBDEV_ENDPTFLUSH_FERB2 (1 << 2) /* Bit 2: Flush EP recv buffer for physical OUT EP 2 */ +#define USBDEV_ENDPTFLUSH_FERB1 (1 << 1) /* Bit 1: Flush EP recv buffer for physical OUT EP 1 */ +#define USBDEV_ENDPTFLUSH_FERB0 (1 << 0) /* Bit 0: Flush EP recv buffer for physical OUT EP 0 */ + +/* USB Endpoint Status register ENDPTSTATUS */ + +#define USBDEV_ENDPTSTATUS_ETBR7 (1 << 23) /* Bit 23: EP xmt buffer ready for physical IN EP 7 */ +#define USBDEV_ENDPTSTATUS_ETBR6 (1 << 22) /* Bit 22: EP xmt buffer ready for physical IN EP 6 */ +#define USBDEV_ENDPTSTATUS_ETBR5 (1 << 21) /* Bit 21: EP xmt buffer ready for physical IN EP 5 */ +#define USBDEV_ENDPTSTATUS_ETBR4 (1 << 20) /* Bit 20: EP xmt buffer ready for physical IN EP 4 */ +#define USBDEV_ENDPTSTATUS_ETBR3 (1 << 19) /* Bit 19: EP xmt buffer ready for physical IN EP 3 */ +#define USBDEV_ENDPTSTATUS_ETBR2 (1 << 18) /* Bit 18: EP xmt buffer ready for physical IN EP 2 */ +#define USBDEV_ENDPTSTATUS_ETBR1 (1 << 17) /* Bit 17: EP xmt buffer ready for physical IN EP 1 */ +#define USBDEV_ENDPTSTATUS_ETBR0 (1 << 16) /* Bit 16: EP xmt buffer ready for physical IN EP 0 */ +#define USBDEV_ENDPTSTATUS_ERBR7 (1 << 7) /* Bit 7: EP recv buffer ready for physical OUT EP 7 */ +#define USBDEV_ENDPTSTATUS_ERBR6 (1 << 6) /* Bit 6: EP recv buffer ready for physical OUT EP 6 */ +#define USBDEV_ENDPTSTATUS_ERBR5 (1 << 5) /* Bit 5: EP recv buffer ready for physical OUT EP 5 */ +#define USBDEV_ENDPTSTATUS_ERBR4 (1 << 4) /* Bit 4: EP recv buffer ready for physical OUT EP 4 */ +#define USBDEV_ENDPTSTATUS_ERBR3 (1 << 3) /* Bit 3: EP recv buffer ready for physical OUT EP 3 */ +#define USBDEV_ENDPTSTATUS_ERBR2 (1 << 2) /* Bit 2: EP recv buffer ready for physical OUT EP 2 */ +#define USBDEV_ENDPTSTATUS_ERBR1 (1 << 1) /* Bit 1: EP recv buffer ready for physical OUT EP 1 */ +#define USBDEV_ENDPTSTATUS_ERBR0 (1 << 0) /* Bit 0: EP recv buffer ready for physical OUT EP 0 */ + +/* USB Endpoint Complete register ENDPTCOMPLETE */ + +#define USBDEV_ENDPTCOMPLETE_ETCE7 (1 << 23) /* Bit 23: EP xmt complete event for physical IN EP 7 */ +#define USBDEV_ENDPTCOMPLETE_ETCE6 (1 << 22) /* Bit 22: EP xmt complete event for physical IN EP 6 */ +#define USBDEV_ENDPTCOMPLETE_ETCE5 (1 << 21) /* Bit 21: EP xmt complete event for physical IN EP 5 */ +#define USBDEV_ENDPTCOMPLETE_ETCE4 (1 << 20) /* Bit 20: EP xmt complete event for physical IN EP 4 */ +#define USBDEV_ENDPTCOMPLETE_ETCE3 (1 << 19) /* Bit 19: EP xmt complete event for physical IN EP 3 */ +#define USBDEV_ENDPTCOMPLETE_ETCE2 (1 << 18) /* Bit 18: EP xmt complete event for physical IN EP 2 */ +#define USBDEV_ENDPTCOMPLETE_ETCE1 (1 << 17) /* Bit 17: EP xmt complete event for physical IN EP 1 */ +#define USBDEV_ENDPTCOMPLETE_ETCE0 (1 << 16) /* Bit 16: EP xmt complete event for physical IN EP 0 */ +#define USBDEV_ENDPTCOMPLETE_ERCE7 (1 << 7) /* Bit 7: EP recv complete event for physical OUT EP 7 */ +#define USBDEV_ENDPTCOMPLETE_ERCE6 (1 << 6) /* Bit 6: EP recv complete event for physical OUT EP 6 */ +#define USBDEV_ENDPTCOMPLETE_ERCE5 (1 << 5) /* Bit 5: EP recv complete event for physical OUT EP 5 */ +#define USBDEV_ENDPTCOMPLETE_ERCE4 (1 << 4) /* Bit 4: EP recv complete event for physical OUT EP 4 */ +#define USBDEV_ENDPTCOMPLETE_ERCE3 (1 << 3) /* Bit 3: EP recv complete event for physical OUT EP 3 */ +#define USBDEV_ENDPTCOMPLETE_ERCE2 (1 << 2) /* Bit 2: EP recv complete event for physical OUT EP 2 */ +#define USBDEV_ENDPTCOMPLETE_ERCE1 (1 << 1) /* Bit 1: EP recv complete event for physical OUT EP 1 */ +#define USBDEV_ENDPTCOMPLETE_ERCE0 (1 << 0) /* Bit 0: EP recv complete event for physical OUT EP 0 */ + +/* USB Endpoint 0 Control register ENDPTCTRL0 */ + +#define USBDEV_ENDPTCTRL0_TXE (1 << 23) /* Bit 23: Tx endpoint enable */ +#define USBDEV_ENDPTCTRL0_TXT_SHIFT (18) /* Bits 18-19: Tx endpoint type */ +#define USBDEV_ENDPTCTRL0_TXT_MASK (3 << USBDEV_ENDPTCTRL0_TXT_SHIFT) +# define USBDEV_ENDPTCTRL0_TXT_CTRL (0 << USBDEV_ENDPTCTRL0_TXT_SHIFT) /* Control */ + +#define USBDEV_ENDPTCTRL0_TXS (1 << 16) /* Bit 16: Tx endpoint stall */ +#define USBDEV_ENDPTCTRL0_RXE (1 << 7) /* Bit 7: Rx endpoint enable */ +#define USBDEV_ENDPTCTRL0_RXT_SHIFT (2) /* Bits 2-3: Endpoint type */ +#define USBDEV_ENDPTCTR0L_RXT_MASK (3 << USBDEV_ENDPTCTRL0_RXT_SHIFT) +# define USBDEV_ENDPTCTRL0_RXT_CTRL (0 << USBDEV_ENDPTCTRL0_RXT_SHIFT) /* Control */ + +#define USBDEV_ENDPTCTRL0_RXS (1 << 0) /* Bit 0: Rx endpoint stall */ + +/* USB Endpoint 1-7 control registers ENDPTCTRL1-ENDPPTCTRL7 */ + +#define USBDEV_ENDPTCTRL_TXE (1 << 23) /* Bit 23: Tx endpoint enable */ +#define USBDEV_ENDPTCTRL_TXR (1 << 22) /* Bit 22: Tx data toggle reset */ +#define USBDEV_ENDPTCTRL_TXI (1 << 21) /* Bit 21: Tx data toggle inhibit */ +#define USBDEV_ENDPTCTRL_TXT_SHIFT (18) /* Bits 18-19: Tx endpoint type */ +#define USBDEV_ENDPTCTRL_TXT_MASK (3 << USBDEV_ENDPTCTRL_TXT_SHIFT) +# define USBDEV_ENDPTCTRL_TXT_CTRL (0 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Control */ +# define USBDEV_ENDPTCTRL_TXT_ISOC (1 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Isochronous */ +# define USBDEV_ENDPTCTRL_TXT_BULK (2 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Bulk */ +# define USBDEV_ENDPTCTRL_TXT_INTR (3 << USBDEV_ENDPTCTRL_TXT_SHIFT) /* Interrupt */ + +#define USBDEV_ENDPTCTRL_TXS (1 << 16) /* Bit 16: Tx endpoint stall */ +#define USBDEV_ENDPTCTRL_RXE (1 << 7) /* Bit 7: Rx endpoint enable */ +#define USBDEV_ENDPTCTRL_RXR (1 << 6) /* Bit 6: Rx data toggle reset */ +#define USBDEV_ENDPTCTRL_RXI (1 << 5) /* Bit 5: Rx data toggle inhibit */ +#define USBDEV_ENDPTCTRL_RXT_SHIFT (2) /* Bits 2-3: Endpoint type */ +#define USBDEV_ENDPTCTRL_RXT_MASK (3 << USBDEV_ENDPTCTRL_RXT_SHIFT) +# define USBDEV_ENDPTCTRL_RXT_CTRL (0 << USBDEV_ENDPTCTRL_RXT_SHIFT) /* Control */ +# define USBDEV_ENDPTCTRL_RXT_ISOC (1 << USBDEV_ENDPTCTRL_RXT_SHIFT) /* Isochronous */ +# define USBDEV_ENDPTCTRL_RXT_BULK (2 << USBDEV_ENDPTCTRL_RXT_SHIFT) /* Bulk */ +# define USBDEV_ENDPTCTRL_RXT_INTR (3 << USBDEV_ENDPTCTRL_RXT_SHIFT) /* Interrupt */ + +#define USBDEV_ENDPTCTRL_RXS (1 << 0) /* Bit 0: Rx endpoint stall */ + +/* Device non-core registers */ + +/* USB OTG Control register */ + +/* Bits 0-6: + * Reserved + */ +#define USBNC_OVER_CUR_DIS (1 << 7) /* Bit 7: Disable Over current detection */ +#define USBNC_OVER_CUR_POL (1 << 8) /* Bit 8: Polarity of over current */ +#define USBNC_PWR_POL (1 << 9) /* Bit 9: Power polarity */ +#define USBNC_WIE (1<< 10) /* Bit 10: Wake up interrupt enable */ + /* Bit 11-13: Reserved */ +#define USBNC_WKUP_SW_EN (1 << 14) /* Bit 14: Software wake up enable */ +#define USBNC_WKUP_SW (1 << 15) /* Bit 15: Software wake up */ +#define USBNC_WKUP_ID_EN (1 << 16) /* Bit 16: Wakeup on ID change enable */ +#define USBNC_WKUP_VBUS_EN (1 << 17) /* Bit 17: Wakeup on VBUS change enable */ + /* Bit 18-28: Reserved */ +#define USBNC_WKUP_DPDM_EN (1 << 29) /* Bit 29: Wakeup on DPDM change enable */ + /* Bit 30: Reserved */ +#define USBNC_WIR (1 << 31) /* Bit 31: Wake up interrupt request */ + +#endif /* __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT_USBOTG_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/hardware/imxrt_usbphy.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/hardware/imxrt_usbphy.h new file mode 100644 index 000000000..ec30f0aee --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/hardware/imxrt_usbphy.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/arm/src/imxrt/hardware/imxrt_usbphy.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT_USB_PHY_H +#define __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT_USB_PHY_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "hardware/imxrt_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IMXRT_USBPHY1_BASE_OFFSET 0x1000 /* USB PHY1 Base */ +#define IMXRT_USBPHY2_BASE_OFFSET 0x2000 /* USB PHY2 Base */ + +#define IMXRT_USBPHY1_BASE (IMXRT_ANATOP_BASE + IMXRT_USBPHY1_BASE_OFFSET) /* USB PHY1 Base */ +#define IMXRT_USBPHY2_BASE (IMXRT_ANATOP_BASE + IMXRT_USBPHY2_BASE_OFFSET) /* USB PHY2 Base */ + +/* Register Offsets *********************************************************/ + +#define IMXRT_USBPHY1_PWD_OFFSET 0x0000 /* USBPHY1 USB PHY1 Power-Down Register */ +#define IMXRT_USBPHY1_PWD_CLR_OFFSET 0x0008 /* USBPHY1 USB PHY1 Power-Down Register Clear */ +#define IMXRT_USBPHY1_CTRL_OFFSET 0x0030 /* USBPHY1 USB PHY1 General Control Register */ +#define IMXRT_USBPHY1_CTRL_CLR_OFFSET 0x0038 /* USBPHY1 USB PHY1 General Control Register Clear */ + +#define IMXRT_USBPHY2_PWD_OFFSET 0x0000 /* USBPHY2 USB PHY Power-Down Register */ +#define IMXRT_USBPHY2_PWD_CLR_OFFSET 0x0008 /* USBPHY2 USB PHY Power-Down Register Clear */ +#define IMXRT_USBPHY2_CTRL_OFFSET 0x0030 /* USBPHY2 USB PHY General Control Register */ +#define IMXRT_USBPHY2_CTRL_CLR_OFFSET 0x0038 /* USBPHY2 USB PHY General Control Register Clear */ + +/* Register addresses *******************************************************/ + +#define IMXRT_USBPHY1_PWD (IMXRT_USBPHY1_BASE + IMXRT_USBPHY1_PWD_OFFSET) /* USBPHY1 USB PHY1 Power-Down Register */ +#define IMXRT_USBPHY1_PWD_CLR (IMXRT_USBPHY1_BASE + IMXRT_USBPHY1_PWD_CLR_OFFSET) /* USBPHY1 USB PHY1 Power-Down Register Clear */ +#define IMXRT_USBPHY1_CTRL (IMXRT_USBPHY1_BASE + IMXRT_USBPHY1_CTRL_OFFSET) /* USBPHY1 USB PHY1 General Control Register */ +#define IMXRT_USBPHY1_CTRL_CLR (IMXRT_USBPHY1_BASE + IMXRT_USBPHY1_CTRL_CLR_OFFSET) /* USBPHY1 USB PHY1 General Control Register Clear */ + +#define IMXRT_USBPHY2_PWD (IMXRT_USBPHY2_BASE + IMXRT_USBPHY2_PWD_OFFSET) /* USBPHY2 USB PHY2 Power-Down Register */ +#define IMXRT_USBPHY2_PWD_CLR (IMXRT_USBPHY2_BASE + IMXRT_USBPHY2_PWD_CLR_OFFSET) /* USBPHY2 USB PHY2 Power-Down Register Clear */ +#define IMXRT_USBPHY2_CTRL (IMXRT_USBPHY2_BASE + IMXRT_USBPHY2_CTRL_OFFSET) /* USBPHY2 USB PHY2 General Control Register */ +#define IMXRT_USBPHY2_CTRL_CLR (IMXRT_USBPHY2_BASE + IMXRT_USBPHY2_CTRL_CLR_OFFSET) /* USBPHY2 USB PHY2 General Control Register Clear */ + +/* Register Bit Definitions *************************************************/ + +/* USB PHY Power-Down Register */ + +#define USBPHY_PWD_RXPWDRX (1 << 20) /* Bit 20: Power-down the entire USB PHY receiver block except for the full-speed differential receiver. */ +#define USBPHY_PWD_RXPWDDIFF (1 << 19) /* Bit 19: Power-down the USB high-speed differential receiver. */ +#define USBPHY_PWD_RXPWD1PT1 (1 << 18) /* Bit 18: Power-down the USB full-speed differential receiver. */ +#define USBPHY_PWD_RXPWDENV (1 << 17) /* Bit 17: Power-down the USB high-speed receiver envelope detector (squelch signal). */ +#define USBPHY_PWD_TXPWDV2I (1 << 12) /* Bit 12: Power-down the USB PHY transmit V-to-I converter and the current mirror. */ +#define USBPHY_PWD_TXPWDIBIAS (1 << 11) /* Bit 11: Power-down the USB PHY current bias block for the transmitter. */ +#define USBPHY_PWD_TXPWDFS (1 << 10) /* Bit 10: Power-down the USB full-speed drivers. */ + +/* USB PHY General Control Register */ + +#define USBPHY_CTRL_SFTRST (1 << 31) /* Bit 31: Soft-reset */ +#define USBPHY_CTRL_CLKGATE (1 << 30) /* Bit 30: Gate UTMI clocks */ + +#endif /* __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT_USB_PHY_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/hardware/rt105x/imxrt105x_memorymap.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/hardware/rt105x/imxrt105x_memorymap.h new file mode 100644 index 000000000..dc42ac2e8 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/hardware/rt105x/imxrt105x_memorymap.h @@ -0,0 +1,311 @@ +/**************************************************************************** + * arch/arm/src/imxrt/hardware/rt105x/imxrt105x_memorymap.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT105X_MEMORYMAP_H +#define __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT105X_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* System memory map */ + +#define IMXRT_ITCM_BASE 0x00000000 /* 512KB ITCM */ + + /* 0x00080000 512KB ITCM Reserved */ + + /* 0x00100000 1MB ITCM Reserved */ +#define IMXRT_ROMCP_BASE 0x00200000 /* 96KB ROMCP */ + + /* 0x00218000 416KB ROMCP Reserved */ + + /* 0x00280000 1536KB Reserved */ + + /* 0x00400000 124MB Reserved */ +#define IMXRT_FLEXSPI_BASE 0x08000000 /* 128MB FlexSPI (Aliased) */ +#define IMXRT_SEMCA_BASE 0x10000000 /* 256MB SEMC (Aliased) */ +#define IMXRT_DTCM_BASE 0x20000000 /* 512KB DTCM */ + + /* 0x20080000 512KB DTCM Reserved */ + + /* 0x20100000 1MB Reserved */ +#define IMXRT_OCRAM_BASE 0x20200000 /* 512KB OCRAM */ + + /* 0x20280000 1536KB OCRAM Reserved */ + + /* 0x20400000 252MB Reserved */ + + /* 0x30000000 256MB Reserved */ +#define IMXRT_AIPS1_BASE 0x40000000 /* 1MB AIPS-1 */ +#define IMXRT_AIPS2_BASE 0x40100000 /* 1MB AIPS-2 */ +#define IMXRT_AIPS3_BASE 0x40200000 /* 1MB AIPS-3 */ +#define IMXRT_AIPS4_BASE 0x40300000 /* 1MB AIPS-4 */ + + /* 40400000 12MB Reserved */ +#define IMXRT_MAINCNF_BASE 0x41000000 /* 1MB "main" configuration port */ +#define IMXRT_MCNF_BASE 0x41100000 /* 1MB "m" configuration port */ + + /* 41200000 1MB Reserved for "per" GPV */ + + /* 41300000 1MB Reserved for "ems" GPV */ +#define IMXRT_CPUCNF_BASE 0x41400000 /* 1MB "cpu" configuration port */ + + /* 0x41500000 1MB GPV Reserved */ + + /* 0x41600000 1MB GPV Reserved */ + + /* 0x41700000 1MB GPV Reserved */ + + /* 0x41800000 8MB Reserved */ + + /* 0x42000000 32MB Reserved */ + + /* 0x44000000 64MB Reserved */ + + /* 0x48000000 384MB Reserved */ +#define IMXRT_FLEXCIPHER_BASE 0x60000000 /* 504MB FlexSPI/ FlexSPI ciphertext */ +#define IMXRT_FLEXSPITX_BASE 0x7f800000 /* 4MB FlexSPI TX FIFO */ +#define IMXRT_FLEXSPIRX_BASE 0x7fc00000 /* 4MB FlexSPI RX FIFO */ +#define IMXRT_EXTMEM_BASE 0x80000000 /* 1.5GB SEMC external memories shared memory space */ +#define IMXRT_CM7_BASE 0xe0000000 /* 1MB CM7 PPB */ + + /* 0xe0100000 511MB Reserved */ + +/* AIPS-1 memory map */ + + /* 0x40000000 256KB Reserved */ + + /* 0x40040000 240KB Reserved */ +#define IMXRT_AIPS1CNF_BASE 0x4007c000 /* 6KB AIPS-1 Configuration */ +#define IMXRT_DCDC_BASE 0x40080000 /* 16KB DCDC */ +#define IMXRT_PIT_BASE 0x40084000 /* 16KB PIT */ + + /* 0x40088000 16KB Reserved */ + + /* 0x4008c000 16KB Reserved */ +#define IMXRT_MTR_BASE 0x40090000 /* 16KB MTR */ +#define IMXRT_ACMP_BASE 0x40094000 /* 16KB ACMP */ + + /* 0x40098000 16KB Reserved */ + + /* 0x4009c000 16KB Reserved */ + + /* 0x400a0000 16KB Reserved */ +#define IMXRT_IOMUXCSNVSGPR_BASE 0x400a4000 /* 16KB IOMUXC_SNVS_GPR */ +#define IMXRT_IOMUXCSNVS_BASE 0x400a8000 /* 16KB IOMUXC_SNVS */ +#define IMXRT_IOMUXCGPR_BASE 0x400ac000 /* 16KB IOMUXC_GPR */ +#define IMXRT_FLEXRAM_BASE 0x400b0000 /* 16KB CM7_MX6RT(FLEXRAM) */ +#define IMXRT_EWM_BASE 0x400b4000 /* 16KB EWM */ +#define IMXRT_WDOG1_BASE 0x400b8000 /* 16KB WDOG1 */ +#define IMXRT_WDOG3_BASE 0x400bc000 /* 16KB WDOG3 */ +#define IMXRT_GPIO5_BASE 0x400c0000 /* 16KB GPIO5 */ +#define IMXRT_ADC1_BASE 0x400c4000 /* 16KB ADC1 */ +#define IMXRT_ADC2_BASE 0x400c8000 /* 16KB ADC2 */ +#define IMXRT_TRNG_BASE 0x400cc000 /* 16KB TRNG */ +#define IMXRT_WDOG2_BASE 0x400d0000 /* 16KB WDOG2 */ +#define IMXRT_SNVSHP_BASE 0x400d4000 /* 16KB SNVS_HP */ +#define IMXRT_ANATOP_BASE 0x400d8000 /* 16KB ANATOP */ +#define IMXRT_CSU_BASE 0x400dc000 /* 16KB CSU */ + + /* 0x400e0000 16KB Reserved */ + + /* 0x400e4000 16KB Reserved */ +#define IMXRT_EDMA_BASE 0x400e8000 /* 16KB EDMA */ +#define IMXRT_DMAMUX_BASE 0x400ec000 /* 16KB DMA_CH_MUX */ + + /* 400f0000 16KB Reserved */ +#define IMXRT_GPC_BASE 0x400f4000 /* 16KB GPC */ +#define IMXRT_SRC_BASE 0x400f8000 /* 16KB SRC */ +#define IMXRT_CCM_BASE 0x400fc000 /* 16KB CCM */ + +/* AIPS-2 memory map */ + + /* 0x40100000 256KB Reserved */ + + /* 0x40140000 240KB Reserved */ +#define IMXRT_AIPS2CNF_BASE 0x4017c000 /* 16KB AIPS-2 Configuration */ +#define IMXRT_ROMCPC_BASE 0x40180000 /* 16KB ROMCP controller*/ +#define IMXRT_LPUART1_BASE 0x40184000 /* 16KB LPUART1 */ +#define IMXRT_LPUART2_BASE 0x40188000 /* 16KB LPUART2 */ +#define IMXRT_LPUART3_BASE 0x4018c000 /* 16KB LPUART3 */ +#define IMXRT_LPUART4_BASE 0x40190000 /* 16KB LPUART4 */ +#define IMXRT_LPUART5_BASE 0x40194000 /* 16KB LPUART5 */ +#define IMXRT_LPUART6_BASE 0x40198000 /* 16KB LPUART6 */ +#define IMXRT_LPUART7_BASE 0x4019c000 /* 16KB LPUART7 */ +#define IMXRT_LPUART8_BASE 0x401a0000 /* 16KB LPUART8 */ + + /* 0x401a4000 16KB Reserved */ + + /* 0x401a8000 16KB Reserved */ +#define IMXRT_FLEXIO1_BASE 0x401ac000 /* 16KB FlexIO1 */ +#define IMXRT_FLEXIO2_BASE 0x401b0000 /* 16KB FlexIO2 */ + + /* 0x401b4000 16KB Reserved */ +#define IMXRT_GPIO1_BASE 0x401b8000 /* 16KB GPIO1 */ +#define IMXRT_GPIO2_BASE 0x401bc000 /* 16KB GPIO2 */ +#define IMXRT_GPIO3_BASE 0x401c0000 /* 16KB GPIO3 */ +#define IMXRT_GPIO4_BASE 0x401c4000 /* 16KB GPIO4 */ + + /* 0x401c8000 16KB Reserved */ + + /* 0x401cc000 16KB Reserved */ +#define IMXRT_CAN1_BASE 0x401d0000 /* 16KB CAN1 */ +#define IMXRT_CAN2_BASE 0x401d4000 /* 16KB CAN2 */ + + /* 0x401d8000 16KB Reserved */ +#define IMXRT_QTIMER1_BASE 0x401dc000 /* 16KB QTimer1 */ +#define IMXRT_QTIMER2_BASE 0x401e0000 /* 16KB QTimer2 */ +#define IMXRT_QTIMER3_BASE 0x401e4000 /* 16KB QTimer3 */ +#define IMXRT_QTIMER4_BASE 0x401e8000 /* 16KB QTimer4 */ +#define IMXRT_GPT1_BASE 0x401ec000 /* 16KB GPT1 */ +#define IMXRT_GPT2_BASE 0x401f0000 /* 16KB GPT2 */ +#define IMXRT_OCOTP_BASE 0x401f4000 /* 16KB OCOTP */ +#define IMXRT_IOMUXC_BASE 0x401f8000 /* 16KB IOMUXC */ +#define IMXRT_KPP_BASE 0x401fc000 /* 16KB KPP */ + +/* AIPS-3 memory map */ + + /* 0x40200000 256KB Reserved */ + + /* 0x40240000 240KB Reserved */ +#define IMXRT_AIOS3CNF_BASE 0x4027c000 /* 16KB AIPS-3 Configuration */ + + /* 0x40280000 16KB Reserved */ + + /* 0x40284000 16KB Reserved */ + + /* 0x40288000 16KB Reserved */ + + /* 0x4028c000 16KB Reserved */ + + /* 0x40290000 16KB Reserved */ + + /* 0x40294000 16KB Reserved */ + + /* 0x40298000 16KB Reserved */ + + /* 0x4029c000 16KB Reserved */ + + /* 0x402a0000 16KB Reserved */ + + /* 0x402a4000 16KB Reserved */ +#define IMXRT_FLEXSPIC_BASE 0x402a8000 /* 16KB FlexSPI controller */ + + /* 0x402ac000 16KB Reserved */ + + /* 0x402b0000 16KB Reserved */ +#define IMXRT_PXP_BASE 0x402b4000 /* 16KB PXP */ +#define IMXRT_LCDIF_BASE 0x402b8000 /* 16KB LCDIF */ +#define IMXRT_CSI_BASE 0x402bc000 /* 16KB CSI */ +#define IMXRT_USDHC1_BASE 0x402c0000 /* 16KB USDHC1 */ +#define IMXRT_USDHC2_BASE 0x402c4000 /* 16KB USDHC2 */ + + /* 0x402c8000 16KB Reserved */ + + /* 0x402cc000 16KB Reserved */ + + /* 0x402d0000 16KB Reserved */ + + /* 0x402d4000 16KB Reserved */ +#define IMXRT_ENET_BASE 0x402d8000 /* 16KB ENET */ +#define IMXRT_USBPL301_BASE 0x402dc000 /* 16KB USB(PL301) */ +#define IMXRT_USB_BASE 0x402e0200 /* 16KB USB(USB) */ + + /* 0x402e4000 16KB Reserved */ + + /* 0x402e8000 16KB Reserved */ + + /* 0x402ec000 16KB Reserved */ +#define IMXRT_SEMC_BASE 0x402f0000 /* 16KB SEMC */ + + /* 0x402f4000 16KB Reserved */ + + /* 0x402f8000 16KB Reserved */ +#define IMXRT_DCP_BASE 0x402fc000 /* 16KB DCP */ + +/* AIPS-4 memory map */ + + /* 0x40300000 256KB Reserved */ + + /* 0x40340000 240KB Reserved */ +#define IMXRT_AIPS4CNF_BASE 0x4037c000 /* 16KB AIPS-4 Configuration */ +#define IMXRT_SPDIF_BASE 0x40380000 /* 16KB SPDIF */ +#define IMXRT_SAI1_BASE 0x40384000 /* 16KB SAI1 */ +#define IMXRT_SAI2_BASE 0x40388000 /* 16KB SAI2 */ +#define IMXRT_SAI3_BASE 0x4038c000 /* 16KB SAI3 */ + + /* 0x40390000 16KB Reserved */ +#define IMXRT_LPSPI1_BASE 0x40394000 /* 16KB LPSPI1 */ +#define IMXRT_LPSPI2_BASE 0x40398000 /* 16KB LPSPI2 */ +#define IMXRT_LPSPI3_BASE 0x4039c000 /* 16KB LPSPI3 */ +#define IMXRT_LPSPI4_BASE 0x403a0000 /* 16KB LPSPI4 */ + + /* 0x403a4000 16KB Reserved */ + + /* 0x403a8000 16KB Reserved */ + + /* 0x403ac000 16KB Reserved */ +#define IMXRT_ADCETC_BASE 0x403b0000 /* 16KB ADC_ETC */ +#define IMXRT_AOI1_BASE 0x403b4000 /* 16KB AOI1 */ +#define IMXRT_AOI2_BASE 0x403b8000 /* 16KB AOI2 */ +#define IMXRT_XBAR1_BASE 0x403bc000 /* 16KB XBAR1 */ +#define IMXRT_XBAR2_BASE 0x403c0000 /* 16KB XBAR2 */ +#define IMXRT_XBAR3_BASE 0x403c4000 /* 16KB XBAR3 */ +#define IMXRT_ENC1_BASE 0x403c8000 /* 16KB ENC1 */ +#define IMXRT_ENC2_BASE 0x403cc000 /* 16KB ENC2 */ +#define IMXRT_ENC3_BASE 0x403d0000 /* 16KB ENC3 */ +#define IMXRT_ENC4_BASE 0x403d4000 /* 16KB ENC4 */ + + /* 0x403d8000 16KB Reserved */ +#define IMXRT_FLEXPWM1_BASE 0x403dc000 /* 16KB FLEXPWM1 */ +#define IMXRT_FLEXPWM2_BASE 0x403e0000 /* 16KB FLEXPWM2 */ +#define IMXRT_FLEXPWM3_BASE 0x403e4000 /* 16KB FLEXPWM3 */ +#define IMXRT_FLEXPWM4_BASE 0x403e8000 /* 16KB FLEXPWM4 */ +#define IMXRT_BEE_BASE 0x403ec000 /* 16KB BEE */ +#define IMXRT_LPI2C1_BASE 0x403f0000 /* 16KB */ +#define IMXRT_LPI2C2_BASE 0x403f4000 /* 16KB LPI2C2 */ +#define IMXRT_LPI2C3_BASE 0x403f8000 /* 16KB LPI2C3 */ +#define IMXRT_LPI2C4_BASE 0x403fc000 /* 16KB LPI2C4 */ + +/* PPB memory map */ + +#define IMXRT_TPIU_BASE 0xe0040000 /* 4KB TPIU */ +#define IMXRT_ETM_BASE 0xe0041000 /* 4KB ETM */ +#define IMXRT_CTI_BASE 0xe0042000 /* 4KB CTI */ +#define IMXRT_TSGEN_BASE 0xe0043000 /* 4KB TSGEN */ +#define IMXRT_PPBRES_BASE 0xe0044000 /* 4KB PPB RES */ + + /* 0xe0045000 236KB PPB Reserved */ +#define IMXRT_MCM_BASE 0xe0080000 /* 4KB MCM */ + + /* 0xe0081000 444KB PPB Reserved */ + + /* 0xe00f0000 52KB PPB Reserved */ +#define IMXRT_SYSROM_BASE 0xe00fd000 /* 4KB SYS ROM */ +#define IMXRT_PROCROM_BASE 0xe00fe000 /* 4KB Processor ROM */ +#define IMXRT_PPBROM_BASE 0xe00ff000 /* 4KB PPB ROM */ + +#endif /* __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT105X_MEMORYMAP_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_clockconfig.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_clockconfig.c new file mode 100644 index 000000000..97fef0a96 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_clockconfig.c @@ -0,0 +1,698 @@ +/**************************************************************************** + * arch/arm/src/imxrt/imxrt_clockconfig.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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "arm_arch.h" +#include +#include "hardware/imxrt_ccm.h" +#include "hardware/imxrt_dcdc.h" +#include "imxrt_clockconfig.h" +#include "imxrt_lcd.h" +#include "hardware/imxrt_memorymap.h" +#include "hardware/imxrt_iomuxc.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define VIDEO_PLL_MIN_FREQ 650000000 +#define OSC24_FREQ 24000000 + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_lcd_clockconfig + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_LCD +static void imxrt_lcd_clockconfig(void) +{ + uint32_t reg; + uint32_t reg2; + + int post; + int pre; + + uint32_t numerator; + uint32_t denominator; + uint32_t post_divider; + uint32_t pre_divider; + uint32_t loop_divider; + uint32_t target_freq; + uint32_t freq_error; + + target_freq = (CONFIG_IMXRT_LCD_HWIDTH + + CONFIG_IMXRT_LCD_HPULSE + + CONFIG_IMXRT_LCD_HFRONTPORCH + + CONFIG_IMXRT_LCD_HBACKPORCH) * + (CONFIG_IMXRT_LCD_VHEIGHT + + CONFIG_IMXRT_LCD_VPULSE + + CONFIG_IMXRT_LCD_VFRONTPORCH + + CONFIG_IMXRT_LCD_VBACKPORCH) * + CONFIG_IMXRT_LCD_REFRESH_FREQ; + + for (post_divider = 1; post_divider < 16; post_divider <<= 1) + { + if (IMXRT_LCD_VIDEO_PLL_FREQ * post_divider >= VIDEO_PLL_MIN_FREQ) + { + break; + } + } + + loop_divider = (IMXRT_LCD_VIDEO_PLL_FREQ * post_divider) / OSC24_FREQ; + numerator = (IMXRT_LCD_VIDEO_PLL_FREQ * post_divider) - + (loop_divider * OSC24_FREQ); + denominator = OSC24_FREQ; + + /* Bypass PLL first */ + + modifyreg32(IMXRT_CCM_ANALOG_PLL_VIDEO, + CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_MASK, + CCM_ANALOG_PLL_VIDEO_BYPASS | + CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_REF_24M); + + putreg32(CCM_ANALOG_PLL_VIDEO_NUM_A(numerator), + IMXRT_CCM_ANALOG_PLL_VIDEO_NUM); + putreg32(CCM_ANALOG_PLL_VIDEO_DENOM_B(denominator), + IMXRT_CCM_ANALOG_PLL_VIDEO_DENOM); + + /* Set post divider: + * + * ------------------------------------------------------------------------ + * | config->postDivider | PLL_VIDEO[POST_DIV_SELECT] | MISC2[VIDEO_DIV] | + * ------------------------------------------------------------------------ + * | 1 | 2 | 0 | + * ------------------------------------------------------------------------ + * | 2 | 1 | 0 | + * ------------------------------------------------------------------------ + * | 4 | 2 | 3 | + * ------------------------------------------------------------------------ + * | 8 | 1 | 3 | + * ------------------------------------------------------------------------ + * | 16 | 0 | 3 | + * ------------------------------------------------------------------------ + */ + + reg = getreg32(IMXRT_CCM_ANALOG_PLL_VIDEO); + reg &= ~(CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK | + CCM_ANALOG_PLL_VIDEO_POWERDOWN); + reg |= CCM_ANALOG_PLL_VIDEO_ENABLE | + CCM_ANALOG_PLL_VIDEO_DIV_SELECT(loop_divider); + + reg2 = getreg32(IMXRT_CCM_ANALOG_MISC2); + reg2 &= ~CCM_ANALOG_MISC2_VIDEO_DIV_MASK; + + switch (post_divider) + { + case 16: + reg |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT_DIV4; + reg2 |= CCM_ANALOG_MISC2_VIDEO_DIV(3); + break; + + case 8: + reg |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT_DIV2; + reg2 |= CCM_ANALOG_MISC2_VIDEO_DIV(3); + break; + + case 4: + reg |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT_DIV1; + reg2 |= CCM_ANALOG_MISC2_VIDEO_DIV(3); + break; + + case 2: + reg |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT_DIV2; + reg2 |= 0; + break; + + default: + reg |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT_DIV1; + reg2 |= 0; + break; + } + + putreg32(reg, IMXRT_CCM_ANALOG_PLL_VIDEO); + + putreg32(reg2, IMXRT_CCM_ANALOG_MISC2); + + while ((getreg32(IMXRT_CCM_ANALOG_PLL_VIDEO) & + CCM_ANALOG_PLL_VIDEO_LOCK) == 0) + { + } + + /* Disable Bypass */ + + modifyreg32(IMXRT_CCM_ANALOG_PLL_VIDEO, + CCM_ANALOG_PLL_VIDEO_BYPASS, + 0); + + freq_error = IMXRT_LCD_VIDEO_PLL_FREQ; + pre_divider = 0; + post_divider = 0; + + for (post = 0; post < 8; post++) + { + for (pre = 0; pre < 8; pre++) + { + int32_t temp_error; + temp_error = labs((post + 1) * (pre + 1) * target_freq - + IMXRT_LCD_VIDEO_PLL_FREQ); + if (temp_error < freq_error) + { + pre_divider = pre; + post_divider = post; + freq_error = temp_error; + } + } + } + + /* Select PLL5 as LCD Clock and set Pre divider. */ + + modifyreg32(IMXRT_CCM_CSCDR2, + CCM_CSCDR2_LCDIF_PRE_CLK_SEL_MASK | + CCM_CSCDR2_LCDIF_PRED_MASK, + CCM_CSCDR2_LCDIF_PRE_CLK_SEL_PLL5 | + CCM_CSCDR2_LCDIF_PRED(pre_divider)); + + /* Set Post divider. */ + + modifyreg32(IMXRT_CCM_CBCMR, CCM_CBCMR_LCDIF_PODF_MASK, + CCM_CBCMR_LCDIF_PODF(post_divider)); +} + +#endif + +/**************************************************************************** + * Name: imxrt_pllsetup + ****************************************************************************/ + +static void imxrt_pllsetup(void) +{ +#ifdef CONFIG_ARCH_FAMILY_IMXRT102x + uint32_t pll2reg; +#endif + uint32_t pll3reg; + uint32_t reg; + +#if (defined(CONFIG_ARCH_FAMILY_IMXRT105x) || defined (CONFIG_ARCH_FAMILY_IMXRT106x)) + /* Init Arm PLL1 */ + + reg = CCM_ANALOG_PLL_ARM_DIV_SELECT(IMXRT_ARM_PLL_DIV_SELECT) | + CCM_ANALOG_PLL_ARM_ENABLE; + putreg32(reg, IMXRT_CCM_ANALOG_PLL_ARM); + while ((getreg32(IMXRT_CCM_ANALOG_PLL_ARM) & CCM_ANALOG_PLL_ARM_LOCK) == 0) + { + } + + /* Init Sys PLL2 */ + + reg = CCM_ANALOG_PLL_SYS_DIV_SELECT(IMXRT_SYS_PLL_SELECT) | + CCM_ANALOG_PLL_SYS_ENABLE; + putreg32(reg, IMXRT_CCM_ANALOG_PLL_SYS); + while ((getreg32(IMXRT_CCM_ANALOG_PLL_SYS) & CCM_ANALOG_PLL_SYS_LOCK) == 0) + { + } + + /* Init USB PLL3 */ + + /* capture it's original value */ + + pll3reg = getreg32(IMXRT_CCM_ANALOG_PFD_480); + putreg32(pll3reg | + CCM_ANALOG_PFD_480_PFD0_CLKGATE | + CCM_ANALOG_PFD_480_PFD1_CLKGATE | + CCM_ANALOG_PFD_480_PFD2_CLKGATE | + CCM_ANALOG_PFD_480_PFD3_CLKGATE, + IMXRT_CCM_ANALOG_PFD_480); + + reg = IMXRT_USB2_PLL_DIV_SELECT | + CCM_ANALOG_PLL_USB2_ENABLE | + CCM_ANALOG_PLL_USB2_EN_USB_CLKS | + CCM_ANALOG_PLL_USB2_POWER; + putreg32(reg, IMXRT_CCM_ANALOG_PLL_USB2); + + while ((getreg32(IMXRT_CCM_ANALOG_PLL_USB2) & + CCM_ANALOG_PLL_USB2_LOCK) == 0) + { + } + + putreg32(pll3reg, IMXRT_CCM_ANALOG_PFD_480); + +#ifdef CONFIG_IMXRT_LCD + /* Init Video PLL5 */ + + imxrt_lcd_clockconfig(); +#endif + + /* Init ENET PLL6 */ + + reg = CCM_ANALOG_PLL_ENET_ENET0_DIV_SELECT_50MHZ | + CCM_ANALOG_PLL_ENET_ENET1_125M_EN | + CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN | + CCM_ANALOG_PLL_ENET_ENET_500M_REF_EN | + CCM_ANALOG_PLL_ENET_ENET1_DIV_SELECT_50MHZ; + + putreg32(reg, IMXRT_CCM_ANALOG_PLL_ENET); + + while ((getreg32(IMXRT_CCM_ANALOG_PLL_ENET) & + CCM_ANALOG_PLL_ENET_LOCK) == 0) + { + } + +#elif defined(CONFIG_ARCH_FAMILY_IMXRT102x) + /* Init Sys PLL2 */ + + /* First reset its fractional dividers */ + + pll2reg = getreg32(IMXRT_CCM_ANALOG_PFD_528); + putreg32(pll2reg | + CCM_ANALOG_PFD_528_PFD0_CLKGATE | + CCM_ANALOG_PFD_528_PFD1_CLKGATE | + CCM_ANALOG_PFD_528_PFD2_CLKGATE | + CCM_ANALOG_PFD_528_PFD3_CLKGATE, + IMXRT_CCM_ANALOG_PFD_528); + + reg = CCM_ANALOG_PLL_SYS_DIV_SELECT(IMXRT_SYS_PLL_DIV_SELECT) | + CCM_ANALOG_PLL_SYS_ENABLE; + putreg32(reg, IMXRT_CCM_ANALOG_PLL_SYS); + + while ((getreg32(IMXRT_CCM_ANALOG_PLL_SYS) & + CCM_ANALOG_PLL_SYS_LOCK) == 0) + { + } + + putreg32(pll2reg, IMXRT_CCM_ANALOG_PFD_528); + + /* Init USB PLL3 */ + + /* capture it's original value */ + + pll3reg = getreg32(IMXRT_CCM_ANALOG_PFD_480); + putreg32(pll3reg | + CCM_ANALOG_PFD_480_PFD0_CLKGATE | + CCM_ANALOG_PFD_480_PFD1_CLKGATE | + CCM_ANALOG_PFD_480_PFD2_CLKGATE | + CCM_ANALOG_PFD_480_PFD3_CLKGATE, + IMXRT_CCM_ANALOG_PFD_480); + + reg = CCM_ANALOG_PLL_USB2_DIV_SELECT(IMXRT_USB2_PLL_DIV_SELECT) | + CCM_ANALOG_PLL_USB2_ENABLE | CCM_ANALOG_PLL_USB2_EN_USB_CLKS | + CCM_ANALOG_PLL_USB2_POWER; + putreg32(reg, IMXRT_CCM_ANALOG_PLL_USB2); + + while ((getreg32(IMXRT_CCM_ANALOG_PLL_USB2) & + CCM_ANALOG_PLL_USB2_LOCK) == 0) + { + } + + putreg32(pll3reg, IMXRT_CCM_ANALOG_PFD_480); + + /* Init Audio PLL4 */ + + reg = CCM_ANALOG_PLL_AUDIO_DIV_SELECT(IMXRT_AUDIO_PLL_DIV_SELECT) | + CCM_ANALOG_PLL_AUDIO_ENABLE; + putreg32(reg, IMXRT_CCM_ANALOG_PLL_AUDIO); + + while ((getreg32(IMXRT_CCM_ANALOG_PLL_AUDIO) & + CCM_ANALOG_PLL_AUDIO_LOCK) == 0) + { + } + + /* Init ENET PLL6 */ + + reg = CCM_ANALOG_PLL_ENET_ENET0_DIV_SELECT_50MHZ | + CCM_ANALOG_PLL_ENET_ENET1_125M_EN | + CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN | + CCM_ANALOG_PLL_ENET_ENET_500M_REF_EN; + + putreg32(reg, IMXRT_CCM_ANALOG_PLL_ENET); + + while ((getreg32(IMXRT_CCM_ANALOG_PLL_ENET) & + CCM_ANALOG_PLL_ENET_LOCK) == 0) + { + } + +#else +# error Unrecognised IMXRT family member for clock config +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_clockconfig + * + * Description: + * Called to initialize the i.MXRT. This does whatever setup is needed to + * put the SoC in a usable state. This includes the initialization of + * clocking using the settings in board.h. + * + ****************************************************************************/ + +void imxrt_clockconfig(void) +{ + /* Don't change the current basic clock configuration if we are running + * from SDRAM. In this case, some bootloader logic has already configured + * clocking and SDRAM. We are pretty much committed to using things the + * way that the bootloader has left them. + * + * Note that although this is safe at boot while nothing is using + * the clocks additional caution is required if at some later date + * we want to manipulate the PODFs while the system is running + * (for power minimisation) because changing those is not glitch free. + */ + +#ifndef CONFIG_IMXRT_BOOT_SDRAM + uint32_t reg; + + /* Set clock mux and dividers */ + + /* Set PERIPH_CLK2 MUX to OSC */ + + reg = getreg32(IMXRT_CCM_CBCMR); + reg &= ~CCM_CBCMR_PERIPH_CLK2_SEL_MASK; + reg |= CCM_CBCMR_PERIPH_CLK2_SEL_OSC_CLK; + putreg32(reg, IMXRT_CCM_CBCMR); + + while ((getreg32(IMXRT_CCM_CDHIPR) & CCM_CDHIPR_PERIPH2_CLK_SEL_BUSY) != 0) + { + } + + /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ + + reg = getreg32(IMXRT_CCM_CBCDR); + reg &= ~CCM_CBCDR_PERIPH_CLK_SEL_MASK; + reg |= CCM_CBCDR_PERIPH_CLK_SEL(CCM_CBCDR_PERIPH_CLK_SEL_PERIPH_CLK2); + putreg32(reg, IMXRT_CCM_CBCDR); + while ((getreg32(IMXRT_CCM_CDHIPR) & CCM_CDHIPR_PERIPH_CLK_SEL_BUSY) != 0) + { + } + + /* Set Soc VDD and wait for it to stablise */ + + reg = getreg32(IMXRT_DCDC_REG3); + reg &= ~(DCDC_REG3_TRG_MASK); + reg |= DCDC_REG3_TRG(IMXRT_VDD_SOC); + putreg32(reg, IMXRT_DCDC_REG3); + while ((getreg32(IMXRT_DCDC_REG0) & DCDC_REG0_STS_DC_OK) == 0) + { + } + + /* OK, now nothing is depending on us, configure the PLLs */ + + imxrt_pllsetup(); + + /* Set Dividers */ + + reg = getreg32(IMXRT_CCM_CACRR); + reg &= ~CCM_CACRR_ARM_PODF_MASK; + reg |= CCM_CACRR_ARM_PODF(CCM_PODF_FROM_DIVISOR(IMXRT_ARM_PODF_DIVIDER)); + putreg32(reg, IMXRT_CCM_CACRR); + while ((getreg32(IMXRT_CCM_CDHIPR) & CCM_CDHIPR_ARM_PODF_BUSY) != 0) + { + } + + reg = getreg32(IMXRT_CCM_CBCDR); + reg &= ~CCM_CBCDR_AHB_PODF_MASK; + reg |= CCM_CBCDR_AHB_PODF(CCM_PODF_FROM_DIVISOR(IMXRT_AHB_PODF_DIVIDER)); + putreg32(reg, IMXRT_CCM_CBCDR); + while ((getreg32(IMXRT_CCM_CDHIPR) & CCM_CDHIPR_AHB_PODF_BUSY) != 0) + { + } + + /* Adjust IPG and PERCLK PODFs. Consumers of these clocks will need to + * be gated if there are any (there aren't at boot). + */ + + reg = getreg32(IMXRT_CCM_CBCDR); + reg &= ~CCM_CBCDR_IPG_PODF_MASK; + reg |= CCM_CBCDR_IPG_PODF(CCM_PODF_FROM_DIVISOR(IMXRT_IPG_PODF_DIVIDER)); + putreg32(reg, IMXRT_CCM_CBCDR); + + reg = getreg32(IMXRT_CCM_CSCMR1); + reg &= ~CCM_CSCMR1_PERCLK_PODF_MASK; + reg |= CCM_CSCMR1_PERCLK_PODF( + CCM_PODF_FROM_DIVISOR(IMXRT_PERCLK_PODF_DIVIDER)); + putreg32(reg, IMXRT_CCM_CSCMR1); + +#ifndef CONFIG_IMXRT_SEMC_INIT_DONE + /* Configure SEMC Clock only if not already done by DCD SDR */ + + reg = getreg32(IMXRT_CCM_CBCDR); + reg &= ~CCM_CBCDR_SEMC_PODF_MASK; + reg |= CCM_CBCDR_SEMC_PODF(CCM_PODF_FROM_DIVISOR(IMXRT_SEMC_PODF_DIVIDER)); + putreg32(reg, IMXRT_CCM_CBCDR); + + while ((getreg32(IMXRT_CCM_CDHIPR) & CCM_CDHIPR_SEMC_PODF_BUSY) != 0) + { + } +#endif + + /* Set PRE_PERIPH_CLK to Board Selection */ + + reg = getreg32(IMXRT_CCM_CBCMR); + reg &= ~CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK; + reg |= CCM_CBCMR_PRE_PERIPH_CLK_SEL(IMXRT_PRE_PERIPH_CLK_SEL); + putreg32(reg, IMXRT_CCM_CBCMR); + + /* Set PERIPH_CLK MUX to Board Selection */ + + reg = getreg32(IMXRT_CCM_CBCDR); + reg &= ~CCM_CBCDR_PERIPH_CLK_SEL_MASK; + reg |= CCM_CBCDR_PERIPH_CLK_SEL(IMXRT_PERIPH_CLK_SEL); + putreg32(reg, IMXRT_CCM_CBCDR); + + /* Wait handshake */ + + while ((getreg32(IMXRT_CCM_CDHIPR) & CCM_CDHIPR_PERIPH_CLK_SEL_BUSY) != 0) + { + } + + /* Set PERCLK_CLK_SEL to Board Selection */ + + reg = getreg32(IMXRT_CCM_CSCMR1); + reg &= ~CCM_CSCMR1_PERCLK_CLK_SEL_MASK; + reg |= CCM_CSCMR1_PERCLK_CLK_SEL(IMXRT_PERCLK_CLK_SEL); + putreg32(reg, IMXRT_CCM_CSCMR1); + + while ((getreg32(IMXRT_CCM_CDHIPR) & CCM_CDHIPR_PERIPH_CLK_SEL_BUSY) != 0) + { + } + + /* Setup perhiperals. At this point these are not activated so don't + * need to worry too much about switching off the clock feeds. + */ + + /* Set UART source to PLL3 80M */ + + reg = getreg32(IMXRT_CCM_CSCDR1); + reg &= ~CCM_CSCDR1_UART_CLK_SEL; + reg |= CCM_CSCDR1_UART_CLK_SEL_PLL3_80; + putreg32(reg, IMXRT_CCM_CSCDR1); + + /* Set UART divider to 1 */ + + reg = getreg32(IMXRT_CCM_CSCDR1); + reg &= ~CCM_CSCDR1_UART_CLK_PODF_MASK; + reg |= CCM_CSCDR1_UART_CLK_PODF(CCM_PODF_FROM_DIVISOR(1)); + putreg32(reg, IMXRT_CCM_CSCDR1); + +#ifdef CONFIG_IMXRT_FLEXIO1 +#ifdef CONFIG_ARCH_FAMILY_IMXRT102x + /* Set FlEXIO1 source */ + + reg = getreg32(IMXRT_CCM_CSCMR2); + reg &= ~CCM_CSCMR2_FLEXIO1_CLK_SEL_MASK; + reg |= CCM_CSCMR2_FLEXIO1_CLK_SEL(CONFIG_FLEXIO1_CLK); + putreg32(reg, IMXRT_CCM_CSCMR2); + + /* Set FlEXIO1 divider */ + + reg = getreg32(IMXRT_CCM_CS1CDR); + reg &= ~(CCM_CS1CDR_FLEXIO1_CLK_PODF_MASK | \ + CCM_CS1CDR_FLEXIO1_CLK_PRED_MASK); + reg |= CCM_CS1CDR_FLEXIO1_CLK_PODF + (CCM_PODF_FROM_DIVISOR(CONFIG_FLEXIO1_PODF_DIVIDER)); + reg |= CCM_CS1CDR_FLEXIO1_CLK_PRED + (CCM_PRED_FROM_DIVISOR(CONFIG_FLEXIO1_PRED_DIVIDER)); + putreg32(reg, IMXRT_CCM_CS1CDR); + +#elif (defined(CONFIG_ARCH_FAMILY_IMXRT105x) || defined(CONFIG_ARCH_FAMILY_IMXRT106x)) + /* Set FlEXIO1 source & divider */ + + reg = getreg32(IMXRT_CCM_CDCDR); + reg &= ~(CCM_CDCDR_FLEXIO1_CLK_SEL_MASK | + CCM_CDCDR_FLEXIO1_CLK_PODF_MASK | + CCM_CDCDR_FLEXIO1_CLK_PRED_MASK); + reg |= CCM_CDCDR_FLEXIO1_CLK_SEL(CONFIG_FLEXIO1_CLK); + reg |= CCM_CDCDR_FLEXIO1_CLK_PODF + (CCM_PODF_FROM_DIVISOR(CONFIG_FLEXIO1_PODF_DIVIDER)); + reg |= CCM_CDCDR_FLEXIO1_CLK_PRED + (CCM_PRED_FROM_DIVISOR(CONFIG_FLEXIO1_PRED_DIVIDER)); + putreg32(reg, IMXRT_CCM_CDCDR); + +#endif /* CONFIG_ARCH_FAMILY_IMXRT102x */ +#endif /* CONFIG_IMXRT_FLEXIO1 */ + +#if (defined(CONFIG_IMXRT_FLEXIO2) || defined(CONFIG_IMXRT_FLEXIO3)) + /* Set FlEXIO2 source */ + + reg = getreg32(IMXRT_CCM_CSCMR2); + reg &= ~CCM_CSCMR2_FLEXIO2_CLK_SEL_MASK; + reg |= CCM_CSCMR2_FLEXIO2_CLK_SEL(CONFIG_FLEXIO2_CLK); + putreg32(reg, IMXRT_CCM_CSCMR2); + + /* Set FlEXIO2 divider */ + + reg = getreg32(IMXRT_CCM_CS1CDR); + reg &= ~(CCM_CS1CDR_FLEXIO2_CLK_PODF_MASK | \ + CCM_CS1CDR_FLEXIO2_CLK_PRED_MASK); + reg |= CCM_CS1CDR_FLEXIO2_CLK_PODF + (CCM_PODF_FROM_DIVISOR(CONFIG_FLEXIO2_PODF_DIVIDER)); + reg |= CCM_CS1CDR_FLEXIO2_CLK_PRED + (CCM_PRED_FROM_DIVISOR(CONFIG_FLEXIO2_PRED_DIVIDER)); + putreg32(reg, IMXRT_CCM_CS1CDR); + +#endif /* CONFIG_IMXRT_FLEXIO2 */ + +#ifdef CONFIG_IMXRT_LPI2C + /* Set LPI2C source to PLL3 60M */ + + reg = getreg32(IMXRT_CCM_CSCDR2); + reg &= ~CCM_CSCDR2_LPI2C_CLK_SEL; + reg |= IMXRT_LPI2C_CLK_SELECT; + putreg32(reg, IMXRT_CCM_CSCDR2); + + /* Set LPI2C divider to 5 for 12 MHz */ + + reg = getreg32(IMXRT_CCM_CSCDR2); + reg &= ~CCM_CSCDR2_LPI2C_CLK_PODF_MASK; + reg |= CCM_CSCDR2_LPI2C_CLK_PODF( + CCM_PODF_FROM_DIVISOR(IMXRT_LSI2C_PODF_DIVIDER) + ); + putreg32(reg, IMXRT_CCM_CSCDR2); + +#endif + +#ifdef CONFIG_IMXRT_FLEXCAN + /* Set FlexCAN clock source to PLL3 80M */ + + reg = getreg32(IMXRT_CCM_CSCMR2); + reg &= ~CCM_CSCMR2_CAN_CLK_SEL_MASK; + reg |= IMXRT_CAN_CLK_SELECT; + putreg32(reg, IMXRT_CCM_CSCMR2); + + /* Set FlexCAN dividet to 1 for 80 MHz */ + + reg = getreg32(IMXRT_CCM_CSCMR2); + reg &= ~CCM_CSCMR2_CAN_CLK_PODF_MASK; + reg |= CCM_CSCMR2_CAN_CLK_PODF( + CCM_PODF_FROM_DIVISOR(IMXRT_CAN_PODF_DIVIDER) + ); + putreg32(reg, IMXRT_CCM_CSCMR2); + +#endif + +#ifdef CONFIG_IMXRT_LPSPI + /* Set LPSPI clock source to PLL3 PFD0 */ + + reg = getreg32(IMXRT_CCM_CBCMR); + reg &= ~CCM_CBCMR_LPSPI_CLK_SEL_MASK; + reg |= IMXRT_LPSPI_CLK_SELECT; + putreg32(reg, IMXRT_CCM_CBCMR); + + /* Set LPSPI divider to IMXRT_LSPI_PODF_DIVIDER */ + + reg = getreg32(IMXRT_CCM_CBCMR); + reg &= ~CCM_CBCMR_LPSPI_PODF_MASK; + reg |= CCM_CBCMR_LPSPI_PODF( + CCM_PODF_FROM_DIVISOR(IMXRT_LSPI_PODF_DIVIDER) + ); + putreg32(reg, IMXRT_CCM_CBCMR); +#endif + +#ifdef IMXRT_TRACE_PODF_DIVIDER + /* Set TRACE clock source and speed */ + + reg = getreg32(IMXRT_CCM_CBCMR); + reg &= ~CCM_CBCMR_TRACE_CLK_SEL_MASK; + reg |= IMXRT_TRACE_CLK_SELECT; + putreg32(reg, IMXRT_CCM_CBCMR); + + reg = getreg32(IMXRT_CCM_CSCDR1); + reg &= ~CCM_CSCDR1_TRACE_PODF_MASK; + reg |= CCM_CSCDR1_TRACE_PODF( + CCM_PODF_FROM_DIVISOR(IMXRT_TRACE_PODF_DIVIDER)); + putreg32(reg, IMXRT_CCM_CSCDR1); +#endif + +#ifdef CONFIG_IMXRT_USDHC + /* Optionally set USDHC1 & 2 to generate clocks + * from IMXRT_USDHC1_CLK_SELECT + */ + + reg = getreg32(IMXRT_CCM_CSCMR1); + reg &= ~(CCM_CSCMR1_USDHC1_CLK_SEL | CCM_CSCMR1_USDHC2_CLK_SEL); +#if defined(IMXRT_USDHC1_CLK_SELECT) + reg |= IMXRT_USDHC1_CLK_SELECT; +#endif +#if defined(IMXRT_USDHC2_CLK_SELECT) + reg |= IMXRT_USDHC2_CLK_SELECT; +#endif + putreg32(reg, IMXRT_CCM_CSCMR1); + + /* Now divide down clocks by IMXRT_USDHC[1|2]_PODF_DIVIDER */ + + reg = getreg32(IMXRT_CCM_CSCDR1); + reg &= ~(CCM_CSCDR1_USDHC1_PODF_MASK | CCM_CSCDR1_USDHC2_PODF_MASK); +#if defined(IMXRT_USDHC1_PODF_DIVIDER) + reg |= CCM_CSCDR1_USDHC1_PODF( + CCM_PODF_FROM_DIVISOR(IMXRT_USDHC1_PODF_DIVIDER)); +#endif +#if defined(IMXRT_USDHC2_PODF_DIVIDER) + reg |= CCM_CSCDR1_USDHC2_PODF( + CCM_PODF_FROM_DIVISOR(IMXRT_USDHC2_PODF_DIVIDER)); +#endif + putreg32(reg, IMXRT_CCM_CSCDR1); +#endif + + /* Ensure platform memory clocks remain enabled in WFI */ + + reg = getreg32(IMXRT_CCM_CGPR); + reg |= CCM_CGPR_INT_MEM_CLK_LPM; + putreg32(reg, IMXRT_CCM_CGPR); + + /* Remain in run mode */ + + modifyreg32(IMXRT_CCM_CLPCR, + CCM_CLPCR_LPM_MASK, + CCM_CLPCR_LPM_RUN); +#endif +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_ehci.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_ehci.c new file mode 100644 index 000000000..e5b28c3f0 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_ehci.c @@ -0,0 +1,5452 @@ +/**************************************************************************** + * arch/arm/src/imxrt/imxrt_ehci.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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "arm_arch.h" +#include "chip.h" +#include "hardware/imxrt_usbotg.h" +#include "imxrt_periphclks.h" + +#if defined(CONFIG_IMXRT_USBOTG) && defined(CONFIG_USBHOST) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Pre-requisites */ + +#if !defined(CONFIG_SCHED_WORKQUEUE) +# error Work queue support is required (CONFIG_SCHED_WORKQUEUE) +#elif !defined(CONFIG_SCHED_HPWORK) +# error Hi-priority work queue support is required (CONFIG_SCHED_HPWORK) +#endif + +/* Configurable number of Queue Head (QH) structures. The default is one per + * Root hub port plus one for EP0. + */ + +#ifndef CONFIG_IMXRT_EHCI_NQHS +# define CONFIG_IMXRT_EHCI_NQHS (IMXRT_EHCI_NRHPORT + 1) +#endif + +/* Configurable number of Queue Element Transfer Descriptor (qTDs). The + * default is one per root hub plus three from EP0. + */ + +#ifndef CONFIG_IMXRT_EHCI_NQTDS +# define CONFIG_IMXRT_EHCI_NQTDS (IMXRT_EHCI_NRHPORT + 3) +#endif + +/* Buffers must be aligned to the cache line size */ + +#define DCACHE_LINEMASK (ARMV7M_DCACHE_LINESIZE -1) + +/* Configurable size of a request/descriptor buffers */ + +#ifndef CONFIG_IMXRT_EHCI_BUFSIZE +# define CONFIG_IMXRT_EHCI_BUFSIZE 128 +#endif + +#define IMXRT_EHCI_BUFSIZE \ + ((CONFIG_IMXRT_EHCI_BUFSIZE + DCACHE_LINEMASK) & ~DCACHE_LINEMASK) + +/* Debug options */ + +#ifndef CONFIG_DEBUG_USB_INFO +# undef CONFIG_IMXRT_EHCI_REGDEBUG +#endif + +/* Isochronous transfers are not currently supported */ + +#undef CONFIG_USBHOST_ISOC_DISABLE +#define CONFIG_USBHOST_ISOC_DISABLE 1 + +/* Registers **************************************************************** + * Traditionally, NuttX specifies register locations using individual + * register offsets from a base address. That tradition is broken here and, + * instead, register blocks are represented as structures. This is done here + * because, in principle, EHCI operational register address may not be known + * at compile time; the operational registers lie at an offset specified in + * the 'caplength' byte of the Host Controller Capability Registers. + * + * However, for the case of the IMXRT EHCI, we know apriori that locations + * of these register blocks. + */ + +/* Host Controller Capability Registers */ + +#define HCCR ((struct ehci_hccr_s *)IMXRT_USBOTG_HCCR_BASE) + +/* Host Controller Operational Registers */ + +#define HCOR ((volatile struct ehci_hcor_s *)IMXRT_USBOTG_HCOR_BASE) + +/* Interrupts *************************************************************** + * This is the set of interrupts handled by this driver. + */ + +#define EHCI_HANDLED_INTS (EHCI_INT_USBINT | EHCI_INT_USBERRINT | \ + EHCI_INT_PORTSC | EHCI_INT_SYSERROR | \ + EHCI_INT_AAINT) + +/* The periodic frame list is a 4K-page aligned array of Frame List Link + * pointers. The length of the frame list may be programmable. The + * programmability of the periodic frame list is exported to system software + * via the HCCPARAMS register. If non-programmable, the length is 1024 + * elements. If programmable, the length can be selected by system software + * as one of 256, 512, or 1024 elements. + */ + +#define FRAME_LIST_SIZE 1024 + +/* DMA **********************************************************************/ + +/* For now, we are assuming an identity mapping between physical and virtual + * address spaces. + */ + +#define imxrt_physramaddr(a) (a) +#define imxrt_virtramaddr(a) (a) + +/* USB trace ****************************************************************/ + +#ifdef HAVE_USBHOST_TRACE +# define TR_FMT1 false +# define TR_FMT2 true + +# define TRENTRY(id,fmt1,string) {string} + +# define TRACE1_FIRST ((int)__TRACE1_BASEVALUE + 1) +# define TRACE1_INDEX(id) ((int)(id) - TRACE1_FIRST) +# define TRACE1_NSTRINGS TRACE1_INDEX(__TRACE1_NSTRINGS) + +# define TRACE2_FIRST ((int)__TRACE1_NSTRINGS + 1) +# define TRACE2_INDEX(id) ((int)(id) - TRACE2_FIRST) +# define TRACE2_NSTRINGS TRACE2_INDEX(__TRACE2_NSTRINGS) +#endif + +/* Port numbers */ + +#define RHPNDX(rh) ((rh)->hport.hport.port) +#define RHPORT(rh) (RHPNDX(rh)+1) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Internal representation of the EHCI Queue Head (QH) */ + +struct imxrt_epinfo_s; +struct imxrt_qh_s +{ + /* Fields visible to hardware */ + + struct ehci_qh_s hw; /* Hardware representation of the queue head */ + + /* Internal fields used by the EHCI driver */ + + struct imxrt_epinfo_s *epinfo; /* Endpoint used for the transfer */ + uint32_t fqp; /* First qTD in the list (physical address) */ + uint8_t pad[8]; /* Padding to assure 32-byte alignment */ +}; + +/* Internal representation of the EHCI Queue Element Transfer Descriptor + * (qTD) + */ + +struct imxrt_qtd_s +{ + /* Fields visible to hardware */ + + struct ehci_qtd_s hw; /* Hardware representation of the queue head */ + + /* Internal fields used by the EHCI driver */ +}; + +/* The following is used to manage lists of free QHs and qTDs */ + +struct imxrt_list_s +{ + struct imxrt_list_s *flink; /* Link to next entry in the list + * Variable length entry data follows + */ +}; + +/* List traversal call-out functions */ + +typedef int (*foreach_qh_t)(struct imxrt_qh_s *qh, uint32_t **bp, + void *arg); +typedef int (*foreach_qtd_t)(struct imxrt_qtd_s *qtd, uint32_t **bp, + void *arg); + +/* This structure describes one endpoint. */ + +struct imxrt_epinfo_s +{ + uint8_t epno:7; /* Endpoint number */ + uint8_t dirin:1; /* 1:IN endpoint 0:OUT endpoint */ + uint8_t devaddr:7; /* Device address */ + uint8_t toggle:1; /* Next data toggle */ +#ifndef CONFIG_USBHOST_INT_DISABLE + uint8_t interval; /* Polling interval */ +#endif + uint8_t status; /* Retained token status bits (for debug purposes) */ + volatile bool iocwait; /* TRUE: Thread is waiting for transfer completion */ + uint16_t maxpacket:11; /* Maximum packet size */ + uint16_t xfrtype:2; /* See USB_EP_ATTR_XFER_* definitions in usb.h */ + uint16_t speed:2; /* See USB_*_SPEED definitions in ehci.h */ + int result; /* The result of the transfer */ + uint32_t xfrd; /* On completion, will hold the number of bytes transferred */ + sem_t iocsem; /* Semaphore used to wait for transfer completion */ +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; /* Transfer complete callback */ + void *arg; /* Argument that accompanies the callback */ +#endif +}; + +/* This structure retains the state of one root hub port */ + +struct imxrt_rhport_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbhost_s + * to struct imxrt_rhport_s. + */ + + struct usbhost_driver_s drvr; + + /* Root hub port status */ + + volatile bool connected; /* Connected to device */ + volatile bool lowspeed; /* Low speed device attached */ + struct imxrt_epinfo_s ep0; /* EP0 endpoint info */ + + /* This is the hub port description understood by class drivers */ + + struct usbhost_roothubport_s hport; +}; + +/* This structure retains the overall state of the USB host controller */ + +struct imxrt_ehci_s +{ + volatile bool pscwait; /* TRUE: Thread is waiting for port status change event */ + + sem_t exclsem; /* Support mutually exclusive access */ + sem_t pscsem; /* Semaphore to wait for port status change events */ + + struct imxrt_epinfo_s ep0; /* Endpoint 0 */ + struct imxrt_list_s *qhfree; /* List of free Queue Head (QH) structures */ + struct imxrt_list_s *qtdfree; /* List of free Queue Element Transfer Descriptor (qTD) */ + struct work_s work; /* Supports interrupt bottom half */ + +#ifdef CONFIG_USBHOST_HUB + /* Used to pass external hub port events */ + + volatile struct usbhost_hubport_s *hport; +#endif + + /* Root hub ports */ + + struct imxrt_rhport_s rhport[IMXRT_EHCI_NRHPORT]; +}; + +#ifdef HAVE_USBHOST_TRACE +/* USB trace codes */ + +enum usbhost_trace1codes_e +{ + __TRACE1_BASEVALUE = 0, /* This will force the first value to be 1 */ + + EHCI_TRACE1_SYSTEMERROR, /* EHCI ERROR: System error */ + EHCI_TRACE1_QTDFOREACH_FAILED, /* EHCI ERROR: imxrt_qtd_foreach failed */ + EHCI_TRACE1_QHALLOC_FAILED, /* EHCI ERROR: Failed to allocate a QH */ + EHCI_TRACE1_BUFTOOBIG, /* EHCI ERROR: Buffer too big */ + EHCI_TRACE1_REQQTDALLOC_FAILED, /* EHCI ERROR: Failed to allocate request qTD */ + EHCI_TRACE1_ADDBPL_FAILED, /* EHCI ERROR: imxrt_qtd_addbpl failed */ + EHCI_TRACE1_DATAQTDALLOC_FAILED, /* EHCI ERROR: Failed to allocate data buffer qTD */ + EHCI_TRACE1_DEVDISCONNECTED, /* EHCI ERROR: Device disconnected */ + EHCI_TRACE1_QHCREATE_FAILED, /* EHCI ERROR: imxrt_qh_create failed */ + EHCI_TRACE1_QTDSETUP_FAILED, /* EHCI ERROR: imxrt_qtd_setupphase failed */ + + EHCI_TRACE1_QTDDATA_FAILED, /* EHCI ERROR: imxrt_qtd_dataphase failed */ + EHCI_TRACE1_QTDSTATUS_FAILED, /* EHCI ERROR: imxrt_qtd_statusphase failed */ + EHCI_TRACE1_TRANSFER_FAILED, /* EHCI ERROR: Transfer failed */ + EHCI_TRACE1_QHFOREACH_FAILED, /* EHCI ERROR: imxrt_qh_foreach failed: */ + EHCI_TRACE1_SYSERR_INTR, /* EHCI: Host System Error Interrupt */ + EHCI_TRACE1_USBERR_INTR, /* EHCI: USB Error Interrupt (USBERRINT) Interrupt */ + EHCI_TRACE1_EPALLOC_FAILED, /* EHCI ERROR: Failed to allocate EP info structure */ + EHCI_TRACE1_BADXFRTYPE, /* EHCI ERROR: Support for transfer type not implemented */ + EHCI_TRACE1_HCHALTED_TIMEOUT, /* EHCI ERROR: Timed out waiting for HCHalted */ + EHCI_TRACE1_QHPOOLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the QH pool */ + + EHCI_TRACE1_QTDPOOLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the qTD pool */ + EHCI_TRACE1_PERFLALLOC_FAILED, /* EHCI ERROR: Failed to allocate the periodic frame list */ + EHCI_TRACE1_RESET_FAILED, /* EHCI ERROR: imxrt_reset failed */ + EHCI_TRACE1_RUN_FAILED, /* EHCI ERROR: EHCI Failed to run */ + EHCI_TRACE1_IRQATTACH_FAILED, /* EHCI ERROR: Failed to attach IRQ */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + EHCI_VTRACE1_PORTSC_CSC, /* EHCI Connect Status Change */ + EHCI_VTRACE1_PORTSC_CONNALREADY, /* EHCI Already connected */ + EHCI_VTRACE1_PORTSC_DISCALREADY, /* EHCI Already disconnected */ + EHCI_VTRACE1_TOPHALF, /* EHCI Interrupt top half */ + EHCI_VTRACE1_AAINTR, /* EHCI Async Advance Interrupt */ + + EHCI_VTRACE1_CLASSENUM, /* EHCI Hub port CLASS enumeration */ + EHCI_VTRACE1_USBINTR, /* EHCI USB Interrupt (USBINT) Interrupt */ + EHCI_VTRACE1_ENUM_DISCONN, /* EHCI Enumeration not connected */ + EHCI_VTRACE1_INITIALIZING, /* EHCI Initializing EHCI Stack */ + EHCI_VTRACE1_HCCPARAMS, /* EHCI HCCPARAMS */ + EHCI_VTRACE1_INIITIALIZED, /* EHCI USB EHCI Initialized */ +#endif + + __TRACE1_NSTRINGS, /* Separates the format 1 from the format 2 strings */ + + EHCI_TRACE2_EPSTALLED, /* EHCI EP Stalled */ + EHCI_TRACE2_EPIOERROR, /* EHCI ERROR: EP TOKEN */ + EHCI_TRACE2_CLASSENUM_FAILED, /* EHCI usbhost_enumerate() failed */ + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + EHCI_VTRACE2_ASYNCXFR, /* EHCI Async transfer */ + EHCI_VTRACE2_INTRXFR, /* EHCI Interrupt Transfer */ + EHCI_VTRACE2_IOCCHECK, /* EHCI IOC */ + EHCI_VTRACE2_PORTSC, /* EHCI PORTSC */ + EHCI_VTRACE2_PORTSC_CONNECTED, /* EHCI RHPort connected */ + EHCI_VTRACE2_PORTSC_DISCONND, /* EHCI RHport disconnected */ + EHCI_VTRACE2_MONWAKEUP, /* EHCI RHPort connected wakeup */ + + EHCI_VTRACE2_EPALLOC, /* EHCI EPALLOC */ + EHCI_VTRACE2_CTRLINOUT, /* EHCI CTRLIN/OUT */ + EHCI_VTRACE2_HCIVERSION, /* EHCI HCIVERSION */ + EHCI_VTRACE2_HCSPARAMS, /* EHCI HCSPARAMS */ +#endif + + __TRACE2_NSTRINGS /* Total number of enumeration values */ +}; + +/* USB trace data structure */ + +struct imxrt_ehci_trace_s +{ +#if 0 + uint16_t id; + bool fmt2; +#endif + FAR const char *string; +}; + +#endif /* HAVE_USBHOST_TRACE */ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ******************************************************/ + +static uint16_t imxrt_read16(const uint8_t *addr); +static uint32_t imxrt_read32(const uint8_t *addr); +#if 0 /* Not used */ +static void imxrt_write16(uint16_t memval, uint8_t *addr); +static void imxrt_write32(uint32_t memval, uint8_t *addr); +#endif + +#ifdef CONFIG_ENDIAN_BIG +static uint16_t imxrt_swap16(uint16_t value); +static uint32_t imxrt_swap32(uint32_t value); +#else +# define imxrt_swap16(value) (value) +# define imxrt_swap32(value) (value) +#endif + +#ifdef CONFIG_IMXRT_EHCI_REGDEBUG +static void imxrt_printreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite); +static void imxrt_checkreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite); +static uint32_t imxrt_getreg(volatile uint32_t *regaddr); +static void imxrt_putreg(uint32_t regval, volatile uint32_t *regaddr); +#else +static inline uint32_t imxrt_getreg(volatile uint32_t *regaddr); +static inline void imxrt_putreg(uint32_t regval, volatile uint32_t *regaddr); +#endif +static int ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits, + unsigned int delay); + +/* Semaphores ***************************************************************/ + +static int imxrt_takesem(sem_t *sem); +static int imxrt_takesem_noncancelable(sem_t *sem); +#define imxrt_givesem(s) nxsem_post(s); + +/* Allocators ***************************************************************/ + +static struct imxrt_qh_s *imxrt_qh_alloc(void); +static void imxrt_qh_free(struct imxrt_qh_s *qh); +static struct imxrt_qtd_s *imxrt_qtd_alloc(void); +static void imxrt_qtd_free(struct imxrt_qtd_s *qtd); + +/* List Management **********************************************************/ + +static int imxrt_qh_foreach(struct imxrt_qh_s *qh, uint32_t **bp, + foreach_qh_t handler, void *arg); +static int imxrt_qtd_foreach(struct imxrt_qh_s *qh, foreach_qtd_t handler, + void *arg); +static int imxrt_qtd_discard(struct imxrt_qtd_s *qtd, uint32_t **bp, + void *arg); +static int imxrt_qh_discard(struct imxrt_qh_s *qh); + +/* Cache Operations *********************************************************/ + +#if 0 /* Not used */ +static int imxrt_qtd_invalidate(struct imxrt_qtd_s *qtd, uint32_t **bp, + void *arg); +static int imxrt_qh_invalidate(struct imxrt_qh_s *qh); +#endif +static int imxrt_qtd_flush(struct imxrt_qtd_s *qtd, uint32_t **bp, + void *arg); +static int imxrt_qh_flush(struct imxrt_qh_s *qh); + +/* Endpoint Transfer Handling ***********************************************/ + +#ifdef CONFIG_IMXRT_EHCI_REGDEBUG +static void imxrt_qtd_print(struct imxrt_qtd_s *qtd); +static void imxrt_qh_print(struct imxrt_qh_s *qh); +static int imxrt_qtd_dump(struct imxrt_qtd_s *qtd, uint32_t **bp, void *arg); +static int imxrt_qh_dump(struct imxrt_qh_s *qh, uint32_t **bp, void *arg); +#else +# define imxrt_qtd_print(qtd) +# define imxrt_qh_print(qh) +# define imxrt_qtd_dump(qtd, bp, arg) OK +# define imxrt_qh_dump(qh, bp, arg) OK +#endif + +static inline uint8_t imxrt_ehci_speed(uint8_t usbspeed); +static int imxrt_ioc_setup(struct imxrt_rhport_s *rhport, + struct imxrt_epinfo_s *epinfo); +static int imxrt_ioc_wait(struct imxrt_epinfo_s *epinfo); +static void imxrt_qh_enqueue(struct imxrt_qh_s *qhead, + struct imxrt_qh_s *qh); +static struct imxrt_qh_s *imxrt_qh_create(struct imxrt_rhport_s *rhport, + struct imxrt_epinfo_s *epinfo); +static int imxrt_qtd_addbpl(struct imxrt_qtd_s *qtd, const void *buffer, + size_t buflen); +static struct imxrt_qtd_s *imxrt_qtd_setupphase( + struct imxrt_epinfo_s *epinfo, const struct usb_ctrlreq_s *req); +static struct imxrt_qtd_s *imxrt_qtd_dataphase(struct imxrt_epinfo_s *epinfo, + void *buffer, int buflen, uint32_t tokenbits); +static struct imxrt_qtd_s *imxrt_qtd_statusphase(uint32_t tokenbits); +static ssize_t imxrtimxrt_virtramaddr_async_setup( + struct imxrt_rhport_s *rhport, struct imxrt_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req, uint8_t *buffer, size_t buflen); +#ifndef CONFIG_USBHOST_INT_DISABLE +static int imxrt_intr_setup(struct imxrt_rhport_s *rhport, + struct imxrt_epinfo_s *epinfo, uint8_t *buffer, size_t buflen); +#endif +static ssize_t imxrt_transfer_wait(struct imxrt_epinfo_s *epinfo); +#ifdef CONFIG_USBHOST_ASYNCH +static inline int imxrt_ioc_async_setup(struct imxrt_rhport_s *rhport, + struct imxrt_epinfo_s *epinfo, usbhost_asynch_t callback, + FAR void *arg); +static void imxrt_asynch_completion(struct imxrt_epinfo_s *epinfo); +#endif + +/* Interrupt Handling *******************************************************/ + +static int imxrt_qtd_ioccheck(struct imxrt_qtd_s *qtd, uint32_t **bp, + void *arg); +static int imxrt_qh_ioccheck(struct imxrt_qh_s *qh, uint32_t **bp, + void *arg); +#ifdef CONFIG_USBHOST_ASYNCH +static int imxrt_qtd_cancel(struct imxrt_qtd_s *qtd, uint32_t **bp, + void *arg); +static int imxrt_qh_cancel(struct imxrt_qh_s *qh, uint32_t **bp, void *arg); +#endif +static inline void imxrt_ioc_bottomhalf(void); +static inline void imxrt_portsc_bottomhalf(void); +static inline void imxrt_syserr_bottomhalf(void); +static inline void imxrt_async_advance_bottomhalf(void); +static void imxrt_ehci_bottomhalf(FAR void *arg); +static int imxrt_ehci_interrupt(int irq, FAR void *context, FAR void *arg); + +/* USB Host Controller Operations *******************************************/ + +static int imxrt_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport); +static int imxrt_rh_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); +static int imxrt_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); + +static int imxrt_ep0configure(FAR struct usbhost_driver_s *drvr, + usbhost_ep_t ep0, uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize); +static int imxrt_epalloc(FAR struct usbhost_driver_s *drvr, + const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep); +static int imxrt_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +static int imxrt_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen); +static int imxrt_free(FAR struct usbhost_driver_s *drvr, + FAR uint8_t *buffer); +static int imxrt_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen); +static int imxrt_iofree(FAR struct usbhost_driver_s *drvr, + FAR uint8_t *buffer); +static int imxrt_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, FAR uint8_t *buffer); +static int imxrt_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, FAR const uint8_t *buffer); +static ssize_t imxrt_transfer(FAR struct usbhost_driver_s *drvr, + usbhost_ep_t ep, FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static int imxrt_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, usbhost_asynch_t callback, + FAR void *arg); +#endif +static int imxrt_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +#ifdef CONFIG_USBHOST_HUB +static int imxrt_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, bool connected); +#endif +static void imxrt_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); + +/* Initialization ***********************************************************/ + +static int imxrt_reset(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* In this driver implementation, support is provided for only a single a + * single USB device. All status information can be simply retained in a + * single global instance. + */ + +static struct imxrt_ehci_s g_ehci; + +/* This is the connection/enumeration interface */ + +static struct usbhost_connection_s g_ehciconn; + +/* Maps USB chapter 9 speed to EHCI speed */ + +static const uint8_t g_ehci_speed[4] = +{ + 0, EHCI_LOW_SPEED, EHCI_FULL_SPEED, EHCI_HIGH_SPEED +}; + +/* The head of the asynchronous queue */ + +static struct imxrt_qh_s g_asynchead aligned_data(32); + +#ifndef CONFIG_USBHOST_INT_DISABLE +/* The head of the periodic queue */ + +static struct imxrt_qh_s g_intrhead aligned_data(32); + +/* The frame list */ + +#ifdef CONFIG_IMXRT_EHCI_PREALLOCATE +static uint32_t g_framelist[FRAME_LIST_SIZE] aligned_data(4096); +#else +static uint32_t *g_framelist; +#endif +#endif /* CONFIG_USBHOST_INT_DISABLE */ + +#ifdef CONFIG_IMXRT_EHCI_PREALLOCATE +/* Pools of pre-allocated data structures. These will all be linked into the + * free lists within g_ehci. These must all be aligned to 32-byte boundaries + */ + +/* Queue Head (QH) pool */ + +static struct imxrt_qh_s g_qhpool[CONFIG_IMXRT_EHCI_NQHS] + aligned_data(32); + +/* Queue Element Transfer Descriptor (qTD) pool */ + +static struct imxrt_qtd_s g_qtdpool[CONFIG_IMXRT_EHCI_NQTDS] + aligned_data(32); + +#else +/* Pools of dynamically data structures. These will all be linked into the + * free lists within g_ehci. These must all be aligned to 32-byte boundaries + */ + +/* Queue Head (QH) pool */ + +static struct imxrt_qh_s *g_qhpool; + +/* Queue Element Transfer Descriptor (qTD) pool */ + +static struct imxrt_qtd_s *g_qtdpool; + +#endif + +#ifdef HAVE_USBHOST_TRACE +/* USB trace strings */ + +static const struct imxrt_ehci_trace_s g_trace1[TRACE1_NSTRINGS] = +{ + TRENTRY(EHCI_TRACE1_SYSTEMERROR, TR_FMT1, + "EHCI ERROR: System error: %06x\n"), + TRENTRY(EHCI_TRACE1_QTDFOREACH_FAILED, TR_FMT1, + "EHCI ERROR: imxrt_qtd_foreach failed: %d\n"), + TRENTRY(EHCI_TRACE1_QHALLOC_FAILED, TR_FMT1, + "EHCI ERROR: Failed to allocate a QH\n"), + TRENTRY(EHCI_TRACE1_BUFTOOBIG, TR_FMT1, + "EHCI ERROR: Buffer too big. Remaining %d\n"), + TRENTRY(EHCI_TRACE1_REQQTDALLOC_FAILED, TR_FMT1, + "EHCI ERROR: Failed to allocate request qTD"), + TRENTRY(EHCI_TRACE1_ADDBPL_FAILED, TR_FMT1, + "EHCI ERROR: imxrt_qtd_addbpl failed: %d\n"), + TRENTRY(EHCI_TRACE1_DATAQTDALLOC_FAILED, TR_FMT1, + "EHCI ERROR: Failed to allocate data buffer qTD, 0"), + TRENTRY(EHCI_TRACE1_DEVDISCONNECTED, TR_FMT1, + "EHCI ERROR: Device disconnected %d\n"), + TRENTRY(EHCI_TRACE1_QHCREATE_FAILED, TR_FMT1, + "EHCI ERROR: imxrt_qh_create failed\n"), + TRENTRY(EHCI_TRACE1_QTDSETUP_FAILED, TR_FMT1, + "EHCI ERROR: imxrt_qtd_setupphase failed\n"), + + TRENTRY(EHCI_TRACE1_QTDDATA_FAILED, TR_FMT1, + "EHCI ERROR: imxrt_qtd_dataphase failed\n"), + TRENTRY(EHCI_TRACE1_QTDSTATUS_FAILED, TR_FMT1, + "EHCI ERROR: imxrt_qtd_statusphase failed\n"), + TRENTRY(EHCI_TRACE1_TRANSFER_FAILED, TR_FMT1, + "EHCI ERROR: Transfer failed %d\n"), + TRENTRY(EHCI_TRACE1_QHFOREACH_FAILED, TR_FMT1, + "EHCI ERROR: imxrt_qh_foreach failed: %d\n"), + TRENTRY(EHCI_TRACE1_SYSERR_INTR, TR_FMT1, + "EHCI: Host System Error Interrupt\n"), + TRENTRY(EHCI_TRACE1_USBERR_INTR, TR_FMT1, + "EHCI: USB Error Interrupt (USBERRINT) Interrupt: %06x\n"), + TRENTRY(EHCI_TRACE1_EPALLOC_FAILED, TR_FMT1, + "EHCI ERROR: Failed to allocate EP info structure\n"), + TRENTRY(EHCI_TRACE1_BADXFRTYPE, TR_FMT1, + "EHCI ERROR: Support for transfer type %d not implemented\n"), + TRENTRY(EHCI_TRACE1_HCHALTED_TIMEOUT, TR_FMT1, + "EHCI ERROR: Timed out waiting for HCHalted. USBSTS: %06x\n"), + TRENTRY(EHCI_TRACE1_QHPOOLALLOC_FAILED, TR_FMT1, + "EHCI ERROR: Failed to allocate the QH pool\n"), + + TRENTRY(EHCI_TRACE1_QTDPOOLALLOC_FAILED, TR_FMT1, + "EHCI ERROR: Failed to allocate the qTD pool\n"), + TRENTRY(EHCI_TRACE1_PERFLALLOC_FAILED, TR_FMT1, + "EHCI ERROR: Failed to allocate the periodic frame list\n"), + TRENTRY(EHCI_TRACE1_RESET_FAILED, TR_FMT1, + "EHCI ERROR: imxrt_reset failed: %d\n"), + TRENTRY(EHCI_TRACE1_RUN_FAILED, TR_FMT1, + "EHCI ERROR: EHCI Failed to run: USBSTS=%06x\n"), + TRENTRY(EHCI_TRACE1_IRQATTACH_FAILED, TR_FMT1, + "EHCI ERROR: Failed to attach IRQ%d\n"), + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(EHCI_VTRACE1_PORTSC_CSC, TR_FMT1, + "EHCI Connect Status Change: %06x\n"), + TRENTRY(EHCI_VTRACE1_PORTSC_CONNALREADY, TR_FMT1, + "EHCI Already connected: %06x\n"), + TRENTRY(EHCI_VTRACE1_PORTSC_DISCALREADY, TR_FMT1, + "EHCI Already disconnected: %06x\n"), + TRENTRY(EHCI_VTRACE1_TOPHALF, TR_FMT1, + "EHCI Interrupt: %06x\n"), + TRENTRY(EHCI_VTRACE1_AAINTR, TR_FMT1, + "EHCI Async Advance Interrupt\n"), + + TRENTRY(EHCI_VTRACE1_CLASSENUM, TR_FMT1, + "EHCI Hub port %d: Enumerate the device\n"), + TRENTRY(EHCI_VTRACE1_USBINTR, TR_FMT1, + "EHCI USB Interrupt (USBINT) Interrupt: %06x\n"), + TRENTRY(EHCI_VTRACE1_ENUM_DISCONN, TR_FMT1, + "EHCI Enumeration not connected\n"), + TRENTRY(EHCI_VTRACE1_INITIALIZING, TR_FMT1, + "EHCI Initializing EHCI Stack\n"), + TRENTRY(EHCI_VTRACE1_HCCPARAMS, TR_FMT1, + "EHCI HCCPARAMS=%06x\n"), + TRENTRY(EHCI_VTRACE1_INIITIALIZED, TR_FMT1, + "EHCI USB EHCI Initialized\n"), +#endif +}; + +static const struct imxrt_ehci_trace_s g_trace2[TRACE2_NSTRINGS] = +{ + TRENTRY(EHCI_TRACE2_EPSTALLED, TR_FMT2, + "EHCI EP%d Stalled: TOKEN=%04x\n"), + TRENTRY(EHCI_TRACE2_EPIOERROR, TR_FMT2, + "EHCI ERROR: EP%d TOKEN=%04x\n"), + TRENTRY(EHCI_TRACE2_CLASSENUM_FAILED, TR_FMT2, + "EHCI Hub port %d usbhost_enumerate() failed: %d\n"), + +#ifdef HAVE_USBHOST_TRACE_VERBOSE + TRENTRY(EHCI_VTRACE2_ASYNCXFR, TR_FMT2, + "EHCI Async transfer EP%d buflen=%d\n"), + TRENTRY(EHCI_VTRACE2_INTRXFR, TR_FMT2, + "EHCI Intr Transfer EP%d buflen=%d\n"), + TRENTRY(EHCI_VTRACE2_IOCCHECK, TR_FMT2, + "EHCI IOC EP%d TOKEN=%04x\n"), + TRENTRY(EHCI_VTRACE2_PORTSC, TR_FMT2, + "EHCI PORTSC%d: %04x\n"), + TRENTRY(EHCI_VTRACE2_PORTSC_CONNECTED, TR_FMT2, + "EHCI RHPort%d connected, pscwait: %d\n"), + TRENTRY(EHCI_VTRACE2_PORTSC_DISCONND, TR_FMT2, + "EHCI RHport%d disconnected, pscwait: %d\n"), + TRENTRY(EHCI_VTRACE2_MONWAKEUP, TR_FMT2, + "EHCI RHPort%d connected: %d\n"), + + TRENTRY(EHCI_VTRACE2_EPALLOC, TR_FMT2, + "EHCI EPALLOC: EP%d TYPE=%d\n"), + TRENTRY(EHCI_VTRACE2_CTRLINOUT, TR_FMT2, + "EHCI CTRLIN/OUT: RHPort%d req: %02x\n"), + TRENTRY(EHCI_VTRACE2_HCIVERSION, TR_FMT2, + "EHCI HCIVERSION %x.%02x\n"), + TRENTRY(EHCI_VTRACE2_HCSPARAMS, TR_FMT2, + "EHCI nports=%d, HCSPARAMS=%04x\n"), +#endif +}; +#endif /* HAVE_USBHOST_TRACE */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_read16 + * + * Description: + * Read 16-bit little endian data + * + ****************************************************************************/ + +static uint16_t imxrt_read16(const uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + return (uint16_t)addr[0] << 8 | (uint16_t)addr[1]; +#else + return (uint16_t)addr[1] << 8 | (uint16_t)addr[0]; +#endif +} + +/**************************************************************************** + * Name: imxrt_read32 + * + * Description: + * Read 32-bit little endian data + * + ****************************************************************************/ + +static inline uint32_t imxrt_read32(const uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + return (uint32_t)imxrt_read16(&addr[0]) << 16 | + (uint32_t)imxrt_read16(&addr[2]); +#else + return (uint32_t)imxrt_read16(&addr[2]) << 16 | + (uint32_t)imxrt_read16(&addr[0]); +#endif +} + +/**************************************************************************** + * Name: imxrt_write16 + * + * Description: + * Write 16-bit little endian data + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void imxrt_write16(uint16_t memval, uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + addr[0] = memval & 0xff; + addr[1] = memval >> 8; +#else + addr[0] = memval >> 8; + addr[1] = memval & 0xff; +#endif +} +#endif + +/**************************************************************************** + * Name: imxrt_write32 + * + * Description: + * Write 32-bit little endian data + * + ****************************************************************************/ + +#if 0 /* Not used */ +static void imxrt_write32(uint32_t memval, uint8_t *addr) +{ +#ifdef CONFIG_ENDIAN_BIG + imxrt_write16(memval >> 16, &addr[0]); + imxrt_write16(memval & 0xffff, &addr[2]); +#else + imxrt_write16(memval & 0xffff, &addr[0]); + imxrt_write16(memval >> 16, &addr[2]); +#endif +} +#endif + +/**************************************************************************** + * Name: imxrt_swap16 + * + * Description: + * Swap bytes on a 16-bit value + * + ****************************************************************************/ + +#ifdef CONFIG_ENDIAN_BIG +static uint16_t imxrt_swap16(uint16_t value) +{ + return ((value >> 8) & 0xff) | ((value & 0xff) << 8); +} +#endif + +/**************************************************************************** + * Name: imxrt_swap32 + * + * Description: + * Swap bytes on a 32-bit value + * + ****************************************************************************/ + +#ifdef CONFIG_ENDIAN_BIG +static uint32_t imxrt_swap32(uint32_t value) +{ + return (uint32_t)imxrt_swap16((uint16_t)((value >> 16) & 0xffff)) | + (uint32_t)imxrt_swap16((uint16_t)(value & 0xffff)) << 16; +} +#endif + +/**************************************************************************** + * Name: imxrt_printreg + * + * Description: + * Print the contents of a IMXRT EHCI register + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_EHCI_REGDEBUG +static void imxrt_printreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite) +{ + uinfo("%08x%s%08x\n", (uintptr_t)regaddr, iswrite ? "<-" : "->", regval); +} +#endif + +/**************************************************************************** + * Name: imxrt_checkreg + * + * Description: + * Check if it is time to output debug information for accesses to a IMXRT + * EHCI register + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_EHCI_REGDEBUG +static void imxrt_checkreg(volatile uint32_t *regaddr, uint32_t regval, + bool iswrite) +{ + static uint32_t *prevaddr = NULL; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last + * time? Are we polling the register? If so, suppress the output. + */ + + if (regaddr == prevaddr && regval == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + imxrt_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + uinfo("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = (uint32_t *)regaddr; + preval = regval; + count = 0; + prevwrite = iswrite; + + /* Show the new register access */ + + imxrt_printreg(regaddr, regval, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: imxrt_getreg + * + * Description: + * Get the contents of an IMXRT register + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_EHCI_REGDEBUG +static uint32_t imxrt_getreg(volatile uint32_t *regaddr) +{ + /* Read the value from the register */ + + uint32_t regval = *regaddr; + + /* Check if we need to print this value */ + + imxrt_checkreg(regaddr, regval, false); + return regval; +} +#else +static inline uint32_t imxrt_getreg(volatile uint32_t *regaddr) +{ + return *regaddr; +} +#endif + +/**************************************************************************** + * Name: imxrt_putreg + * + * Description: + * Set the contents of an IMXRT register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_EHCI_REGDEBUG +static void imxrt_putreg(uint32_t regval, volatile uint32_t *regaddr) +{ + /* Check if we need to print this value */ + + imxrt_checkreg(regaddr, regval, true); + + /* Write the value */ + + *regaddr = regval; +} +#else +static inline void imxrt_putreg(uint32_t regval, volatile uint32_t *regaddr) +{ + *regaddr = regval; +} +#endif + +/**************************************************************************** + * Name: ehci_wait_usbsts + * + * Description: + * Wait for either (1) a field in the USBSTS register to take a specific + * value, (2) for a timeout to occur, or (3) a error to occur. Return + * a value to indicate which terminated the wait. + * + ****************************************************************************/ + +static int ehci_wait_usbsts(uint32_t maskbits, uint32_t donebits, + unsigned int delay) +{ + uint32_t regval; + unsigned int timeout; + + timeout = 0; + do + { + /* Wait 5usec before trying again */ + + up_udelay(5); + timeout += 5; + + /* Read the USBSTS register and check for a system error */ + + regval = imxrt_getreg(&HCOR->usbsts); + if ((regval & EHCI_INT_SYSERROR) != 0) + { + usbhost_trace1(EHCI_TRACE1_SYSTEMERROR, regval); + return -EIO; + } + + /* Mask out the bits of interest */ + + regval &= maskbits; + + /* Loop until the masked bits take the specified value or until a + * timeout occurs. + */ + } + while (regval != donebits && timeout < delay); + + /* We got here because either the waited for condition or a timeout + * occurred. Return a value to indicate which. + */ + + return (regval == donebits) ? OK : -ETIMEDOUT; +} + +/**************************************************************************** + * Name: imxrt_takesem + * + * Description: + * This is just a wrapper to handle the annoying behavior of semaphore + * waits that return due to the receipt of a signal. + * + ****************************************************************************/ + +static int imxrt_takesem(sem_t *sem) +{ + return nxsem_wait_uninterruptible(sem); +} + +/**************************************************************************** + * Name: imxrt_takesem_noncancelable + * + * Description: + * This is just a wrapper to handle the annoying behavior of semaphore + * waits that return due to the receipt of a signal. This version also + * ignores attempts to cancel the thread. + * + ****************************************************************************/ + +static int imxrt_takesem_noncancelable(sem_t *sem) +{ + int result; + int ret = OK; + + do + { + result = nxsem_wait_uninterruptible(sem); + + /* The only expected error is ECANCELED which would occur if the + * calling thread were canceled. + */ + + DEBUGASSERT(result == OK || result == -ECANCELED); + if (ret == OK && result < 0) + { + ret = result; + } + } + while (result < 0); + + return ret; +} + +/**************************************************************************** + * Name: imxrt_qh_alloc + * + * Description: + * Allocate a Queue Head (QH) structure by removing it from the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static struct imxrt_qh_s *imxrt_qh_alloc(void) +{ + struct imxrt_qh_s *qh; + + /* Remove the QH structure from the freelist */ + + qh = (struct imxrt_qh_s *)g_ehci.qhfree; + if (qh) + { + g_ehci.qhfree = ((struct imxrt_list_s *)qh)->flink; + memset(qh, 0, sizeof(struct imxrt_qh_s)); + } + + return qh; +} + +/**************************************************************************** + * Name: imxrt_qh_free + * + * Description: + * Free a Queue Head (QH) structure by returning it to the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static void imxrt_qh_free(struct imxrt_qh_s *qh) +{ + struct imxrt_list_s *entry = (struct imxrt_list_s *)qh; + + /* Put the QH structure back into the free list */ + + entry->flink = g_ehci.qhfree; + g_ehci.qhfree = entry; +} + +/**************************************************************************** + * Name: imxrt_qtd_alloc + * + * Description: + * Allocate a Queue Element Transfer Descriptor (qTD) by removing it from + * the free list + * + * Assumption: Caller holds the exclsem + * + ****************************************************************************/ + +static struct imxrt_qtd_s *imxrt_qtd_alloc(void) +{ + struct imxrt_qtd_s *qtd; + + /* Remove the qTD from the freelist */ + + qtd = (struct imxrt_qtd_s *)g_ehci.qtdfree; + if (qtd) + { + g_ehci.qtdfree = ((struct imxrt_list_s *)qtd)->flink; + memset(qtd, 0, sizeof(struct imxrt_qtd_s)); + } + + return qtd; +} + +/**************************************************************************** + * Name: imxrt_qtd_free + * + * Description: + * Free a Queue Element Transfer Descriptor (qTD) by returning it to the + * free list + * + * Assumption: + * Caller holds the exclsem + * + ****************************************************************************/ + +static void imxrt_qtd_free(struct imxrt_qtd_s *qtd) +{ + struct imxrt_list_s *entry = (struct imxrt_list_s *)qtd; + + /* Put the qTD back into the free list */ + + entry->flink = g_ehci.qtdfree; + g_ehci.qtdfree = entry; +} + +/**************************************************************************** + * Name: imxrt_qh_foreach + * + * Description: + * Give the first entry in a list of Queue Head (QH) structures, call the + * handler for each QH structure in the list (including the one at the head + * of the list). + * + ****************************************************************************/ + +static int imxrt_qh_foreach(struct imxrt_qh_s *qh, uint32_t **bp, + foreach_qh_t handler, void *arg) +{ + struct imxrt_qh_s *next; + uintptr_t physaddr; + int ret; + + DEBUGASSERT(qh && handler); + while (qh) + { + /* Is this the end of the list? Check the horizontal link pointer + * (HLP) terminate (T) bit. If T==1, then the HLP address is not + * valid. + */ + + physaddr = imxrt_swap32(qh->hw.hlp); + if ((physaddr & QH_HLP_T) != 0) + { + /* Set the next pointer to NULL. This will terminate the loop. */ + + next = NULL; + } + + /* Is the next QH the asynchronous list head which will always be at + * the end of the asynchronous queue? + */ + + else if (imxrt_virtramaddr(physaddr & QH_HLP_MASK) == + (uintptr_t)&g_asynchead) + { + /* That will also terminate the loop */ + + next = NULL; + } + + /* Otherwise, there is a QH structure after this one that describes + * another transaction. + */ + + else + { + physaddr = imxrt_swap32(qh->hw.hlp) & QH_HLP_MASK; + next = (struct imxrt_qh_s *)imxrt_virtramaddr(physaddr); + } + + /* Perform the user action on this entry. The action might result in + * unlinking the entry! But that is okay because we already have the + * next QH pointer. + * + * Notice that we do not manage the back pointer (bp). If the call- + * out uses it, it must update it as necessary. + */ + + ret = handler(qh, bp, arg); + + /* If the handler returns any non-zero value, then terminate the + * traversal early. + */ + + if (ret != 0) + { + return ret; + } + + /* Set up to visit the next entry */ + + qh = next; + } + + return OK; +} + +/**************************************************************************** + * Name: imxrt_qtd_foreach + * + * Description: + * Give a Queue Head (QH) instance, call the handler for each qTD structure + * in the queue. + * + ****************************************************************************/ + +static int imxrt_qtd_foreach(struct imxrt_qh_s *qh, foreach_qtd_t handler, + void *arg) +{ + struct imxrt_qtd_s *qtd; + struct imxrt_qtd_s *next; + uintptr_t physaddr; + uint32_t *bp; + int ret; + + DEBUGASSERT(qh && handler); + + /* Handle the special case where the queue is empty */ + + bp = &qh->fqp; /* Start of qTDs in original list */ + physaddr = imxrt_swap32(*bp); /* Physical address of first qTD in CPU order */ + + if ((physaddr & QTD_NQP_T) != 0) + { + return 0; + } + + /* Start with the first qTD in the list */ + + qtd = (struct imxrt_qtd_s *)imxrt_virtramaddr(physaddr); + next = NULL; + + /* And loop until we encounter the end of the qTD list */ + + while (qtd) + { + /* Is this the end of the list? Check the next qTD pointer (NQP) + * terminate (T) bit. If T==1, then the NQP address is not valid. + */ + + if ((imxrt_swap32(qtd->hw.nqp) & QTD_NQP_T) != 0) + { + /* Set the next pointer to NULL. This will terminate the loop. */ + + next = NULL; + } + else + { + physaddr = imxrt_swap32(qtd->hw.nqp) & QTD_NQP_NTEP_MASK; + next = (struct imxrt_qtd_s *)imxrt_virtramaddr(physaddr); + } + + /* Perform the user action on this entry. The action might result in + * unlinking the entry! But that is okay because we already have the + * next qTD pointer. + * + * Notice that we do not manage the back pointer (bp). If the call-out + * uses it, it must update it as necessary. + */ + + ret = handler(qtd, &bp, arg); + + /* If the handler returns any non-zero value, then terminate the + * traversal early. + */ + + if (ret != 0) + { + return ret; + } + + /* Set up to visit the next entry */ + + qtd = next; + } + + return OK; +} + +/**************************************************************************** + * Name: imxrt_qtd_discard + * + * Description: + * This is a imxrt_qtd_foreach callback. It simply unlinks the QTD, + * updates the back pointer, and frees the QTD structure. + * + ****************************************************************************/ + +static int imxrt_qtd_discard(struct imxrt_qtd_s *qtd, uint32_t **bp, + void *arg) +{ + DEBUGASSERT(qtd && bp && *bp); + + /* Remove the qTD from the list by updating the forward pointer to skip + * around this qTD. We do not change that pointer because are repeatedly + * removing the aTD at the head of the QH list. + */ + + **bp = qtd->hw.nqp; + + /* Then free the qTD */ + + imxrt_qtd_free(qtd); + return OK; +} + +/**************************************************************************** + * Name: imxrt_qh_discard + * + * Description: + * Free the Queue Head (QH) and all qTD's attached to the QH. + * + * Assumptions: + * The QH structure itself has already been unlinked from whatever list it + * may have been in. + * + ****************************************************************************/ + +static int imxrt_qh_discard(struct imxrt_qh_s *qh) +{ + int ret; + + DEBUGASSERT(qh); + + /* Free all of the qTD's attached to the QH */ + + ret = imxrt_qtd_foreach(qh, imxrt_qtd_discard, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Then free the QH itself */ + + imxrt_qh_free(qh); + return ret; +} + +/**************************************************************************** + * Name: imxrt_qtd_invalidate + * + * Description: + * This is a callback from imxrt_qtd_foreach. It simply invalidates D- + * cache for address range of the qTD entry. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static int imxrt_qtd_invalidate(struct imxrt_qtd_s *qtd, uint32_t **bp, + void *arg) +{ + /* Invalidate the D-Cache, i.e., force reloading of the D-Cache from memory + * memory over the specified address range. + */ + + up_invalidate_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + return OK; +} +#endif + +/**************************************************************************** + * Name: imxrt_qh_invalidate + * + * Description: + * Invalidate the Queue Head and all qTD entries in the queue. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static int imxrt_qh_invalidate(struct imxrt_qh_s *qh) +{ + /* Invalidate the QH first so that we reload the qTD list head */ + + up_invalidate_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + + /* Then invalidate all of the qTD entries in the queue */ + + return imxrt_qtd_foreach(qh, imxrt_qtd_invalidate, NULL); +} +#endif + +/**************************************************************************** + * Name: imxrt_qtd_flush + * + * Description: + * This is a callback from imxrt_qtd_foreach. It simply flushes D-cache + * for address range of the qTD entry. + * + ****************************************************************************/ + +static int imxrt_qtd_flush(struct imxrt_qtd_s *qtd, uint32_t **bp, void *arg) +{ + /* Flush the D-Cache, i.e., make the contents of the memory match the + * contents of the D-Cache in the specified address range and invalidate + * the D-Cache to force re-loading of the data from memory when next + * accessed. + */ + + up_flush_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + return OK; +} + +/**************************************************************************** + * Name: imxrt_qh_flush + * + * Description: + * Invalidate the Queue Head and all qTD entries in the queue. + * + ****************************************************************************/ + +static int imxrt_qh_flush(struct imxrt_qh_s *qh) +{ + /* Flush the QH first. This will write the contents of the D-cache to RAM + * and invalidate the contents of the D-cache so that the next access will + * be reloaded from D-Cache. + */ + + up_flush_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + + /* Then flush all of the qTD entries in the queue */ + + return imxrt_qtd_foreach(qh, imxrt_qtd_flush, NULL); +} + +/**************************************************************************** + * Name: imxrt_qtd_print + * + * Description: + * Print the context of one qTD + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_EHCI_REGDEBUG +static void imxrt_qtd_print(struct imxrt_qtd_s *qtd) +{ + uinfo(" QTD[%p]:\n", qtd); + uinfo(" hw:\n"); + uinfo(" nqp: %08x alt: %08x token: %08x\n", + qtd->hw.nqp, qtd->hw.alt, qtd->hw.token); + uinfo(" bpl: %08x %08x %08x %08x %08x\n", + qtd->hw.bpl[0], qtd->hw.bpl[1], qtd->hw.bpl[2], + qtd->hw.bpl[3], qtd->hw.bpl[4]); +} +#endif + +/**************************************************************************** + * Name: imxrt_qh_print + * + * Description: + * Print the context of one QH + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_EHCI_REGDEBUG +static void imxrt_qh_print(struct imxrt_qh_s *qh) +{ + struct imxrt_epinfo_s *epinfo; + struct ehci_overlay_s *overlay; + + uinfo("QH[%p]:\n", qh); + uinfo(" hw:\n"); + uinfo(" hlp: %08x epchar: %08x epcaps: %08x cqp: %08x\n", + qh->hw.hlp, qh->hw.epchar, qh->hw.epcaps, qh->hw.cqp); + + overlay = &qh->hw.overlay; + uinfo(" overlay:\n"); + uinfo(" nqp: %08x alt: %08x token: %08x\n", + overlay->nqp, overlay->alt, overlay->token); + uinfo(" bpl: %08x %08x %08x %08x %08x\n", + overlay->bpl[0], overlay->bpl[1], overlay->bpl[2], + overlay->bpl[3], overlay->bpl[4]); + + uinfo(" fqp:\n", qh->fqp); + + epinfo = qh->epinfo; + uinfo(" epinfo[%p]:\n", epinfo); + if (epinfo) + { + uinfo(" EP%d DIR=%s FA=%08x TYPE=%d MaxPacket=%d\n", + epinfo->epno, epinfo->dirin ? "IN" : "OUT", epinfo->devaddr, + epinfo->xfrtype, epinfo->maxpacket); + uinfo(" Toggle=%d iocwait=%d speed=%d result=%d\n", + epinfo->toggle, epinfo->iocwait, epinfo->speed, epinfo->result); + } +} +#endif + +/**************************************************************************** + * Name: imxrt_qtd_dump + * + * Description: + * This is a imxrt_qtd_foreach callout function. It dumps the context of + * one qTD + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_EHCI_REGDEBUG +static int imxrt_qtd_dump(struct imxrt_qtd_s *qtd, uint32_t **bp, void *arg) +{ + imxrt_qtd_print(qtd); + return OK; +} +#endif + +/**************************************************************************** + * Name: imxrt_qh_dump + * + * Description: + * This is a imxrt_qh_foreach call-out function. It dumps a QH structure + * and all of the qTD structures linked to the QH. + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_EHCI_REGDEBUG +static int imxrt_qh_dump(struct imxrt_qh_s *qh, uint32_t **bp, void *arg) +{ + imxrt_qh_print(qh); + return imxrt_qtd_foreach(qh, imxrt_qtd_dump, NULL); +} +#endif + +/**************************************************************************** + * Name: imxrt_ehci_speed + * + * Description: + * Map a speed enumeration value per Chapter 9 of the USB specification to + * the speed enumeration required in the EHCI queue head. + * + ****************************************************************************/ + +static inline uint8_t imxrt_ehci_speed(uint8_t usbspeed) +{ + DEBUGASSERT(usbspeed >= USB_SPEED_LOW && usbspeed <= USB_SPEED_HIGH); + return g_ehci_speed[usbspeed]; +} + +/**************************************************************************** + * Name: imxrt_ioc_setup + * + * Description: + * Set the request for the IOC event well BEFORE enabling the transfer (as + * soon as we are absolutely committed to the to avoid transfer). We do + * this to minimize race conditions. This logic would have to be expanded + * if we want to have more than one packet in flight at a time! + * + * Assumption: The caller holds the EHCI exclsem + * + ****************************************************************************/ + +static int imxrt_ioc_setup(struct imxrt_rhport_s *rhport, + struct imxrt_epinfo_s *epinfo) +{ + irqstate_t flags; + int ret = -ENODEV; + + DEBUGASSERT(rhport && epinfo && !epinfo->iocwait); +#ifdef CONFIG_USBHOST_ASYNCH + DEBUGASSERT(epinfo->callback == NULL); +#endif + + /* Is the device still connected? */ + + flags = enter_critical_section(); + if (rhport->connected) + { + /* Then set iocwait to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer + * completed. + */ + + epinfo->iocwait = true; /* We want to be awakened by IOC interrupt */ + epinfo->status = 0; /* No status yet */ + epinfo->xfrd = 0; /* Nothing transferred yet */ + epinfo->result = -EBUSY; /* Transfer in progress */ +#ifdef CONFIG_USBHOST_ASYNCH + epinfo->callback = NULL; /* No asynchronous callback */ + epinfo->arg = NULL; +#endif + ret = OK; /* We are good to go */ + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: imxrt_ioc_wait + * + * Description: + * Wait for the IOC event. + * + * Assumption: The caller does *NOT* hold the EHCI exclsem. That would + * cause a deadlock when the bottom-half, worker thread needs to take the + * semaphore. + * + ****************************************************************************/ + +static int imxrt_ioc_wait(struct imxrt_epinfo_s *epinfo) +{ + int ret = OK; + + /* Wait for the IOC event. Loop to handle any false alarm semaphore + * counts. Return an error if the task is canceled. + */ + + while (epinfo->iocwait) + { + ret = imxrt_takesem(&epinfo->iocsem); + if (ret < 0) + { + break; + } + } + + return ret < 0 ? ret : epinfo->result; +} + +/**************************************************************************** + * Name: imxrt_qh_enqueue + * + * Description: + * Add a new, ready-to-go QH w/attached qTDs to the asynchronous queue. + * + * Assumptions: The caller holds the EHCI exclsem + * + ****************************************************************************/ + +static void imxrt_qh_enqueue(struct imxrt_qh_s *qhead, struct imxrt_qh_s *qh) +{ + uintptr_t physaddr; + + /* Set the internal fqp field. When we transverse the QH list later, + * we need to know the correct place to start because the overlay may no + * longer point to the first qTD entry. + */ + + qh->fqp = qh->hw.overlay.nqp; + imxrt_qh_dump(qh, NULL, NULL); + + /* Add the new QH to the head of the asynchronous queue list. + * + * First, attach the old head as the new QH HLP and flush the new QH and + * its attached qTDs to RAM. + */ + + qh->hw.hlp = qhead->hw.hlp; + imxrt_qh_flush(qh); + + /* Then set the new QH as the first QH in the asynchronous queue and flush + * the modified head to RAM. + */ + + physaddr = (uintptr_t)imxrt_physramaddr((uintptr_t)qh); + qhead->hw.hlp = imxrt_swap32(physaddr | QH_HLP_TYP_QH); + + up_flush_dcache((uintptr_t)&qhead->hw, + (uintptr_t)&qhead->hw + sizeof(struct ehci_qh_s)); +} + +/**************************************************************************** + * Name: imxrt_qh_create + * + * Description: + * Create a new Queue Head (QH) + * + ****************************************************************************/ + +static struct imxrt_qh_s *imxrt_qh_create(struct imxrt_rhport_s *rhport, + struct imxrt_epinfo_s *epinfo) +{ + struct imxrt_qh_s *qh; + uint32_t rhpndx; + uint32_t regval; + uint8_t hubaddr; + uint8_t hubport; + + /* Allocate a new queue head structure */ + + qh = imxrt_qh_alloc(); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHALLOC_FAILED, 0); + return NULL; + } + + /* Save the endpoint information with the QH itself */ + + qh->epinfo = epinfo; + + /* Write QH endpoint characteristics: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * DEVADDR Device address Endpoint structure + * I Inactivate on Next Transaction 0 + * ENDPT Endpoint number Endpoint structure + * EPS Endpoint speed Endpoint structure + * DTC Data toggle control 1 + * MAXPKT Max packet size Endpoint structure + * C Control endpoint Calculated + * RL NAK count reloaded 8 + */ + + regval = ((uint32_t)epinfo->devaddr << QH_EPCHAR_DEVADDR_SHIFT) | + ((uint32_t)epinfo->epno << QH_EPCHAR_ENDPT_SHIFT) | + ((uint32_t)imxrt_ehci_speed(epinfo->speed) << + QH_EPCHAR_EPS_SHIFT) | + QH_EPCHAR_DTC | + ((uint32_t)epinfo->maxpacket << QH_EPCHAR_MAXPKT_SHIFT) | + ((uint32_t)8 << QH_EPCHAR_RL_SHIFT); + + /* Paragraph 3.6.3: "Control Endpoint Flag (C). If the QH.EPS field + * indicates the endpoint is not a high-speed device, and the endpoint + * is an control endpoint, then software must set this bit to a one. + * Otherwise it should always set this bit to a zero." + */ + + if (epinfo->speed != USB_SPEED_HIGH && + epinfo->xfrtype == USB_EP_ATTR_XFER_CONTROL) + { + regval |= QH_EPCHAR_C; + } + + /* Save the endpoint characteristics word with the correct byte order */ + + qh->hw.epchar = imxrt_swap32(regval); + + /* Write QH endpoint capabilities + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * SSMASK Interrupt Schedule Mask Depends on epinfo->xfrtype + * SCMASK Split Completion Mask 0 + * HUBADDR Hub Address Always 0 for now + * PORT Port number RH port index + 1 + * MULT High band width multiplier 1 + */ + + rhpndx = RHPNDX(rhport); + +#ifdef CONFIG_USBHOST_HUB + /* REVISIT: Future HUB support will require the HUB port number + * and HUB device address to be included here: + * + * - The HUB device address is the USB device address of the USB 2.0 Hub + * below which a full- or low-speed device is attached. + * - The HUB port number is the port number on the above USB 2.0 Hub + * + * These fields are used in the split-transaction protocol. The kludge + * below should work for hubs connected directly to a root hub port, + * but would not work for devices connected to downstream hubs. + */ + +#warning Missing logic + hubaddr = rhport->ep0.devaddr; + hubport = rhpndx + 1; +#else + hubaddr = rhport->ep0.devaddr; + hubport = rhpndx + 1; +#endif + + regval = ((uint32_t)hubaddr << QH_EPCAPS_HUBADDR_SHIFT) | + ((uint32_t)hubport << QH_EPCAPS_PORT_SHIFT) | + ((uint32_t)1 << QH_EPCAPS_MULT_SHIFT); + +#ifndef CONFIG_USBHOST_INT_DISABLE + if (epinfo->xfrtype == USB_EP_ATTR_XFER_INT) + { + /* Here, the S-Mask field in the queue head is set to 1, indicating + * that the transaction for the endpoint should be executed on the bus + * during micro-frame 0 of the frame. + * + * REVISIT: The polling interval should be controlled by the which + * entry is the framelist holds the QH pointer for a given micro-frame + * and the QH pointer should be replicated for different polling rates. + * This implementation currently just sets all frame_list entry to + * all the same interrupt queue. That should work but will not give + * any control over polling rates. + */ +#warning REVISIT + + regval |= ((uint32_t)1 << QH_EPCAPS_SSMASK_SHIFT); + } +#endif + + qh->hw.epcaps = imxrt_swap32(regval); + + /* Mark this as the end of this list. This will be overwritten if/when the + * next qTD is added to the queue. + */ + + qh->hw.hlp = imxrt_swap32(QH_HLP_T); + qh->hw.overlay.nqp = imxrt_swap32(QH_NQP_T); + qh->hw.overlay.alt = imxrt_swap32(QH_AQP_T); + return qh; +} + +/**************************************************************************** + * Name: imxrt_qtd_addbpl + * + * Description: + * Add a buffer pointer list to a qTD. + * + ****************************************************************************/ + +static int imxrt_qtd_addbpl(struct imxrt_qtd_s *qtd, const void *buffer, + size_t buflen) +{ + uint32_t physaddr; + uint32_t nbytes; + uint32_t next; + int ndx; + + /* Flush the contents of the data buffer to RAM so that the correct + * contents will be accessed for an OUT DMA. + */ + + up_flush_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); + + /* Loop, adding the aligned physical addresses of the buffer to the buffer + * page list. Only the first entry need not be aligned (because only the + * first entry has the offset field). The subsequent entries must begin on + * 4KB address boundaries. + */ + + physaddr = (uint32_t)imxrt_physramaddr((uintptr_t)buffer); + + for (ndx = 0; ndx < 5; ndx++) + { + /* Write the physical address of the buffer into the qTD buffer pointer + * list. + */ + + qtd->hw.bpl[ndx] = imxrt_swap32(physaddr); + + /* Get the next buffer pointer (in the case where we will have to + * transfer more then one chunk). This buffer must be aligned to a + * 4KB address boundary. + */ + + next = (physaddr + 4096) & ~4095; + + /* How many bytes were included in the last buffer? Was it the whole + * thing? + */ + + nbytes = next - physaddr; + if (nbytes >= buflen) + { + /* Yes... it was the whole thing. Break out of the loop early. */ + + break; + } + + /* Adjust the buffer length and physical address for the next time + * through the loop. + */ + + buflen -= nbytes; + physaddr = next; + } + + /* Handle the case of a huge buffer > 4*4KB = 16KB */ + + if (ndx >= 5) + { + usbhost_trace1(EHCI_TRACE1_BUFTOOBIG, buflen); + return -EFBIG; + } + + return OK; +} + +/**************************************************************************** + * Name: imxrt_qtd_setupphase + * + * Description: + * Create a SETUP phase request qTD. + * + ****************************************************************************/ + +static struct imxrt_qtd_s * + imxrt_qtd_setupphase(struct imxrt_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req) +{ + struct imxrt_qtd_s *qtd; + uint32_t regval; + int ret; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = imxrt_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = imxrt_swap32(QTD_NQP_T); + qtd->hw.alt = imxrt_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code QTD_TOKEN_PID_SETUP + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete 0 + * NBYTES Total Bytes to Transfer USB_SIZEOF_CTRLREQ + * TOGGLE Data Toggle 0 + */ + + regval = QTD_TOKEN_ACTIVE | QTD_TOKEN_PID_SETUP | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT) | + ((uint32_t)USB_SIZEOF_CTRLREQ << QTD_TOKEN_NBYTES_SHIFT); + + qtd->hw.token = imxrt_swap32(regval); + + /* Add the buffer data */ + + ret = imxrt_qtd_addbpl(qtd, req, USB_SIZEOF_CTRLREQ); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret); + imxrt_qtd_free(qtd); + return NULL; + } + + /* Add the data transfer size to the count in the epinfo structure */ + + epinfo->xfrd += USB_SIZEOF_CTRLREQ; + + return qtd; +} + +/**************************************************************************** + * Name: imxrt_qtd_dataphase + * + * Description: + * Create a data transfer or SET data phase qTD. + * + ****************************************************************************/ + +static struct imxrt_qtd_s *imxrt_qtd_dataphase(struct imxrt_epinfo_s *epinfo, + void *buffer, int buflen, + uint32_t tokenbits) +{ + struct imxrt_qtd_s *qtd; + uint32_t regval; + int ret; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = imxrt_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_DATAQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = imxrt_swap32(QTD_NQP_T); + qtd->hw.alt = imxrt_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code Contained in tokenbits + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete Contained in tokenbits + * NBYTES Total Bytes to Transfer buflen + * TOGGLE Data Toggle Contained in tokenbits + */ + + regval = tokenbits | QTD_TOKEN_ACTIVE | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT) | + ((uint32_t)buflen << QTD_TOKEN_NBYTES_SHIFT); + + qtd->hw.token = imxrt_swap32(regval); + + /* Add the buffer information to the buffer pointer list */ + + ret = imxrt_qtd_addbpl(qtd, buffer, buflen); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_ADDBPL_FAILED, -ret); + imxrt_qtd_free(qtd); + return NULL; + } + + /* Add the data transfer size to the count in the epinfo structure */ + + epinfo->xfrd += buflen; + + return qtd; +} + +/**************************************************************************** + * Name: imxrt_qtd_statusphase + * + * Description: + * Create a STATUS phase request qTD. + * + ****************************************************************************/ + +static struct imxrt_qtd_s *imxrt_qtd_statusphase(uint32_t tokenbits) +{ + struct imxrt_qtd_s *qtd; + uint32_t regval; + + /* Allocate a new Queue Element Transfer Descriptor (qTD) */ + + qtd = imxrt_qtd_alloc(); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_REQQTDALLOC_FAILED, 0); + return NULL; + } + + /* Mark this as the end of the list (this will be overwritten if another + * qTD is added after this one). + */ + + qtd->hw.nqp = imxrt_swap32(QTD_NQP_T); + qtd->hw.alt = imxrt_swap32(QTD_AQP_T); + + /* Write qTD token: + * + * FIELD DESCRIPTION VALUE/SOURCE + * -------- ------------------------------- -------------------- + * STATUS Status QTD_TOKEN_ACTIVE + * PID PID Code Contained in tokenbits + * CERR Error Counter 3 + * CPAGE Current Page 0 + * IOC Interrupt on complete QTD_TOKEN_IOC + * NBYTES Total Bytes to Transfer 0 + * TOGGLE Data Toggle Contained in tokenbits + */ + + regval = tokenbits | QTD_TOKEN_ACTIVE | QTD_TOKEN_IOC | + ((uint32_t)3 << QTD_TOKEN_CERR_SHIFT); + + qtd->hw.token = imxrt_swap32(regval); + return qtd; +} + +/**************************************************************************** + * Name: imxrt_async_setup + * + * Description: + * Process a IN or OUT request on any asynchronous endpoint (bulk or + * control). This function will enqueue the request and wait for it to + * complete. Bulk data transfers differ in that req == NULL and there are + * not SETUP or STATUS phases. + * + * This is a blocking function; it will not return until the control + * transfer has completed. + * + * Assumption: The caller holds the EHCI exclsem. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is return on + * any failure. + * + ****************************************************************************/ + +static int imxrt_async_setup(struct imxrt_rhport_s *rhport, + struct imxrt_epinfo_s *epinfo, + const struct usb_ctrlreq_s *req, + uint8_t *buffer, size_t buflen) +{ + struct imxrt_qh_s *qh; + struct imxrt_qtd_s *qtd; + uintptr_t physaddr; + uint32_t *flink; + uint32_t *alt; + uint32_t toggle; + bool dirin = false; + int ret; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_ASYNCXFR, epinfo->epno, buflen); +#else + uinfo("RHport%d EP%d: buffer=%p, buflen=%d, req=%p\n", + RHPORT(rhport), epinfo->epno, buffer, buflen, req); +#endif + + DEBUGASSERT(rhport && epinfo); + + /* A buffer may or may be supplied with an EP0 SETUP transfer. A buffer + * will always be present for normal endpoint data transfers. + */ + + DEBUGASSERT(req || (buffer && buflen > 0)); + + /* Create and initialize a Queue Head (QH) structure for this transfer */ + + qh = imxrt_qh_create(rhport, epinfo); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0); + return -ENOMEM; + } + + /* Initialize the QH link and get the next data toggle (not used for SETUP + * transfers) + */ + + flink = &qh->hw.overlay.nqp; + toggle = (uint32_t)epinfo->toggle << QTD_TOKEN_TOGGLE_SHIFT; + ret = -EIO; + + /* Is there an EP0 SETUP request? If so, req will be non-NULL and we will + * queue two or three qTDs: + * + * 1) One for the SETUP phase, + * 2) One for the DATA phase (if there is data), and + * 3) One for the STATUS phase. + * + * If this is not an EP0 SETUP request, then only a data transfer will be + * enqueued. + */ + + if (req != NULL) + { + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the SETUP + * phase of the request sequence. + */ + + qtd = imxrt_qtd_setupphase(epinfo, req); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDSETUP_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to the QH head. */ + + physaddr = imxrt_physramaddr((uintptr_t)qtd); + *flink = imxrt_swap32(physaddr); + + /* Get the new forward link pointer and data toggle */ + + flink = &qtd->hw.nqp; + toggle = QTD_TOKEN_TOGGLE; + } + + /* A buffer may or may be supplied with an EP0 SETUP transfer. A buffer + * will always be present for normal endpoint data transfers. + */ + + alt = NULL; + if (buffer != NULL && buflen > 0) + { + uint32_t tokenbits; + + /* Extra TOKEN bits include the data toggle, the data PID, and if + * there is no request, an indication to interrupt at the end of this + * transfer. + */ + + tokenbits = toggle; + + /* Get the data token direction. + * + * If this is a SETUP request, use the direction contained in the + * request. The IOC bit is not set. + */ + + if (req) + { + if ((req->type & USB_REQ_DIR_MASK) == USB_REQ_DIR_IN) + { + tokenbits |= QTD_TOKEN_PID_IN; + dirin = true; + } + else + { + tokenbits |= QTD_TOKEN_PID_OUT; + dirin = false; + } + } + + /* Otherwise, the endpoint is uni-directional. Get the direction from + * the epinfo structure. Since this is not an EP0 SETUP request, + * nothing follows the data and we want the IOC interrupt when the + * data transfer completes. + */ + + else if (epinfo->dirin) + { + tokenbits |= (QTD_TOKEN_PID_IN | QTD_TOKEN_IOC); + dirin = true; + } + else + { + tokenbits |= (QTD_TOKEN_PID_OUT | QTD_TOKEN_IOC); + dirin = false; + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the data + * buffer. + */ + + qtd = imxrt_qtd_dataphase(epinfo, buffer, buflen, tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to either QH head of the SETUP qTD. */ + + physaddr = imxrt_physramaddr((uintptr_t)qtd); + *flink = imxrt_swap32(physaddr); + + /* Set the forward link pointer to this new qTD */ + + flink = &qtd->hw.nqp; + + /* If this was an IN transfer, then setup a pointer alternate link. + * The EHCI hardware will use this link if a short packet is received. + */ + + if (dirin) + { + alt = &qtd->hw.alt; + } + } + + /* If this is an EP0 SETUP request, then enqueue one more qTD for the + * STATUS phase transfer. + */ + + if (req != NULL) + { + /* Extra TOKEN bits include the data toggle and the correct data PID. */ + + uint32_t tokenbits = toggle; + + /* The status phase direction is the opposite of the data phase. If + * this is an IN request, then we received the buffer and we will send + * the zero length packet handshake. + */ + + if ((req->type & USB_REQ_DIR_MASK) == USB_REQ_DIR_IN) + { + tokenbits |= QTD_TOKEN_PID_OUT; + } + + /* Otherwise, this in an OUT request. We send the buffer and we expect + * to receive the NULL packet handshake. + */ + + else + { + tokenbits |= QTD_TOKEN_PID_IN; + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) + * for the status + */ + + qtd = imxrt_qtd_statusphase(tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDSTATUS_FAILED, 0); + goto errout_with_qh; + } + + /* Link the new qTD to either the SETUP or data qTD. */ + + physaddr = imxrt_physramaddr((uintptr_t)qtd); + *flink = imxrt_swap32(physaddr); + + /* In an IN data qTD was also enqueued, then linked the data qTD's + * alternate pointer to this STATUS phase qTD in order to handle short + * transfers. + */ + + if (alt) + { + *alt = imxrt_swap32(physaddr); + } + } + + /* Add the new QH to the head of the asynchronous queue list */ + + imxrt_qh_enqueue(&g_asynchead, qh); + return OK; + + /* Clean-up after an error */ + +errout_with_qh: + imxrt_qh_discard(qh); + return ret; +} + +/**************************************************************************** + * Name: imxrt_intr_setup + * + * Description: + * Process a IN or OUT request on any interrupt endpoint by inserting a qTD + * into the periodic frame list. + * + * Paragraph 4.10.7 "Adding Interrupt Queue Heads to the Periodic Schedule" + * "The link path(s) from the periodic frame list to a queue head + * establishes in which frames a transaction can be executed for the + * queue head. Queue heads are linked into the periodic schedule so they + * are polled at the appropriate rate. System software sets a bit in a + * queue head's S-Mask to indicate which micro-frame with-in a 1 + * millisecond period a transaction should be executed for the queue + * head. Software must ensure that all queue heads in the periodic + * schedule have S-Mask set to a non-zero value. An S-mask with a zero + * value in the context of the periodic schedule yields undefined + * results. + * + * "If the desired poll rate is greater than one frame, system software + * can use a combination of queue head linking and S-Mask values to + * spread interrupts of equal poll rates through the schedule so that the + * periodic bandwidth is allocated and managed in the most efficient + * manner possible." + * + * Paragraph 4.6 "Periodic Schedule" + * + * "The periodic schedule is used to manage all isochronous and interrupt + * transfer streams. The base of the periodic schedule is the periodic + * frame list. Software links schedule data structures to the periodic + * frame list to produce a graph of scheduled data structures. The graph + * represents an appropriate sequence of transactions on the USB. ... + * isochronous transfers (using iTDs and siTDs) with a period of one are + * linked directly to the periodic frame list. Interrupt transfers (are + * managed with queue heads) and isochronous streams with periods other + * than one are linked following the period-one iTD/siTDs. Interrupt + * queue heads are linked into the frame list ordered by poll rate. + * Longer poll rates are linked first (e.g. closest to the periodic + * frame list), followed by shorter poll rates, with queue heads with a + * poll rate of one, on the very end." + * + * Assumption: The caller holds the EHCI exclsem. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is return on + * any failure. + * + ****************************************************************************/ + +#ifndef CONFIG_USBHOST_INT_DISABLE +static int imxrt_intr_setup(struct imxrt_rhport_s *rhport, + struct imxrt_epinfo_s *epinfo, + uint8_t *buffer, size_t buflen) +{ + struct imxrt_qh_s *qh; + struct imxrt_qtd_s *qtd; + uintptr_t physaddr; + uint32_t tokenbits; + uint32_t regval; + int ret; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_INTRXFR, epinfo->epno, buflen); +#else + uinfo("RHport%d EP%d: buffer=%p, buflen=%d\n", + RHPORT(rhport), epinfo->epno, buffer, buflen); +#endif + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* Create and initialize a Queue Head (QH) structure for this transfer */ + + qh = imxrt_qh_create(rhport, epinfo); + if (qh == NULL) + { + usbhost_trace1(EHCI_TRACE1_QHCREATE_FAILED, 0); + return -ENOMEM; + } + + /* Extra TOKEN bits include the data toggle, the data PID, and an + * indication to interrupt at the end of this transfer. + */ + + tokenbits = (uint32_t)epinfo->toggle << QTD_TOKEN_TOGGLE_SHIFT; + + /* Get the data token direction. */ + + if (epinfo->dirin) + { + tokenbits |= (QTD_TOKEN_PID_IN | QTD_TOKEN_IOC); + } + else + { + tokenbits |= (QTD_TOKEN_PID_OUT | QTD_TOKEN_IOC); + } + + /* Allocate a new Queue Element Transfer Descriptor (qTD) for the data + * buffer. + */ + + qtd = imxrt_qtd_dataphase(epinfo, buffer, buflen, tokenbits); + if (qtd == NULL) + { + usbhost_trace1(EHCI_TRACE1_QTDDATA_FAILED, 0); + ret = -ENOMEM; + goto errout_with_qh; + } + + /* Link the new qTD to the QH. */ + + physaddr = imxrt_physramaddr((uintptr_t)qtd); + qh->hw.overlay.nqp = imxrt_swap32(physaddr); + + /* Disable the periodic schedule */ + + regval = imxrt_getreg(&HCOR->usbcmd); + regval &= ~EHCI_USBCMD_PSEN; + imxrt_putreg(regval, &HCOR->usbcmd); + + /* Add the new QH to the head of the interrupt transfer list */ + + imxrt_qh_enqueue(&g_intrhead, qh); + + /* Re-enable the periodic schedule */ + + regval |= EHCI_USBCMD_PSEN; + imxrt_putreg(regval, &HCOR->usbcmd); + return OK; + + /* Clean-up after an error */ + +errout_with_qh: + imxrt_qh_discard(qh); + return ret; +} +#endif /* CONFIG_USBHOST_INT_DISABLE */ + +/**************************************************************************** + * Name: imxrt_transfer_wait + * + * Description: + * Wait for an IN or OUT transfer to complete. + * + * Assumption: The caller holds the EHCI exclsem. The caller must be aware + * that the EHCI exclsem will released while waiting for the transfer to + * complete, but will be re-acquired when before returning. The state of + * EHCI resources could be very different upon return. + * + * Returned Value: + * On success, this function returns the number of bytes actually + * transferred. For control transfers, this size includes the size of the + * control request plus the size of the data (which could be short); for + * bulk transfers, this will be the number of data bytes transfers (which + * could be short). + * + ****************************************************************************/ + +static ssize_t imxrt_transfer_wait(struct imxrt_epinfo_s *epinfo) +{ + int ret; + int ret2; + + /* Release the EHCI semaphore while we wait. Other threads need the + * opportunity to access the EHCI resources while we wait. + * + * REVISIT: Is this safe? NO. This is a bug and needs rethinking. + * We need to lock all of the port-resources (not EHCI common) until + * the transfer is complete. But we can't use the common EHCI exclsem + * or we will deadlock while waiting (because the working thread that + * wakes this thread up needs the exclsem). + */ + + /* REVISIT */ + + imxrt_givesem(&g_ehci.exclsem); + + /* Wait for the IOC completion event */ + + ret = imxrt_ioc_wait(epinfo); + + /* Re-acquire the EHCI semaphore. The caller expects to be holding + * this upon return. + */ + + ret2 = imxrt_takesem_noncancelable(&g_ehci.exclsem); + if (ret >= 0 && ret2 < 0) + { + ret = ret2; + } + +#if 0 /* Does not seem to be needed */ + /* Was there a data buffer? Was this an OUT transfer? */ + + if (buffer != NULL && buflen > 0 && !dirin) + { + /* We have received data from the host -- unless there was an error. + * in any event, we will invalidate the data buffer so that we will + * reload any new data freshly DMAed into the user buffer. + * + * NOTE: This might be un-necessary. We cleaned and invalidated the + * D-Cache prior to starting the DMA so the D-Cache should still be + * invalid in this memory region. + */ + + up_invalidate_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); + } +#endif + + /* Did imxrt_ioc_wait() or imxrt_takesem_noncancelable() report an + * error? + */ + + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_TRANSFER_FAILED, -ret); + epinfo->iocwait = false; + return (ssize_t)ret; + } + + /* Transfer completed successfully. Return the number of bytes + * transferred. + */ + + return epinfo->xfrd; +} + +/**************************************************************************** + * Name: imxrt_ioc_async_setup + * + * Description: + * Setup to receive an asynchronous notification when a transfer completes. + * + * Input Parameters: + * epinfo - The IN or OUT endpoint descriptor for the device endpoint on + * which the transfer will be performed. + * callback - The function to be called when the completes + * arg - An arbitrary argument that will be provided with the callback. + * + * Returned Value: + * None + * + * Assumptions: + * - Called from the interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static inline int imxrt_ioc_async_setup(struct imxrt_rhport_s *rhport, + struct imxrt_epinfo_s *epinfo, + usbhost_asynch_t callback, + FAR void *arg) +{ + irqstate_t flags; + int ret = -ENODEV; + + DEBUGASSERT(rhport && epinfo && !epinfo->iocwait && + callback != NULL && epinfo->callback == NULL); + + /* Is the device still connected? */ + + flags = enter_critical_section(); + if (rhport->connected) + { + /* Then save callback information to used when either (1) the + * device is disconnected, or (2) the transfer completes. + */ + + epinfo->iocwait = false; /* No synchronous wakeup */ + epinfo->status = 0; /* No status yet */ + epinfo->xfrd = 0; /* Nothing transferred yet */ + epinfo->result = -EBUSY; /* Transfer in progress */ + epinfo->callback = callback; /* Asynchronous callback */ + epinfo->arg = arg; /* Argument that accompanies the callback */ + ret = OK; /* We are good to go */ + } + + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: imxrt_asynch_completion + * + * Description: + * This function is called at the interrupt level when an asynchronous + * transfer completes. It performs the pending callback. + * + * Input Parameters: + * epinfo - The IN or OUT endpoint descriptor for the device endpoint on + * which the transfer was performed. + * + * Returned Value: + * None + * + * Assumptions: + * - Called from the interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void imxrt_asynch_completion(struct imxrt_epinfo_s *epinfo) +{ + usbhost_asynch_t callback; + ssize_t nbytes; + void *arg; + int result; + + DEBUGASSERT(epinfo != NULL && epinfo->iocwait == false && + epinfo->callback != NULL); + + /* Extract and reset the callback info */ + + callback = epinfo->callback; + arg = epinfo->arg; + result = epinfo->result; + nbytes = epinfo->xfrd; + + epinfo->callback = NULL; + epinfo->arg = NULL; + epinfo->result = OK; + epinfo->iocwait = false; + + /* Then perform the callback. Provide the number of bytes successfully + * transferred or the negated errno value in the event of a failure. + */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: imxrt_qtd_ioccheck + * + * Description: + * This function is a imxrt_qtd_foreach() callback function. It services + * one qTD in the asynchronous queue. It removes all of the qTD + * structures that are no longer active. + * + ****************************************************************************/ + +static int imxrt_qtd_ioccheck(struct imxrt_qtd_s *qtd, uint32_t **bp, + void *arg) +{ + struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)arg; + DEBUGASSERT(qtd && epinfo); + + /* Make sure we reload the QH from memory */ + + up_invalidate_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + imxrt_qtd_print(qtd); + + /* Remove the qTD from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + */ + + **bp = qtd->hw.nqp; + + /* Subtract the number of bytes left un-transferred. The epinfo->xfrd + * field is initialized to the total number of bytes to be transferred + * (all qTDs in the list). We subtract out the number of un-transferred + * bytes on each transfer and the final result will be the number of bytes + * actually transferred. + */ + + epinfo->xfrd -= (imxrt_swap32(qtd->hw.token) & QTD_TOKEN_NBYTES_MASK) >> + QTD_TOKEN_NBYTES_SHIFT; + + /* Release this QH by returning it to the free list */ + + imxrt_qtd_free(qtd); + return OK; +} + +/**************************************************************************** + * Name: imxrt_qh_ioccheck + * + * Description: + * This function is a imxrt_qh_foreach() callback function. It services + * one QH in the asynchronous queue. It check all attached qTD structures + * and remove all of the structures that are no longer active. if all of + * the qTD structures are removed, then QH itself will also be removed. + * + ****************************************************************************/ + +static int imxrt_qh_ioccheck(struct imxrt_qh_s *qh, uint32_t **bp, void *arg) +{ + struct imxrt_epinfo_s *epinfo; + uint32_t token; + int ret; + + DEBUGASSERT(qh && bp); + + /* Make sure we reload the QH from memory */ + + up_invalidate_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + imxrt_qh_print(qh); + + /* Get the endpoint info pointer from the extended QH data. Only the + * g_asynchead QH can have a NULL epinfo field. + */ + + epinfo = qh->epinfo; + DEBUGASSERT(epinfo); + + /* Paragraph 3.6.3: "The nine DWords in [the Transfer Overlay] area + * represent a transaction working space for the host controller. The + * general operational model is that the host controller can detect + * whether the overlay area contains a description of an active transfer. + * If it does not contain an active transfer, then it follows the Queue + * Head Horizontal Link Pointer to the next queue head. The host + * controller will never follow the Next Transfer Queue Element or + * Alternate Queue Element pointers unless it is actively attempting to + * advance the queue ..." + */ + + /* Is the qTD still active? */ + + token = imxrt_swap32(qh->hw.overlay.token); + usbhost_vtrace2(EHCI_VTRACE2_IOCCHECK, epinfo->epno, token); + + if ((token & QH_TOKEN_ACTIVE) != 0) + { + /* Yes... we cannot process the QH while it is still active. Return + * zero to visit the next QH in the list. + */ + + *bp = &qh->hw.hlp; + return OK; + } + + /* Remove all active, attached qTD structures from the inactive QH */ + + ret = imxrt_qtd_foreach(qh, imxrt_qtd_ioccheck, (void *)qh->epinfo); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* If there is no longer anything attached to the QH, then remove it from + * the asynchronous queue. + */ + + if ((imxrt_swap32(qh->fqp) & QTD_NQP_T) != 0) + { + /* Set the forward link of the previous QH to point to the next + * QH in the list. + */ + + **bp = qh->hw.hlp; + up_flush_dcache((uintptr_t)*bp, (uintptr_t)*bp + sizeof(uint32_t)); + + /* Check for errors, update the data toggle */ + + if ((token & QH_TOKEN_ERRORS) == 0) + { + /* No errors.. Save the last data toggle value */ + + epinfo->toggle = (token >> QTD_TOKEN_TOGGLE_SHIFT) & 1; + + /* Report success */ + + epinfo->status = 0; + epinfo->result = OK; + } + else + { + /* An error occurred */ + + epinfo->status = (token & QH_TOKEN_STATUS_MASK) >> + QH_TOKEN_STATUS_SHIFT; + + /* The HALT condition is set on a variety of conditions: babble, + * error counter countdown to zero, or a STALL. If we can rule + * out babble (babble bit not set) and if the error counter is + * non-zero, then we can assume a STALL. In this case, we return + * -PERM to inform the class driver of the stall condition. + */ + + if ((token & (QH_TOKEN_BABBLE | QH_TOKEN_HALTED)) == + QH_TOKEN_HALTED && + (token & QH_TOKEN_CERR_MASK) != 0) + { + /* It is a stall, Note that the data toggle is reset + * after the stall. + */ + + usbhost_trace2(EHCI_TRACE2_EPSTALLED, epinfo->epno, token); + epinfo->result = -EPERM; + epinfo->toggle = 0; + } + else + { + /* Otherwise, it is some kind of data transfer error */ + + usbhost_trace2(EHCI_TRACE2_EPIOERROR, epinfo->epno, token); + epinfo->result = -EIO; + } + } + + /* Is there a thread waiting for this transfer to complete? */ + + if (epinfo->iocwait) + { + /* Yes... wake it up */ + + epinfo->iocwait = false; + imxrt_givesem(&epinfo->iocsem); + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. Is there a pending asynchronous transfer? */ + + else if (epinfo->callback != NULL) + { + /* Yes.. perform the callback */ + + imxrt_asynch_completion(epinfo); + } +#endif + + /* Then release this QH by returning it to the free list */ + + imxrt_qh_free(qh); + } + else + { + /* Otherwise, the horizontal link pointer of this QH will become the + * next back pointer. + */ + + *bp = &qh->hw.hlp; + } + + return OK; +} + +/**************************************************************************** + * Name: imxrt_qtd_cancel + * + * Description: + * This function is a imxrt_qtd_foreach() callback function. It removes + * each qTD attached to a QH. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int imxrt_qtd_cancel(struct imxrt_qtd_s *qtd, uint32_t **bp, + void *arg) +{ + DEBUGASSERT(qtd != NULL && bp != NULL); + + /* Make sure we reload the QH from memory */ + + up_invalidate_dcache((uintptr_t)&qtd->hw, + (uintptr_t)&qtd->hw + sizeof(struct ehci_qtd_s)); + imxrt_qtd_print(qtd); + + /* Remove the qTD from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + * + * REVISIT: There is a race condition here that needs to be resolved. + */ + + **bp = qtd->hw.nqp; + + /* Release this QH by returning it to the free list */ + + imxrt_qtd_free(qtd); + return OK; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/**************************************************************************** + * Name: imxrt_qh_cancel + * + * Description: + * This function is a imxrt_qh_foreach() callback function. It cancels + * one QH in the asynchronous queue. It will remove all attached qTD + * structures and remove all of the structures that are no longer active. + * Then QH itself will also be removed. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int imxrt_qh_cancel(struct imxrt_qh_s *qh, uint32_t **bp, void *arg) +{ + struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)arg; + uint32_t regval; + int ret; + + DEBUGASSERT(qh != NULL && bp != NULL && epinfo != NULL); + + /* Make sure we reload the QH from memory */ + + up_invalidate_dcache((uintptr_t)&qh->hw, + (uintptr_t)&qh->hw + sizeof(struct ehci_qh_s)); + imxrt_qh_print(qh); + + /* Check if this is the QH that we are looking for */ + + if (qh->epinfo == epinfo) + { + /* No... keep looking */ + + return OK; + } + + /* Disable both the asynchronous and period schedules */ + + regval = imxrt_getreg(&HCOR->usbcmd); + imxrt_putreg(regval & ~(EHCI_USBCMD_ASEN | EHCI_USBCMD_PSEN), + &HCOR->usbcmd); + + /* Remove the QH from the list + * + * NOTE that we don't check if the qTD is active nor do we check if there + * are any errors reported in the qTD. If the transfer halted due to + * an error, then qTDs in the list after the error qTD will still appear + * to be active. + * + * REVISIT: There is a race condition here that needs to be resolved. + */ + + **bp = qh->hw.hlp; + up_flush_dcache((uintptr_t)*bp, (uintptr_t)*bp + sizeof(uint32_t)); + + /* Re-enable the schedules (if they were enabled before. */ + + imxrt_putreg(regval, &HCOR->usbcmd); + + /* Remove all active, attached qTD structures from the removed QH */ + + ret = imxrt_qtd_foreach(qh, imxrt_qtd_cancel, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Then release this QH by returning it to the free list. Return 1 + * to stop the traverse without an error. + */ + + imxrt_qh_free(qh); + return 1; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/**************************************************************************** + * Name: imxrt_ioc_bottomhalf + * + * Description: + * EHCI USB Interrupt (USBINT) "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to 1 on the completion of a USB + * transaction, which results in the retirement of a Transfer Descriptor + * that had its IOC bit set. + * + * "The Host Controller also sets this bit to 1 when a short packet is + * detected (actual number of bytes received was less than the expected + * number of bytes)." + * + * Assumptions: The caller holds the EHCI exclsem + * + ****************************************************************************/ + +static inline void imxrt_ioc_bottomhalf(void) +{ + struct imxrt_qh_s *qh; + uint32_t *bp; + int ret; + + /* Check the Asynchronous Queue + * Make sure that the head of the asynchronous queue is invalidated. + */ + + up_invalidate_dcache((uintptr_t)&g_asynchead.hw, + (uintptr_t)&g_asynchead.hw + + sizeof(struct ehci_qh_s)); + + /* Set the back pointer to the forward QH pointer of the asynchronous + * queue head. + */ + + bp = (uint32_t *)&g_asynchead.hw.hlp; + qh = (struct imxrt_qh_s *) + imxrt_virtramaddr(imxrt_swap32(*bp) & QH_HLP_MASK); + + /* If the asynchronous queue is empty, then the forward point in the + * asynchronous queue head will point back to the queue head. + */ + + if (qh && qh != &g_asynchead) + { + /* Then traverse and operate on every QH and qTD in the asynchronous + * queue + */ + + ret = imxrt_qh_foreach(qh, &bp, imxrt_qh_ioccheck, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QHFOREACH_FAILED, -ret); + } + } + +#ifndef CONFIG_USBHOST_INT_DISABLE + + /* Check the Interrupt Queue + * Make sure that the head of the interrupt queue is invalidated. + */ + + up_invalidate_dcache((uintptr_t)&g_intrhead.hw, + (uintptr_t)&g_intrhead.hw + sizeof(struct ehci_qh_s)); + + /* Set the back pointer to the forward qTD pointer of the asynchronous + * queue head. + */ + + bp = (uint32_t *)&g_intrhead.hw.hlp; + qh = (struct imxrt_qh_s *) + imxrt_virtramaddr(imxrt_swap32(*bp) & QH_HLP_MASK); + if (qh) + { + /* Then traverse and operate on every QH and qTD in the asynchronous + * queue. + */ + + ret = imxrt_qh_foreach(qh, &bp, imxrt_qh_ioccheck, NULL); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QHFOREACH_FAILED, -ret); + } + } +#endif +} + +/**************************************************************************** + * Name: imxrt_portsc_bottomhalf + * + * Description: + * EHCI Port Change Detect "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to a one when any port for which the + * Port Owner bit is set to zero ... has a change bit transition from a + * zero to a one or a Force Port Resume bit transition from a zero to a + * one as a result of a J-K transition detected on a suspended port. + * This bit will also be set as a result of the Connect Status Change + * being set to a one after system software has relinquished ownership of + * a connected port by writing a one to a port's Port Owner bit... + * + * "This bit is allowed to be maintained in the Auxiliary power well. + * Alternatively, it is also acceptable that on a D3 to D0 transition of + * the EHCI HC device, this bit is loaded with the OR of all of the PORTSC + * change bits (including: Force port resume, over-current change, + * enable/disable change and connect status change)." + * + ****************************************************************************/ + +static inline void imxrt_portsc_bottomhalf(void) +{ + struct imxrt_rhport_s *rhport; + struct usbhost_hubport_s *hport; + uint32_t portsc; + int rhpndx; + + /* Handle root hub status change on each root port */ + + for (rhpndx = 0; rhpndx < IMXRT_EHCI_NRHPORT; rhpndx++) + { + rhport = &g_ehci.rhport[rhpndx]; + portsc = imxrt_getreg(&HCOR->portsc[rhpndx]); + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC, rhpndx + 1, portsc); + + /* Handle port connection status change (CSC) events */ + + if ((portsc & EHCI_PORTSC_CSC) != 0) + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_CSC, portsc); + + /* Check current connect status */ + + if ((portsc & EHCI_PORTSC_CCS) != 0) + { + /* Connected ... Did we just become connected? */ + + if (!rhport->connected) + { + /* Yes.. connected. */ + + rhport->connected = true; + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC_CONNECTED, + rhpndx + 1, g_ehci.pscwait); + + /* Notify any waiters */ + + if (g_ehci.pscwait) + { + imxrt_givesem(&g_ehci.pscsem); + g_ehci.pscwait = false; + } + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_CONNALREADY, portsc); + } + } + else + { + /* Disconnected... Did we just become disconnected? */ + + if (rhport->connected) + { + /* Yes.. disconnect the device */ + + usbhost_vtrace2(EHCI_VTRACE2_PORTSC_DISCONND, + rhpndx + 1, g_ehci.pscwait); + + rhport->connected = false; + rhport->lowspeed = false; + + /* Are we bound to a class instance? */ + + hport = &rhport->hport.hport; + if (hport->devclass) + { + /* Yes.. Disconnect the class */ + + CLASS_DISCONNECTED(hport->devclass); + hport->devclass = NULL; + } + + /* Notify any waiters for the Root Hub Status change + * event. + */ + + if (g_ehci.pscwait) + { + imxrt_givesem(&g_ehci.pscsem); + g_ehci.pscwait = false; + } + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_PORTSC_DISCALREADY, portsc); + } + } + } + + /* Clear all pending port interrupt sources by writing a '1' to the + * corresponding bit in the PORTSC register. In addition, we need + * to preserve the values of all R/W bits (RO bits don't matter) + */ + + imxrt_putreg(portsc, &HCOR->portsc[rhpndx]); + } +} + +/**************************************************************************** + * Name: imxrt_syserr_bottomhalf + * + * Description: + * EHCI Host System Error "Bottom Half" interrupt handler + * + * "The Host Controller sets this bit to 1 when a serious error occurs + * during a host system access involving the Host Controller module. ... + * When this error occurs, the Host Controller clears the Run/Stop bit in + * the Command register to prevent further execution of the scheduled TDs." + * + ****************************************************************************/ + +static inline void imxrt_syserr_bottomhalf(void) +{ + usbhost_trace1(EHCI_TRACE1_SYSERR_INTR, 0); + DEBUGPANIC(); +} + +/**************************************************************************** + * Name: imxrt_async_advance_bottomhalf + * + * Description: + * EHCI Async Advance "Bottom Half" interrupt handler + * + * "System software can force the host controller to issue an interrupt the + * next time the host controller advances the asynchronous schedule by + * writing a one to the Interrupt on Async Advance Doorbell bit in the + * USBCMD register. This status bit indicates the assertion of that + * interrupt source." + * + ****************************************************************************/ + +static inline void imxrt_async_advance_bottomhalf(void) +{ + usbhost_vtrace1(EHCI_VTRACE1_AAINTR, 0); + + /* REVISIT: Could remove all tagged QH entries here */ +} + +/**************************************************************************** + * Name: imxrt_ehci_bottomhalf + * + * Description: + * EHCI "Bottom Half" interrupt handler. Runs on a work queue thread. + * + ****************************************************************************/ + +static void imxrt_ehci_bottomhalf(FAR void *arg) +{ + uint32_t pending = (uint32_t)arg; + + /* We need to have exclusive access to the EHCI data structures. Waiting + * here is not a good thing to do on the worker thread, but there is no + * real option (other than to reschedule and delay). + */ + + imxrt_takesem_noncancelable(&g_ehci.exclsem); + + /* Handle all unmasked interrupt sources + * USB Interrupt (USBINT) + * + * "The Host Controller sets this bit to 1 on the completion of a USB + * transaction, which results in the retirement of a Transfer Descriptor + * that had its IOC bit set. + * + * "The Host Controller also sets this bit to 1 when a short packet is + * detected (actual number of bytes received was less than the expected + * number of bytes)." + * + * USB Error Interrupt (USBERRINT) + * + * "The Host Controller sets this bit to 1 when completion of a USB + * transaction results in an error condition (e.g., error counter + * underflow). If the TD on which the error interrupt occurred also + * had its IOC bit set, both this bit and USBINT bit are set. ..." + * + * We do the same thing in either case: Traverse the asynchronous queue + * and remove all of the transfers that are no longer active. + */ + + if ((pending & (EHCI_INT_USBINT | EHCI_INT_USBERRINT)) != 0) + { + if ((pending & EHCI_INT_USBERRINT) != 0) + { + usbhost_trace1(EHCI_TRACE1_USBERR_INTR, pending); + } + else + { + usbhost_vtrace1(EHCI_VTRACE1_USBINTR, pending); + } + + imxrt_ioc_bottomhalf(); + } + + /* Port Change Detect + * + * "The Host Controller sets this bit to a one when any port for which + * the Port Owner bit is set to zero ... has a change bit transition + * from a zero to a one or a Force Port Resume bit transition from a zero + * to a one as a result of a J-K transition detected on a suspended port. + * This bit will also be set as a result of the Connect Status Change + * being set to a one after system software has relinquished ownership + * of a connected port by writing a one to a port's Port Owner bit... + * + * "This bit is allowed to be maintained in the Auxiliary power well. + * Alternatively, it is also acceptable that on a D3 to D0 transition + * of the EHCI HC device, this bit is loaded with the OR of all of the + * PORTSC change bits (including: Force port resume, over-current change, + * enable/disable change and connect status change)." + */ + + if ((pending & EHCI_INT_PORTSC) != 0) + { + imxrt_portsc_bottomhalf(); + } + + /* Frame List Rollover + * + * "The Host Controller sets this bit to a one when the Frame List Index + * ... rolls over from its maximum value to zero. The exact value at + * which the rollover occurs depends on the frame list size. For example, + * if the frame list size (as programmed in the Frame List Size field of + * the USBCMD register) is 1024, the Frame Index Register rolls over + * every time FRINDEX[13] toggles. Similarly, if the size is 512, the + * Host Controller sets this bit to a one every time FRINDEX[12] + * toggles." + */ + +#if 0 /* Not used */ + if ((pending & EHCI_INT_FLROLL) != 0) + { + imxrt_flroll_bottomhalf(); + } +#endif + + /* Host System Error + * + * "The Host Controller sets this bit to 1 when a serious error occurs + * during a host system access involving the Host Controller module. ... + * When this error occurs, the Host Controller clears the Run/Stop bit + * in the Command register to prevent further execution of the scheduled + * TDs." + */ + + if ((pending & EHCI_INT_SYSERROR) != 0) + { + uerr("Syserror\n"); + imxrt_syserr_bottomhalf(); + } + + /* Interrupt on Async Advance + * + * "System software can force the host controller to issue an interrupt + * the next time the host controller advances the asynchronous schedule + * by writing a one to the Interrupt on Async Advance Doorbell bit in + * the USBCMD register. This status bit indicates the assertion of that + * interrupt source." + */ + + if ((pending & EHCI_INT_AAINT) != 0) + { + uerr("Async Advance\n"); + imxrt_async_advance_bottomhalf(); + } + + /* We are done with the EHCI structures */ + + imxrt_givesem(&g_ehci.exclsem); + + /* Re-enable relevant EHCI interrupts. Interrupts should still be enabled + * at the level of the interrupt controller. + */ + + imxrt_putreg(EHCI_HANDLED_INTS, &HCOR->usbintr); +} + +/**************************************************************************** + * Name: imxrt_ehci_interrupt + * + * Description: + * EHCI "Top Half" interrupt handler + * + ****************************************************************************/ + +static int imxrt_ehci_interrupt(int irq, FAR void *context, FAR void *arg) +{ + uint32_t usbsts; + uint32_t pending; + uint32_t regval; + + /* Read Interrupt Status and mask out interrupts that are not enabled. */ + + usbsts = imxrt_getreg(&HCOR->usbsts); + regval = imxrt_getreg(&HCOR->usbintr); + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace1(EHCI_VTRACE1_TOPHALF, usbsts & regval); +#else + uinfo("USBSTS: %08x USBINTR: %08x\n", usbsts, regval); +#endif + + /* Handle all unmasked interrupt sources */ + + pending = usbsts & regval; + if (pending != 0) + { + /* Schedule interrupt handling work for the high priority worker + * thread so that we are not pressed for time and so that we can + * interrupt with other USB threads gracefully. + * + * The worker should be available now because we implement a handshake + * by controlling the EHCI interrupts. + */ + + DEBUGASSERT(work_available(&g_ehci.work)); + DEBUGVERIFY(work_queue(HPWORK, &g_ehci.work, imxrt_ehci_bottomhalf, + (FAR void *)pending, 0)); + + /* Disable further EHCI interrupts so that we do not overrun the work + * queue. + */ + + imxrt_putreg(0, &HCOR->usbintr); + + /* Clear all pending status bits by writing the value of the pending + * interrupt bits back to the status register. + */ + + imxrt_putreg(usbsts & EHCI_INT_ALLINTS, &HCOR->usbsts); + } + + return OK; +} + +/**************************************************************************** + * Name: imxrt_wait + * + * Description: + * Wait for a device to be connected or disconnected to/from a hub port. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from the + * call to the USB driver initialization logic. + * hport - The location to return the hub port descriptor that detected the + * connection related event. + * + * Returned Value: + * Zero (OK) is returned on success when a device is connected or + * disconnected. This function will not return until either (1) a device is + * connected or disconnect to/from any hub port or until (2) some failure + * occurs. On a failure, a negated errno value is returned indicating the + * nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int imxrt_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport) +{ + irqstate_t flags; + int rhpndx; + int ret; + + /* Loop until the connection state changes on one of the root hub ports or + * until an error occurs. + */ + + flags = enter_critical_section(); + for (; ; ) + { + /* Check for a change in the connection state on any root hub port */ + + for (rhpndx = 0; rhpndx < IMXRT_EHCI_NRHPORT; rhpndx++) + { + struct imxrt_rhport_s *rhport; + struct usbhost_hubport_s *connport; + + /* Has the connection state changed on the RH port? */ + + rhport = &g_ehci.rhport[rhpndx]; + connport = &rhport->hport.hport; + if (rhport->connected != connport->connected) + { + /* Yes.. Return the RH port to inform the caller which + * port has the connection change. + */ + + connport->connected = rhport->connected; + *hport = connport; + leave_critical_section(flags); + + usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP, + rhpndx + 1, rhport->connected); + return OK; + } + } + +#ifdef CONFIG_USBHOST_HUB + /* Is a device connected to an external hub? */ + + if (g_ehci.hport) + { + volatile struct usbhost_hubport_s *connport; + + /* Yes.. return the external hub port */ + + connport = g_ehci.hport; + g_ehci.hport = NULL; + + *hport = (struct usbhost_hubport_s *)connport; + leave_critical_section(flags); + + usbhost_vtrace2(EHCI_VTRACE2_MONWAKEUP, + connport->port + 1, connport->connected); + return OK; + } +#endif + + /* No changes on any port. Wait for a connection/disconnection event + * and check again + */ + + g_ehci.pscwait = true; + ret = imxrt_takesem(&g_ehci.pscsem); + if (ret < 0) + { + return ret; + } + } +} + +/**************************************************************************** + * Name: imxrt_enumerate + * + * Description: + * Enumerate the connected device. As part of this enumeration process, + * the driver will (1) get the device's configuration descriptor, (2) + * extract the class ID info from the configuration descriptor, (3) call + * usbhost_findclass() to find the class that supports this device, (4) + * call the create() method on the struct usbhost_registry_s interface + * to get a class instance, and finally (5) call the connect() method + * of the struct usbhost_class_s interface. After that, the class is in + * charge of the sequence of operations. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The descriptor of the hub port that has the newly connected + * device. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int imxrt_rh_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + struct imxrt_rhport_s *rhport; + volatile uint32_t *regaddr; + uint32_t regval; + int rhpndx; + + DEBUGASSERT(conn != NULL && hport != NULL); + rhpndx = hport->port; + + DEBUGASSERT(rhpndx >= 0 && rhpndx < IMXRT_EHCI_NRHPORT); + rhport = &g_ehci.rhport[rhpndx]; + + /* Are we connected to a device? The caller should have called the wait() + * method first to be assured that a device is connected. + */ + + while (!rhport->connected) + { + /* No, return an error */ + + usbhost_vtrace1(EHCI_VTRACE1_ENUM_DISCONN, 0); + return -ENODEV; + } + + /* USB 2.0 spec says at least 50ms delay before port reset. + * REVISIT: I think this is wrong. It needs to hold the port in + * reset for 50Msec, not wait 50Msec before resetting. + */ + + nxsig_usleep(100 * 1000); + + /* Paragraph 2.3.9: + * + * "Line Status ... These bits reflect the current logical levels of the + * D+ (bit 11) and D- (bit 10) signal lines. These bits are used for + * detection of low-speed USB devices prior to the port reset and enable + * sequence. This field is valid only when the port enable bit is zero + * and the current connect status bit is set to a one." + * + * Bits[11:10] USB State Interpretation + * ----------- --------- -------------- + * 00b SE0 Not Low-speed device, perform EHCI reset + * 10b J-state Not Low-speed device, perform EHCI reset + * 01b K-state Low-speed device, release ownership of port + * + * NOTE: Low-speed devices could be detected by examining the PORTSC PSPD + * field after resetting the device. The more conventional way here, + * however, also appears to work. + */ + + regval = imxrt_getreg(&HCOR->portsc[rhpndx]); + if ((regval & EHCI_PORTSC_LSTATUS_MASK) == EHCI_PORTSC_LSTATUS_KSTATE) + { + /* EHCI Paragraph 2.3.9: + * + * "Port Owner ... This bit unconditionally goes to a 0b when the + * Configured bit in the CONFIGFLAG register makes a 0b to 1b + * transition. This bit unconditionally goes to 1b whenever the + * Configured bit is zero. + * + * "System software uses this field to release ownership of the + * port to a selected host controller (in the event that the + * attached device is not a high-speed device). Software writes + * a one to this bit when the attached device is not a high-speed + * device. A one in this bit means that a companion host + * controller owns and controls the port. .... + * + * EHCI Paragraph 4.2: + * + * "When a port is routed to a companion HC, it remains under the + * control of the companion HC until the device is disconnected + * from the root por ... When a disconnect occurs, the disconnect + * event is detected by both the companion HC port control and the + * EHCI port ownership control. On the event, the port ownership + * is returned immediately to the EHCI controller. The companion + * HC stack detects the disconnect and acknowledges as it would + * in an ordinary standalone implementation. Subsequent connects + * will be detected by the EHCI port register and the process will + * repeat." + */ + + hport->speed = USB_SPEED_LOW; + } + else + { + /* Assume full-speed for now */ + + hport->speed = USB_SPEED_FULL; + } + + /* Put the root hub port in reset. + * + * EHCI Paragraph 2.3.9: + * + * "The HCHalted bit in the USBSTS register should be a zero before + * software attempts to use [the Port Reset] bit. The host controller + * may hold Port Reset asserted to a one when the HCHalted bit is a one. + */ + + DEBUGASSERT((imxrt_getreg(&HCOR->usbsts) & EHCI_USBSTS_HALTED) == 0); + + /* EHCI paragraph 2.3.9: + * + * "When software writes a one to [the Port Reset] bit (from a zero), the + * bus reset sequence as defined in the USB Specification Revision 2.0 + * is started. Software writes a zero to this bit to terminate the bus + * reset sequence. Software must keep this bit at a one long enough to + * ensure the reset sequence, as specified in the USB Specification + * Revision 2.0, completes. Note: when software writes this bit to a + * one, it must also write a zero to the Port Enable bit." + */ + + regaddr = &HCOR->portsc[RHPNDX(rhport)]; + regval = imxrt_getreg(regaddr); + regval &= ~EHCI_PORTSC_PE; + regval |= EHCI_PORTSC_RESET; + imxrt_putreg(regval, regaddr); + + /* USB 2.0 "Root hubs must provide an aggregate reset period of at least + * 50 ms." + */ + + nxsig_usleep(50 * 1000); + + regval = imxrt_getreg(regaddr); + regval &= ~EHCI_PORTSC_RESET; + imxrt_putreg(regval, regaddr); + + /* Wait for the port reset to complete + * + * EHCI Paragraph 2.3.9: + * + * "Note that when software writes a zero to this bit there may be a + * delay before the bit status changes to a zero. The bit status will + * not read as a zero until after the reset has completed. If the port + * is in high-speed mode after reset is complete, the host controller + * will automatically enable this port (e.g. set the Port Enable bit + * to a one). A host controller must terminate the reset and stabilize + * the state of the port within 2 milliseconds of software transitioning + * this bit from a one to a zero ..." + */ + + while ((imxrt_getreg(regaddr) & EHCI_PORTSC_RESET) != 0); + nxsig_usleep(200 * 1000); + + /* EHCI Paragraph 4.2.2: + * + * "... The reset process is actually complete when software reads a zero + * in the PortReset bit. The EHCI Driver checks the PortEnable bit in + * the PORTSC register. If set to a one, the connected device is a high- + * speed device and EHCI Driver (root hub emulator) issues a change + * report to the hub driver and the hub driver continues to enumerate + * the attached device." + * + * "At the time the EHCI Driver receives the port reset and enable request + * the LineStatus bits might indicate a low-speed device. Additionally, + * when the port reset process is complete, the PortEnable field may + * indicate that a full-speed device is attached. In either case the EHCI + * driver sets the PortOwner bit in the PORTSC register to a one to + * release port ownership to a companion host controller." + * + * LPC31xx User Manual Paragraph 6.1.3: + * + * "In a standard EHCI controller design, the EHCI host controller driver + * detects a Full speed (FS) or Low speed (LS) device by noting if the + * port enable bit is set after the port reset operation. The port enable + * will only be set in a standard EHCI controller implementation after + * the port reset operation and when the host and device negotiate a + * High-Speed connection (i.e. Chirp completes successfully). Since this + * controller has an embedded Transaction Translator, the port enable + * will always be set after the port reset operation regardless of the + * result of the host device chirp result and the resulting port speed + * will be indicated by the PSPD field in PORTSC1. + */ + + regval = imxrt_getreg(&HCOR->portsc[rhpndx]); + + if ((regval & USBDEV_PRTSC1_PSPD_MASK) == USBDEV_PRTSC1_PSPD_HS) + { + /* High speed device */ + + hport->speed = USB_SPEED_HIGH; + } + else if ((regval & USBDEV_PRTSC1_PSPD_MASK) == USBDEV_PRTSC1_PSPD_FS) + { + /* Low- or Full- speed device. Set the port ownership bit. + * + * EHCI Paragraph 4.2: + * + * "When a port is routed to a companion HC, it remains under the + * control of the companion HC until the device is disconnected + * from the root por ... When a disconnect occurs, the disconnect + * event is detected by both the companion HC port control and the + * EHCI port ownership control. On the event, the port ownership + * is returned immediately to the EHCI controller. The companion + * HC stack detects the disconnect and acknowledges as it would + * in an ordinary standalone implementation. Subsequent connects + * will be detected by the EHCI port register and the process will + * repeat." + */ + + DEBUGASSERT(hport->speed == USB_SPEED_FULL); + } + + /* Otherwise it must be a low speed device */ + + else + { + DEBUGASSERT(hport->speed == USB_SPEED_LOW); + DEBUGASSERT((regval & USBDEV_PRTSC1_PSPD_MASK) == + USBDEV_PRTSC1_PSPD_LS); + } + + return OK; +} + +static int imxrt_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + int ret; + + /* If this is a connection on the root hub, then we need to go to + * little more effort to get the device speed. If it is a connection + * on an external hub, then we already have that information. + */ + + DEBUGASSERT(hport); +#ifdef CONFIG_USBHOST_HUB + if (ROOTHUB(hport)) +#endif + { + ret = imxrt_rh_enumerate(conn, hport); + if (ret < 0) + { + return ret; + } + } + + /* Then let the common usbhost_enumerate do the real enumeration. */ + + usbhost_vtrace1(EHCI_VTRACE1_CLASSENUM, hport->port); + ret = usbhost_enumerate(hport, &hport->devclass); + if (ret < 0) + { + /* Failed to enumerate */ + + usbhost_trace2(EHCI_TRACE2_CLASSENUM_FAILED, hport->port + 1, -ret); + + /* If this is a root hub port, then marking the hub port not connected + * will cause imxrt_wait() to return and we will try the connection + * again. + */ + + hport->connected = false; + } + + return ret; +} + +/**************************************************************************** + * Name: imxrt_ep0configure + * + * Description: + * Configure endpoint 0. This method is normally used internally by the + * enumerate() method but is made available at the interface to support + * an external implementation of the enumeration logic. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * funcaddr - The USB address of the function containing the endpoint that + * EP0 controls. A funcaddr of zero will be received if no address is + * yet assigned to the device. + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH + * maxpacketsize - The maximum number of bytes that can be sent to or + * received from the endpoint in a single data packet + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int imxrt_ep0configure(FAR struct usbhost_driver_s *drvr, + usbhost_ep_t ep0, uint8_t funcaddr, + uint8_t speed, uint16_t maxpacketsize) +{ + struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)ep0; + int ret; + + DEBUGASSERT(drvr != NULL && epinfo != NULL && maxpacketsize < 2048); + + /* We must have exclusive access to the EHCI data structures. */ + + ret = imxrt_takesem(&g_ehci.exclsem); + if (ret >= 0) + { + /* Remember the new device address and max packet size */ + + epinfo->devaddr = funcaddr; + epinfo->speed = speed; + epinfo->maxpacket = maxpacketsize; + + imxrt_givesem(&g_ehci.exclsem); + } + + return ret; +} + +/**************************************************************************** + * Name: imxrt_epalloc + * + * Description: + * Allocate and configure one endpoint. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure. + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int imxrt_epalloc(FAR struct usbhost_driver_s *drvr, + const FAR struct usbhost_epdesc_s *epdesc, + usbhost_ep_t *ep) +{ + struct imxrt_epinfo_s *epinfo; + struct usbhost_hubport_s *hport; + + /* Sanity check. NOTE that this method should only be called if a device + * is connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(drvr != 0 && epdesc != NULL && epdesc->hport != NULL && + ep != NULL); + hport = epdesc->hport; + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_EPALLOC, epdesc->addr, epdesc->xfrtype); +#else + uinfo("EP%d DIR=%s FA=%08x TYPE=%d Interval=%d MaxPacket=%d\n", + epdesc->addr, epdesc->in ? "IN" : "OUT", hport->funcaddr, + epdesc->xfrtype, epdesc->interval, epdesc->mxpacketsize); +#endif + + /* Allocate a endpoint information structure */ + + epinfo = (struct imxrt_epinfo_s *) + kmm_zalloc(sizeof(struct imxrt_epinfo_s)); + if (!epinfo) + { + usbhost_trace1(EHCI_TRACE1_EPALLOC_FAILED, 0); + return -ENOMEM; + } + + /* Initialize the endpoint container (which is really just another form of + * 'struct usbhost_epdesc_s', packed differently and with additional + * information. A cleaner design might just embed struct usbhost_epdesc_s + * inside of struct imxrt_epinfo_s and just memcpy() here. + */ + + epinfo->epno = epdesc->addr; + epinfo->dirin = epdesc->in; + epinfo->devaddr = hport->funcaddr; +#ifndef CONFIG_USBHOST_INT_DISABLE + epinfo->interval = epdesc->interval; +#endif + epinfo->maxpacket = epdesc->mxpacketsize; + epinfo->xfrtype = epdesc->xfrtype; + epinfo->speed = hport->speed; + + /* The iocsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + nxsem_init(&epinfo->iocsem, 0, 0); + nxsem_set_protocol(&epinfo->iocsem, SEM_PRIO_NONE); + + /* Success.. return an opaque reference to the endpoint information + * structure instance + */ + + *ep = (usbhost_ep_t)epinfo; + return OK; +} + +/**************************************************************************** + * Name: imxrt_epfree + * + * Description: + * Free and endpoint previously allocated by DRVR_EPALLOC. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * ep - The endpint to be freed. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int imxrt_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)ep; + + /* There should not be any pending, transfers */ + + DEBUGASSERT(drvr && epinfo && epinfo->iocwait == 0); + + /* Free the container */ + + kmm_free(epinfo); + return OK; +} + +/**************************************************************************** + * Name: imxrt_alloc + * + * Description: + * Some hardware supports special memory in which request and descriptor + * data can be accessed more efficiently. This method provides a + * mechanism to allocate the request/descriptor memory. If the underlying + * hardware does not support such "special" memory, this functions may + * simply map to kmm_malloc(). + * + * This interface was optimized under a particular assumption. It was + * assumed that the driver maintains a pool of small, pre-allocated buffers + * for descriptor traffic. NOTE that size is not an input, but an output: + * The size of the pre-allocated buffer is returned. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * buffer - The address of a memory location provided by the caller in + * which to return the allocated buffer memory address. + * maxlen - The address of a memory location provided by the caller in + * which to return the maximum size of the allocated buffer memory. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int imxrt_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen) +{ + int ret = -ENOMEM; + DEBUGASSERT(drvr && buffer && maxlen); + + /* The only special requirements for transfer/descriptor buffers are that + * (1) they be aligned to a cache line boundary and (2) they are a + * multiple of the cache line size in length. + */ + + *buffer = (FAR uint8_t *)kmm_memalign(ARMV7M_DCACHE_LINESIZE, + IMXRT_EHCI_BUFSIZE); + if (*buffer) + { + *maxlen = IMXRT_EHCI_BUFSIZE; + ret = OK; + } + + return ret; +} + +/**************************************************************************** + * Name: imxrt_free + * + * Description: + * Some hardware supports special memory in which request and descriptor + * data can be accessed more efficiently. This method provides a + * mechanism to free that request/descriptor memory. If the underlying + * hardware does not support such "special" memory, this functions may + * simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + * Assumptions: + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int imxrt_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + DEBUGASSERT(drvr && buffer); + + /* No special action is require to free the transfer/descriptor buffer + * memory + */ + + kmm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: imxrt_ioalloc + * + * Description: + * Some hardware supports special memory in which larger IO buffers can + * be accessed more efficiently. This method provides a mechanism to + * allocate the request/descriptor memory. If the underlying hardware + * does not support such "special" memory, this functions may simply map + * to kumm_malloc. + * + * This interface differs from DRVR_ALLOC in that the buffers are variable- + * sized. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * buffer - The address of a memory location provided by the caller in + * which to return the allocated buffer memory address. + * buflen - The size of the buffer required. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int imxrt_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen) +{ + DEBUGASSERT(drvr && buffer && buflen > 0); + + /* The only special requirements for I/O buffers are that (1) they be + * aligned to a cache line boundary, (2) they are a multiple of the cache + * line size in length, and (3) they might need to be user accessible + * (depending on how the class driver implements its buffering). + */ + + buflen = (buflen + DCACHE_LINEMASK) & ~DCACHE_LINEMASK; + *buffer = (FAR uint8_t *)kumm_memalign(ARMV7M_DCACHE_LINESIZE, buflen); + return *buffer ? OK : -ENOMEM; +} + +/**************************************************************************** + * Name: imxrt_iofree + * + * Description: + * Some hardware supports special memory in which IO data can be accessed + * more efficiently. This method provides a mechanism to free that IO + * buffer memory. If the underlying hardware does not support such + * "special" memory, this functions may simply map to kumm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int imxrt_iofree(FAR struct usbhost_driver_s *drvr, + FAR uint8_t *buffer) +{ + DEBUGASSERT(drvr && buffer); + + /* No special action is require to free the I/O buffer memory */ + + kumm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: imxrt_ctrlin and imxrt_ctrlout + * + * Description: + * Process a IN or OUT request on the control endpoint. These methods + * will enqueue the request and wait for it to complete. Only one + * transfer may be queued; Neither these methods nor the transfer() method + * can be called again until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * ep0 - The control endpoint to send/receive the control request. + * req - Describes the request to be sent. This request must lie in + * memory created by DRVR_ALLOC. + * buffer - A buffer used for sending the request and for returning any + * responses. This buffer must be large enough to hold the + * length value in the request description. buffer must have been + * allocated using DRVR_ALLOC. + * + * NOTE: On an IN transaction, req and buffer may refer to the same + * allocated memory. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int imxrt_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer) +{ + struct imxrt_rhport_s *rhport = (struct imxrt_rhport_s *)drvr; + struct imxrt_epinfo_s *ep0info = (struct imxrt_epinfo_s *)ep0; + uint16_t len; + ssize_t nbytes; + int ret; + + DEBUGASSERT(rhport != NULL && ep0info != NULL && req != NULL); + + len = imxrt_read16(req->len); + + /* Terse output only if we are tracing */ + +#ifdef CONFIG_USBHOST_TRACE + usbhost_vtrace2(EHCI_VTRACE2_CTRLINOUT, RHPORT(rhport), req->req); +#else + uinfo("RHPort%d type: %02x req: %02x value: %02x%02x index: %02x%02x " + "len: %04x\n", + RHPORT(rhport), req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], len); +#endif + + /* We must have exclusive access to the EHCI hardware and data + * structures. + */ + + ret = imxrt_takesem(&g_ehci.exclsem); + if (ret < 0) + { + return ret; + } + + /* Set the request for the IOC event well BEFORE initiating the transfer. */ + + ret = imxrt_ioc_setup(rhport, ep0info); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Now initiate the transfer */ + + ret = imxrt_async_setup(rhport, ep0info, req, buffer, len); + if (ret < 0) + { + uerr("ERROR: imxrt_async_setup failed: %d\n", ret); + goto errout_with_iocwait; + } + + /* And wait for the transfer to complete */ + + nbytes = imxrt_transfer_wait(ep0info); + imxrt_givesem(&g_ehci.exclsem); + return nbytes >= 0 ? OK : (int)nbytes; + +errout_with_iocwait: + ep0info->iocwait = false; +errout_with_sem: + imxrt_givesem(&g_ehci.exclsem); + return ret; +} + +static int imxrt_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer) +{ + /* imxrt_ctrlin can handle both directions. We just need to work around + * the differences in the function signatures. + */ + + return imxrt_ctrlin(drvr, ep0, req, (uint8_t *)buffer); +} + +/**************************************************************************** + * Name: imxrt_transfer + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request, blocking until the transfer completes. + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until this function returns. + * + * This is a blocking method; this functions will not return until the + * transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on + * which to perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or + * received (IN endpoint). buffer must have been allocated using + * DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Value: + * On success, a non-negative value is returned that indicates the number + * of bytes successfully transferred. On a failure, a negated errno value + * is returned that indicates the nature of the failure: + * + * EAGAIN - If devices NAKs the transfer (or NYET or other error where + * it may be appropriate to restart the entire transaction). + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Overrun errors + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static ssize_t imxrt_transfer(FAR struct usbhost_driver_s *drvr, + usbhost_ep_t ep, FAR uint8_t *buffer, + size_t buflen) +{ + struct imxrt_rhport_s *rhport = (struct imxrt_rhport_s *)drvr; + struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)ep; + ssize_t nbytes; + int ret; + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* We must have exclusive access to the EHCI hardware and data + * structures. + */ + + ret = imxrt_takesem(&g_ehci.exclsem); + if (ret < 0) + { + return (ssize_t)ret; + } + + /* Set the request for the IOC event well BEFORE initiating the + * transfer. + */ + + ret = imxrt_ioc_setup(rhport, epinfo); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Initiate the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_BULK: + ret = imxrt_async_setup(rhport, epinfo, NULL, buffer, buflen); + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + ret = imxrt_intr_setup(rhport, epinfo, buffer, buflen); + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + case USB_EP_ATTR_XFER_CONTROL: + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + break; + } + + /* Check for errors in the setup of the transfer */ + + if (ret < 0) + { + goto errout_with_iocwait; + } + + /* Then wait for the transfer to complete */ + + nbytes = imxrt_transfer_wait(epinfo); + imxrt_givesem(&g_ehci.exclsem); + return nbytes; + +errout_with_iocwait: + epinfo->iocwait = false; +errout_with_sem: + uerr("!!!\n"); + imxrt_givesem(&g_ehci.exclsem); + return (ssize_t)ret; +} + +/**************************************************************************** + * Name: imxrt_asynch + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately. When the transfer + * completes, the callback will be invoked with the provided transfer. + * This method is useful for receiving interrupt transfers which may come + * infrequently. + * + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until the transfer completes. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from + * the call to the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on + * which to perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or + * received (IN endpoint). buffer must have been allocated + * using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * callback - This function will be called when the transfer completes. + * arg - The arbitrary parameter that will be passed to the callback + * function when the transfer completes. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int imxrt_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + struct imxrt_rhport_s *rhport = (struct imxrt_rhport_s *)drvr; + struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)ep; + int ret; + + DEBUGASSERT(rhport && epinfo && buffer && buflen > 0); + + /* We must have exclusive access to the EHCI hardware and data + * structures. + */ + + ret = imxrt_takesem(&g_ehci.exclsem); + if (ret < 0) + { + return ret; + } + + /* Set the request for the callback well BEFORE initiating the transfer. */ + + ret = imxrt_ioc_async_setup(rhport, epinfo, callback, arg); + if (ret != OK) + { + usbhost_trace1(EHCI_TRACE1_DEVDISCONNECTED, -ret); + goto errout_with_sem; + } + + /* Initiate the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_BULK: + ret = imxrt_async_setup(rhport, epinfo, NULL, buffer, buflen); + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + ret = imxrt_intr_setup(rhport, epinfo, buffer, buflen); + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + case USB_EP_ATTR_XFER_CONTROL: + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + break; + } + + /* Check for errors in the setup of the transfer */ + + if (ret < 0) + { + goto errout_with_callback; + } + + /* The transfer is in progress */ + + imxrt_givesem(&g_ehci.exclsem); + return OK; + +errout_with_callback: + epinfo->callback = NULL; + epinfo->arg = NULL; +errout_with_sem: + imxrt_givesem(&g_ehci.exclsem); + return ret; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/**************************************************************************** + * Name: imxrt_cancel + * + * Description: + * Cancel a pending transfer on an endpoint. Canceled synchronous or + * asynchronous transfer will complete normally with the error -ESHUTDOWN. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on + * which an asynchronous transfer should be transferred. + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + ****************************************************************************/ + +static int imxrt_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + struct imxrt_epinfo_s *epinfo = (struct imxrt_epinfo_s *)ep; + struct imxrt_qh_s *qh; +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; + void *arg; +#endif + uint32_t *bp; + irqstate_t flags; + bool iocwait; + int ret; + + DEBUGASSERT(epinfo); + + /* We must have exclusive access to the EHCI hardware and data structures. + * This will prevent servicing any transfer completion events while we + * perform the the cancellation, but will not prevent DMA-related race + * conditions. + * + * REVISIT: This won't work. This function must be callable from the + * interrupt level. + */ + + ret = imxrt_takesem(&g_ehci.exclsem); + if (ret < 0) + { + return ret; + } + + /* Sample and reset all transfer termination information. This will + * prevent any callbacks from occurring while are performing the + * cancellation. The transfer may still be in progress, however, so this + * does not eliminate other DMA-related race conditions. + */ + + flags = enter_critical_section(); +#ifdef CONFIG_USBHOST_ASYNCH + callback = epinfo->callback; + arg = epinfo->arg; +#endif + iocwait = epinfo->iocwait; + +#ifdef CONFIG_USBHOST_ASYNCH + epinfo->callback = NULL; + epinfo->arg = NULL; +#endif + epinfo->iocwait = false; + + /* This will prevent any callbacks from occurring while are performing + * the cancellation. The transfer may still be in progress, however, so + * this does not eliminate other DMA-related race conditions. + */ + + epinfo->callback = NULL; + epinfo->arg = NULL; + leave_critical_section(flags); + + /* Bail if there is no transfer in progress for this endpoint */ + +#ifdef CONFIG_USBHOST_ASYNCH + if (callback == NULL && !iocwait) +#else + if (!iocwait) +#endif + { + ret = OK; + goto errout_with_sem; + } + + /* Handle the cancellation according to the type of the transfer */ + + switch (epinfo->xfrtype) + { + case USB_EP_ATTR_XFER_CONTROL: + case USB_EP_ATTR_XFER_BULK: + { + /* Get the horizontal pointer from the head of the asynchronous + * queue. + */ + + bp = (uint32_t *)&g_asynchead.hw.hlp; + qh = (struct imxrt_qh_s *) + imxrt_virtramaddr(imxrt_swap32(*bp) & QH_HLP_MASK); + + /* If the asynchronous queue is empty, then the forward point in + * the asynchronous queue head will point back to the queue + * head. + */ + + if (qh && qh != &g_asynchead) + { + /* Claim that we successfully cancelled the transfer */ + + ret = OK; + goto exit_terminate; + } + } + break; + +#ifndef CONFIG_USBHOST_INT_DISABLE + case USB_EP_ATTR_XFER_INT: + { + /* Get the horizontal pointer from the head of the interrupt + * queue. + */ + + bp = (uint32_t *)&g_intrhead.hw.hlp; + qh = (struct imxrt_qh_s *) + imxrt_virtramaddr(imxrt_swap32(*bp) & QH_HLP_MASK); + if (qh) + { + /* if the queue is empty, then just claim that we successfully + * canceled the transfer. + */ + + ret = OK; + goto exit_terminate; + } + } + break; +#endif + +#ifndef CONFIG_USBHOST_ISOC_DISABLE + case USB_EP_ATTR_XFER_ISOC: +# warning "Isochronous endpoint support not emplemented" +#endif + default: + usbhost_trace1(EHCI_TRACE1_BADXFRTYPE, epinfo->xfrtype); + ret = -ENOSYS; + goto errout_with_sem; + } + + /* Find and remove the QH. There are four possibilities: + * + * 1) The transfer has already completed and the QH is no longer in the + * list. In this case, sam_hq_foreach will return zero + * 2a) The transfer is not active and still pending. It was removed from + * the list and sam_hq_foreach will return one. + * 2b) The is active but not yet complete. This is currently handled the + * same as 2a). REVISIT: This needs to be fixed. + * 3) Some bad happened and sam_hq_foreach returned an error code < 0. + */ + + ret = imxrt_qh_foreach(qh, &bp, imxrt_qh_cancel, epinfo); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_QTDFOREACH_FAILED, -ret); + } + + /* Was there a pending synchronous transfer? */ + +exit_terminate: + epinfo->result = -ESHUTDOWN; +#ifdef CONFIG_USBHOST_ASYNCH + if (iocwait) + { + /* Yes... wake it up */ + + DEBUGASSERT(callback == NULL); + imxrt_givesem(&epinfo->iocsem); + } + + /* No.. Is there a pending asynchronous transfer? */ + + else /* if (callback != NULL) */ + { + /* Yes.. perform the callback */ + + callback(arg, -ESHUTDOWN); + } + +#else + /* Wake up the waiting thread */ + + imxrt_givesem(&epinfo->iocsem); +#endif + +errout_with_sem: + imxrt_givesem(&g_ehci.exclsem); + return ret; +} + +/**************************************************************************** + * Name: imxrt_connect + * + * Description: + * New connections may be detected by an attached hub. This method is the + * mechanism that is used by the hub class to introduce a new connection + * and port description to the system. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * hport - The descriptor of the hub port that detected the connection + * related event + * connected - True: device connected; false: device disconnected + * + * Returned Value: + * On success, zero (OK) is returned. On a failure, a negated errno value + * is returned indicating the nature of the failure + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +static int imxrt_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected) +{ + irqstate_t flags; + + /* Set the connected/disconnected flag */ + + hport->connected = connected; + uinfo("Hub port %d connected: %s\n", + hport->port, connected ? "YES" : "NO"); + + /* Report the connection event */ + + flags = enter_critical_section(); + DEBUGASSERT(g_ehci.hport == NULL); /* REVISIT */ + + g_ehci.hport = hport; + if (g_ehci.pscwait) + { + g_ehci.pscwait = false; + imxrt_givesem(&g_ehci.pscsem); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: imxrt_disconnect + * + * Description: + * Called by the class when an error occurs and driver has been + * disconnected. The USB host driver should discard the handle to the + * class instance (it is stale) and not attempt any further interaction + * with the class driver instance (until a new instance is received from + * the create() method). The driver should not called the class' + * disconnected() method. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the + * call to the class create() method. + * hport - The port from which the device is being disconnected. Might be + * a port on a hub. + * + * Returned Value: + * None + * + * Assumptions: + * - Only a single class bound to a single device is supported. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void imxrt_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) +{ + DEBUGASSERT(hport != NULL); + hport->devclass = NULL; +} + +/**************************************************************************** + * Name: imxrt_reset + * + * Description: + * Set the HCRESET bit in the USBCMD register to reset the EHCI hardware. + * + * Table 2-9. USBCMD - USB Command Register Bit Definitions + * + * "Host Controller Reset (HCRESET) ... This control bit is used by + * software to reset the host controller. The effects of this on Root + * Hub registers are similar to a Chip Hardware Reset. + * + * "When software writes a one to this bit, the Host Controller resets its + * internal pipelines, timers, counters, state machines, etc. to their + * initial value. Any transaction currently in progress on USB is + * immediately terminated. A USB reset is not driven on downstream + * ports. + * + * "PCI Configuration registers are not affected by this reset. All + * operational registers, including port registers and port state + * machines are set to their initial values. Port ownership reverts + * to the companion host controller(s)... Software must reinitialize + * the host controller ... in order to return the host controller to + * an operational state. + * + * "This bit is set to zero by the Host Controller when the reset process + * is complete. Software cannot terminate the reset process early by + * writing a zero to this register. Software should not set this bit to + * a one when the HCHalted bit in the USBSTS register is a zero. + * Attempting to reset an actively running host controller will result + * in undefined behavior." + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * on failure. + * + * Assumptions: + * - Called during the initialization of the EHCI. + * + ****************************************************************************/ + +static int imxrt_reset(void) +{ + uint32_t regval; + unsigned int timeout; + + /* Make sure that the EHCI is halted: "When [the Run/Stop] bit is set to + * 0, the Host Controller completes the current transaction on the USB and + * then halts. The HC Halted bit in the status register indicates when the + * Host Controller has finished the transaction and has entered the + * stopped state..." + */ + + imxrt_putreg(0, &HCOR->usbcmd); + + /* "... Software should not set [HCRESET] to a one when the HCHalted bit in + * the USBSTS register is a zero. Attempting to reset an actively running + * host controller will result in undefined behavior." + */ + + timeout = 0; + do + { + /* Wait one microsecond and update the timeout counter */ + + up_udelay(1); + timeout++; + + /* Get the current value of the USBSTS register. This loop will + * terminate when either the timeout exceeds one millisecond or when + * the HCHalted bit is no longer set in the USBSTS register. + */ + + regval = imxrt_getreg(&HCOR->usbsts); + } + while (((regval & EHCI_USBSTS_HALTED) == 0) && (timeout < 1000)); + + /* Is the EHCI still running? Did we timeout? */ + + if ((regval & EHCI_USBSTS_HALTED) == 0) + { + usbhost_trace1(EHCI_TRACE1_HCHALTED_TIMEOUT, regval); + return -ETIMEDOUT; + } + + /* Now we can set the HCReset bit in the USBCMD register to initiate the + * reset + */ + + regval = imxrt_getreg(&HCOR->usbcmd); + regval |= EHCI_USBCMD_HCRESET; + imxrt_putreg(regval, &HCOR->usbcmd); + + /* Wait for the HCReset bit to become clear */ + + do + { + /* Wait five microsecondw and update the timeout counter */ + + up_udelay(5); + timeout += 5; + + /* Get the current value of the USBCMD register. This loop will + * terminate when either the timeout exceeds one second or when the + * HCReset bit is no longer set in the USBSTS register. + */ + + regval = imxrt_getreg(&HCOR->usbcmd); + } + while (((regval & EHCI_USBCMD_HCRESET) != 0) && (timeout < 1000000)); + + /* Return either success or a timeout */ + + return (regval & EHCI_USBCMD_HCRESET) != 0 ? -ETIMEDOUT : OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_ehci_initialize + * + * Description: + * Initialize USB EHCI host controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than one EHCI interface, then + * this identifies which controller is being initialized. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +FAR struct usbhost_connection_s *imxrt_ehci_initialize(int controller) +{ + FAR struct usbhost_hubport_s *hport; + uint32_t regval; +# if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_INFO) + uint16_t regval16; + unsigned int nports; +# endif + uintptr_t physaddr; + int ret; + int i; + + /* Sanity checks */ + + DEBUGASSERT(controller == 0); + DEBUGASSERT(((uintptr_t) & g_asynchead & 0x1f) == 0); + DEBUGASSERT((sizeof(struct imxrt_qh_s) & 0x1f) == 0); + DEBUGASSERT((sizeof(struct imxrt_qtd_s) & 0x1f) == 0); + +# ifdef CONFIG_IMXRT_EHCI_PREALLOCATE + DEBUGASSERT(((uintptr_t) & g_qhpool & 0x1f) == 0); + DEBUGASSERT(((uintptr_t) & g_qtdpool & 0x1f) == 0); +# endif + +# ifndef CONFIG_USBHOST_INT_DISABLE + DEBUGASSERT(((uintptr_t) & g_intrhead & 0x1f) == 0); +# ifdef CONFIG_IMXRT_EHCI_PREALLOCATE + DEBUGASSERT(((uintptr_t) g_framelist & 0xfff) == 0); +# endif +# endif /* CONFIG_USBHOST_INT_DISABLE */ + + /* Software Configuration *************************************************/ + + usbhost_vtrace1(EHCI_VTRACE1_INITIALIZING, 0); + + /* Initialize the EHCI state data structure */ + + nxsem_init(&g_ehci.exclsem, 0, 1); + nxsem_init(&g_ehci.pscsem, 0, 0); + + /* The pscsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + nxsem_set_protocol(&g_ehci.pscsem, SEM_PRIO_NONE); + + /* Initialize EP0 */ + + nxsem_init(&g_ehci.ep0.iocsem, 0, 1); + + /* Initialize the root hub port structures */ + + for (i = 0; i < IMXRT_EHCI_NRHPORT; i++) + { + struct imxrt_rhport_s *rhport = &g_ehci.rhport[i]; + + /* Initialize the device operations */ + + rhport->drvr.ep0configure = imxrt_ep0configure; + rhport->drvr.epalloc = imxrt_epalloc; + rhport->drvr.epfree = imxrt_epfree; + rhport->drvr.alloc = imxrt_alloc; + rhport->drvr.free = imxrt_free; + rhport->drvr.ioalloc = imxrt_ioalloc; + rhport->drvr.iofree = imxrt_iofree; + rhport->drvr.ctrlin = imxrt_ctrlin; + rhport->drvr.ctrlout = imxrt_ctrlout; + rhport->drvr.transfer = imxrt_transfer; +# ifdef CONFIG_USBHOST_ASYNCH + rhport->drvr.asynch = imxrt_asynch; +# endif + rhport->drvr.cancel = imxrt_cancel; +# ifdef CONFIG_USBHOST_HUB + rhport->drvr.connect = imxrt_connect; +# endif + rhport->drvr.disconnect = imxrt_disconnect; + + /* Initialize EP0 */ + + rhport->ep0.xfrtype = USB_EP_ATTR_XFER_CONTROL; + rhport->ep0.speed = USB_SPEED_FULL; + rhport->ep0.maxpacket = 8; + + /* The EP0 iocsem semaphore is used for signaling and, hence, should + * not have priority inheritance enabled. + */ + + nxsem_init(&rhport->ep0.iocsem, 0, 0); + nxsem_set_protocol(&rhport->ep0.iocsem, SEM_PRIO_NONE); + + /* Initialize the public port representation */ + + hport = &rhport->hport.hport; + hport->drvr = &rhport->drvr; +# ifdef CONFIG_USBHOST_HUB + hport->parent = NULL; +# endif + hport->ep0 = &rhport->ep0; + hport->port = i; + hport->speed = USB_SPEED_FULL; + + /* Initialize function address generation logic */ + + usbhost_devaddr_initialize(&rhport->hport); + } + +# ifndef CONFIG_IMXRT_EHCI_PREALLOCATE + /* Allocate a pool of free Queue Head (QH) structures */ + + g_qhpool = + (struct imxrt_qh_s *)kmm_memalign(32, + CONFIG_IMXRT_EHCI_NQHS * + sizeof(struct imxrt_qh_s)); + if (!g_qhpool) + { + usbhost_trace1(EHCI_TRACE1_QHPOOLALLOC_FAILED, 0); + return NULL; + } +# endif + + /* Initialize the list of free Queue Head (QH) structures */ + + for (i = 0; i < CONFIG_IMXRT_EHCI_NQHS; i++) + { + /* Put the QH structure in a free list */ + + imxrt_qh_free(&g_qhpool[i]); + } + +# ifndef CONFIG_IMXRT_EHCI_PREALLOCATE + /* Allocate a pool of free Transfer Descriptor (qTD) structures */ + + g_qtdpool = + (struct imxrt_qtd_s *)kmm_memalign(32, + CONFIG_IMXRT_EHCI_NQTDS * + sizeof(struct imxrt_qtd_s)); + if (!g_qtdpool) + { + usbhost_trace1(EHCI_TRACE1_QTDPOOLALLOC_FAILED, 0); + kmm_free(g_qhpool); + return NULL; + } +# endif + +# if !defined(CONFIG_IMXRT_EHCI_PREALLOCATE) && !defined(CONFIG_USBHOST_INT_DISABLE) + /* Allocate the periodic framelist */ + + g_framelist = (uint32_t *) + kmm_memalign(4096, FRAME_LIST_SIZE * sizeof(uint32_t)); + if (!g_framelist) + { + usbhost_trace1(EHCI_TRACE1_PERFLALLOC_FAILED, 0); + kmm_free(g_qhpool); + kmm_free(g_qtdpool); + return NULL; + } +# endif + + /* Initialize the list of free Transfer Descriptor (qTD) structures */ + + for (i = 0; i < CONFIG_IMXRT_EHCI_NQTDS; i++) + { + /* Put the TD in a free list */ + + imxrt_qtd_free(&g_qtdpool[i]); + } + + /* EHCI Hardware Configuration ********************************************/ + + imxrt_clockall_usboh3(); + + /* Reset the controller from the OTG peripheral */ + + putreg32(USBDEV_USBCMD_RST, IMXRT_USBDEV_USBCMD); + while ((getreg32(IMXRT_USBDEV_USBCMD) & USBDEV_USBCMD_RST) != 0); + + /* Program the controller to be the USB host controller Fixed selections: + * CM = Host mode ES = 0, Little endian mode. SLOM Not used in host mode. + * VBPS = 1, off-chip power source Configurable selections: SDIS = 1, + * Stream disable mode. Eliminates overruns/underruns at the expense of + * some performance. + */ + +# ifdef CONFIG_IMXRT_EHCI_SDIS + putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_SDIS | + USBHOST_USBMODE_VBPS, IMXRT_USBDEV_USBMODE); +# else + putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_VBPS, + IMXRT_USBDEV_USBMODE); +# endif + + /* Reset the EHCI hardware */ + + ret = imxrt_reset(); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_RESET_FAILED, -ret); + return NULL; + } + + /* Re-program the USB host controller. As implemented, imxrt_reset() + * requires the host mode setup in order to work. However, we lose the + * host configuration in the reset. + */ + +# ifdef CONFIG_IMXRT_EHCI_SDIS + putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_SDIS | + USBHOST_USBMODE_VBPS, IMXRT_USBDEV_USBMODE); +# else + putreg32(USBHOST_USBMODE_CM_HOST | USBHOST_USBMODE_VBPS, + IMXRT_USBDEV_USBMODE); +# endif + + /* Disable all interrupts */ + + imxrt_putreg(0, &HCOR->usbintr); + + /* Clear pending interrupts. Bits in the USBSTS register are cleared by + * writing a '1' to the corresponding bit. + */ + + imxrt_putreg(EHCI_INT_ALLINTS, &HCOR->usbsts); + +# if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_INFO) + /* Show the EHCI version */ + + regval16 = imxrt_swap16(HCCR->hciversion); + usbhost_vtrace2(EHCI_VTRACE2_HCIVERSION, regval16 >> 8, regval16 & 0xff); + + /* Verify that the correct number of ports is reported */ + + regval = imxrt_getreg(&HCCR->hcsparams); + nports = (regval & EHCI_HCSPARAMS_NPORTS_MASK) >> + EHCI_HCSPARAMS_NPORTS_SHIFT; + + usbhost_vtrace2(EHCI_VTRACE2_HCSPARAMS, nports, regval); + DEBUGASSERT(nports == IMXRT_EHCI_NRHPORT); + + /* Show the HCCPARAMS register */ + + regval = imxrt_getreg(&HCCR->hccparams); + usbhost_vtrace1(EHCI_VTRACE1_HCCPARAMS, regval); +# endif + + /* Initialize the head of the asynchronous queue/reclamation list. "In + * order to communicate with devices via the asynchronous schedule, system + * software must write the ASYNDLISTADDR register with the address of a + * control or bulk queue head. Software must then enable the asynchronous + * schedule by writing a one to the Asynchronous Schedule Enable bit in + * the USBCMD register. In order to communicate with devices via the + * periodic schedule, system software must enable the periodic schedule by + * writing a one to the Periodic Schedule Enable bit in the USBCMD + * register. Note that the schedules can be turned on before the first + * port is reset (and enabled)." + */ + + memset(&g_asynchead, 0, sizeof(struct imxrt_qh_s)); + physaddr = imxrt_physramaddr((uintptr_t) & g_asynchead); + g_asynchead.hw.hlp = imxrt_swap32(physaddr | QH_HLP_TYP_QH); + g_asynchead.hw.epchar = imxrt_swap32(QH_EPCHAR_H | QH_EPCHAR_EPS_FULL); + g_asynchead.hw.overlay.nqp = imxrt_swap32(QH_NQP_T); + g_asynchead.hw.overlay.alt = imxrt_swap32(QH_NQP_T); + g_asynchead.hw.overlay.token = imxrt_swap32(QH_TOKEN_HALTED); + g_asynchead.fqp = imxrt_swap32(QTD_NQP_T); + + /* Set the Current Asynchronous List Address. */ + + up_flush_dcache((uintptr_t)&g_asynchead.hw, + (uintptr_t)&g_asynchead.hw + sizeof(struct ehci_qh_s)); + + imxrt_putreg(imxrt_swap32(physaddr), &HCOR->asynclistaddr); + +# ifndef CONFIG_USBHOST_INT_DISABLE + + /* Initialize the head of the periodic list. Since Isochronous endpoints + * are not not yet supported, each element of the frame list is initialized + * to point to the Interrupt Queue Head (g_intrhead). + */ + + memset(&g_intrhead, 0, sizeof(struct imxrt_qh_s)); + g_intrhead.hw.hlp = imxrt_swap32(QH_HLP_T); + g_intrhead.hw.overlay.nqp = imxrt_swap32(QH_NQP_T); + g_intrhead.hw.overlay.alt = imxrt_swap32(QH_NQP_T); + g_intrhead.hw.overlay.token = imxrt_swap32(QH_TOKEN_HALTED); + g_intrhead.hw.epcaps = imxrt_swap32(QH_EPCAPS_SSMASK(1)); + + /* Attach the periodic QH to Period Frame List */ + + physaddr = imxrt_physramaddr((uintptr_t) & g_intrhead); + for (i = 0; i < FRAME_LIST_SIZE; i++) + { + g_framelist[i] = imxrt_swap32(physaddr) | PFL_TYP_QH; + } + + /* Set the Periodic Frame List Base Address. */ + + physaddr = imxrt_physramaddr((uintptr_t) g_framelist); + imxrt_putreg(imxrt_swap32(physaddr), &HCOR->periodiclistbase); +# endif + + /* Enable the asynchronous schedule and, possibly enable the periodic + * schedule and set the frame list size. + */ + + regval = imxrt_getreg(&HCOR->usbcmd); + regval &= ~(EHCI_USBCMD_HCRESET | EHCI_USBCMD_FLSIZE_MASK | + EHCI_USBCMD_FLSIZE_MASK | EHCI_USBCMD_PSEN | + EHCI_USBCMD_IAADB | EHCI_USBCMD_LRESET); + regval |= EHCI_USBCMD_ASEN; + +# ifndef CONFIG_USBHOST_INT_DISABLE + regval |= EHCI_USBCMD_PSEN; +# if FRAME_LIST_SIZE == 1024 + regval |= EHCI_USBCMD_FLSIZE_1024; +# elif FRAME_LIST_SIZE == 512 + regval |= EHCI_USBCMD_FLSIZE_512; +# elif FRAME_LIST_SIZE == 512 + regval |= EHCI_USBCMD_FLSIZE_256; +# else +# error Unsupported frame size list size +# endif +# endif + + imxrt_putreg(regval, &HCOR->usbcmd); + + /* Start the host controller by setting the RUN bit in the USBCMD + * register. + */ + + regval = imxrt_getreg(&HCOR->usbcmd); + regval |= EHCI_USBCMD_RUN; + imxrt_putreg(regval, &HCOR->usbcmd); + + /* Route all ports to this host controller by setting the CONFIG flag. */ + + regval = imxrt_getreg(&HCOR->configflag); + regval |= EHCI_CONFIGFLAG; + imxrt_putreg(regval, &HCOR->configflag); + + /* Wait for the EHCI to run (i.e., no longer report halted) */ + + ret = ehci_wait_usbsts(EHCI_USBSTS_HALTED, 0, 100 * 1000); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_RUN_FAILED, imxrt_getreg(&HCOR->usbsts)); + return NULL; + } + + /* Interrupt Configuration ************************************************/ + + ret = irq_attach(IMXRT_IRQ_USBOTG2, imxrt_ehci_interrupt, NULL); + if (ret != 0) + { + usbhost_trace1(EHCI_TRACE1_IRQATTACH_FAILED, IMXRT_IRQ_USBOTG2); + return NULL; + } + + /* Enable EHCI interrupts. Interrupts are still disabled at the level of + * the interrupt controller. + */ + + imxrt_putreg(EHCI_HANDLED_INTS, &HCOR->usbintr); + + /* Enable interrupts at the interrupt controller */ + + up_enable_irq(IMXRT_IRQ_USBOTG2); + + /* Drive Vbus +5V (the smoke test) */ + + for (i = 0; i < IMXRT_EHCI_NRHPORT; i++) + { + /* Enable VBUS power for the port */ + + imxrt_usbhost_vbusdrive(i, true); + up_mdelay(25); + } + + /* If there is a USB device in the slot at power up, then we will not get + * the status change interrupt to signal us that the device is connected. + * We need to set the initial connected state accordingly. + */ + + for (i = 0; i < IMXRT_EHCI_NRHPORT; i++) + { + g_ehci.rhport[i].connected = + ((imxrt_getreg(&HCOR->portsc[i]) & EHCI_PORTSC_CCS) != 0); + } + + usbhost_vtrace1(EHCI_VTRACE1_INIITIALIZED, 0); + + /* Initialize and return the connection interface */ + + g_ehciconn.wait = imxrt_wait; + g_ehciconn.enumerate = imxrt_enumerate; + return &g_ehciconn; +} + +/**************************************************************************** + * Name: usbhost_trformat1 and usbhost_trformat2 + * + * Description: + * This interface must be provided by platform specific logic that knows + * the HCDs encoding of USB trace data. + * + * Given an 9-bit index, return a format string suitable for use with, say, + * printf. The returned format is expected to handle two unsigned integer + * values. + * + ****************************************************************************/ + +#ifdef HAVE_USBHOST_TRACE +FAR const char *usbhost_trformat1(uint16_t id) +{ + int ndx = TRACE1_INDEX(id); + + if (ndx < TRACE1_NSTRINGS) + { + return g_trace1[ndx].string; + } + + return NULL; +} + +FAR const char *usbhost_trformat2(uint16_t id) +{ + int ndx = TRACE2_INDEX(id); + + if (ndx < TRACE2_NSTRINGS) + { + return g_trace2[ndx].string; + } + + return NULL; +} +#endif /* HAVE_USBHOST_TRACE */ + +#endif /* CONFIG_IMXRT_USBOTG && CONFIG_USBHOST */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_lowputc.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_lowputc.c new file mode 100644 index 000000000..3649ec4f7 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_lowputc.c @@ -0,0 +1,603 @@ +/**************************************************************************** + * arch/arm/src/imxrt/imxrt_lowputc.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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "arm_arch.h" + +#include "hardware/imxrt_iomuxc.h" +#include "hardware/imxrt_pinmux.h" +#include "hardware/imxrt_ccm.h" +#include "hardware/imxrt_lpuart.h" +#include "imxrt_config.h" +#include "imxrt_periphclks.h" +#include "imxrt_iomuxc.h" +#include "imxrt_gpio.h" +#include "imxrt_lowputc.h" + +#include "arm_internal.h" + +#include /* Include last: has dependencies */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifdef HAVE_LPUART_CONSOLE +# if defined(CONFIG_LPUART1_SERIAL_CONSOLE) +# define IMXRT_CONSOLE_BASE IMXRT_LPUART1_BASE +# define IMXRT_CONSOLE_BAUD CONFIG_LPUART1_BAUD +# define IMXRT_CONSOLE_BITS CONFIG_LPUART1_BITS +# define IMXRT_CONSOLE_PARITY CONFIG_LPUART1_PARITY +# define IMXRT_CONSOLE_2STOP CONFIG_LPUART1_2STOP +# elif defined(CONFIG_LPUART2_SERIAL_CONSOLE) +# define IMXRT_CONSOLE_BASE IMXRT_LPUART2_BASE +# define IMXRT_CONSOLE_BAUD CONFIG_LPUART2_BAUD +# define IMXRT_CONSOLE_BITS CONFIG_LPUART2_BITS +# define IMXRT_CONSOLE_PARITY CONFIG_LPUART2_PARITY +# define IMXRT_CONSOLE_2STOP CONFIG_LPUART2_2STOP +# elif defined(CONFIG_LPUART3_SERIAL_CONSOLE) +# define IMXRT_CONSOLE_BASE IMXRT_LPUART3_BASE +# define IMXRT_CONSOLE_BAUD CONFIG_LPUART3_BAUD +# define IMXRT_CONSOLE_BITS CONFIG_LPUART3_BITS +# define IMXRT_CONSOLE_PARITY CONFIG_LPUART3_PARITY +# define IMXRT_CONSOLE_2STOP CONFIG_LPUART3_2STOP +# elif defined(CONFIG_LPUART4_SERIAL_CONSOLE) +# define IMXRT_CONSOLE_BASE IMXRT_LPUART4_BASE +# define IMXRT_CONSOLE_BAUD CONFIG_LPUART4_BAUD +# define IMXRT_CONSOLE_BITS CONFIG_LPUART4_BITS +# define IMXRT_CONSOLE_PARITY CONFIG_LPUART4_PARITY +# define IMXRT_CONSOLE_2STOP CONFIG_LPUART4_2STOP +# elif defined(CONFIG_LPUART5_SERIAL_CONSOLE) +# define IMXRT_CONSOLE_BASE IMXRT_LPUART5_BASE +# define IMXRT_CONSOLE_BAUD CONFIG_LPUART5_BAUD +# define IMXRT_CONSOLE_BITS CONFIG_LPUART5_BITS +# define IMXRT_CONSOLE_PARITY CONFIG_LPUART5_PARITY +# define IMXRT_CONSOLE_2STOP CONFIG_LPUART5_2STOP +# elif defined(CONFIG_LPUART6_SERIAL_CONSOLE) +# define IMXRT_CONSOLE_BASE IMXRT_LPUART6_BASE +# define IMXRT_CONSOLE_BAUD CONFIG_LPUART6_BAUD +# define IMXRT_CONSOLE_BITS CONFIG_LPUART6_BITS +# define IMXRT_CONSOLE_PARITY CONFIG_LPUART6_PARITY +# define IMXRT_CONSOLE_2STOP CONFIG_LPUART6_2STOP +# elif defined(CONFIG_LPUART7_SERIAL_CONSOLE) +# define IMXRT_CONSOLE_BASE IMXRT_LPUART7_BASE +# define IMXRT_CONSOLE_BAUD CONFIG_LPUART7_BAUD +# define IMXRT_CONSOLE_BITS CONFIG_LPUART7_BITS +# define IMXRT_CONSOLE_PARITY CONFIG_LPUART7_PARITY +# define IMXRT_CONSOLE_2STOP CONFIG_LPUART7_2STOP +# elif defined(CONFIG_LPUART8_SERIAL_CONSOLE) +# define IMXRT_CONSOLE_BASE IMXRT_LPUART8_BASE +# define IMXRT_CONSOLE_BAUD CONFIG_LPUART8_BAUD +# define IMXRT_CONSOLE_BITS CONFIG_LPUART8_BITS +# define IMXRT_CONSOLE_PARITY CONFIG_LPUART8_PARITY +# define IMXRT_CONSOLE_2STOP CONFIG_LPUART8_2STOP +# endif +#endif + +/* Clocking *****************************************************************/ + +/* The UART module receives two clocks, a peripheral_clock (ipg_clk) and the + * module_clock (ipg_perclk). The peripheral_clock is used as write clock + * of the TxFIFO, read clock of the RxFIFO and synchronization of the modem + * control input pins. It must always be running when UART is enabled. + * + * The default lpuart1 ipg_clk is 66MHz (max 66.5MHz). ipg_clk is shared + * among many modules and should not be controlled by the UART logic. + * + * The module_clock is for all the state machines, writing RxFIFO, reading + * TxFIFO, etc. It must always be running when UART is sending or receiving + * characters. This clock is used in order to allow frequency scaling on + * peripheral_clock without changing configuration of baud rate. + * + * The default ipg_perclk is 80MHz (max 80MHz). ipg_perclk is gated by + * CCGR5[CG12], lpuart1_clk_enable. The clock generation sequence is: + * + * pll3_sw_clk (480M) -> CCGR5[CG12] -> 3 bit divider cg podf=6 -> + * PLL3_80M (80Mhz) -> CDCDR1: lpuart1_clk_podf -> + * 6 bit divider default=1 -> LPUART1_CLK_ROOT + * + * REVISIT: This logic assumes that all dividers are at the default value + * and that the value of the ipg_perclk is 80MHz. + */ + +#define IPG_PERCLK_FREQUENCY 80000000 + +/* The BRM sub-block receives ref_clk (module_clock clock after divider). + * From this clock, and with integer and non-integer division, BRM generates + * a 16x baud rate clock. + */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef HAVE_LPUART_CONSOLE +static const struct uart_config_s g_console_config = +{ + .baud = IMXRT_CONSOLE_BAUD, /* Configured baud */ + .parity = IMXRT_CONSOLE_PARITY, /* 0=none, 1=odd, 2=even */ + .bits = IMXRT_CONSOLE_BITS, /* Number of bits (5-9) */ + .stopbits2 = IMXRT_CONSOLE_2STOP, /* true: Configure with 2 stop bits instead of 1 */ +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +void imxrt_lpuart_clock_enable (uint32_t base) +{ + if (base == IMXRT_LPUART1_BASE) + { + imxrt_clockall_lpuart1(); + } + else if (base == IMXRT_LPUART2_BASE) + { + imxrt_clockall_lpuart2(); + } + else if (base == IMXRT_LPUART3_BASE) + { + imxrt_clockall_lpuart3(); + } + else if (base == IMXRT_LPUART4_BASE) + { + imxrt_clockall_lpuart4(); + } + else if (base == IMXRT_LPUART5_BASE) + { + imxrt_clockall_lpuart5(); + } + else if (base == IMXRT_LPUART6_BASE) + { + imxrt_clockall_lpuart6(); + } + else if (base == IMXRT_LPUART7_BASE) + { + imxrt_clockall_lpuart7(); + } + else if (base == IMXRT_LPUART8_BASE) + { + imxrt_clockall_lpuart8(); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level + * initialization including setup of the console UART. This UART done + * early so that the serial console is available for debugging very early + * in the boot sequence. + * + ****************************************************************************/ + +void imxrt_lowsetup(void) +{ +#ifndef CONFIG_SUPPRESS_LPUART_CONFIG +#ifdef HAVE_LPUART_DEVICE + +#ifdef CONFIG_IMXRT_LPUART1 + + /* Configure LPUART1 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + imxrt_config_gpio(GPIO_LPUART1_RX); + imxrt_config_gpio(GPIO_LPUART1_TX); +#ifdef CONFIG_LPUART1_OFLOWCONTROL + imxrt_config_gpio(GPIO_LPUART1_CTS); +#endif +#if ((defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_LPUART1_RS485RTSCONTROL)) || \ + (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART1_IFLOWCONTROL))) + imxrt_config_gpio(GPIO_LPUART1_RTS); +#endif +#endif + +#ifdef CONFIG_IMXRT_LPUART2 + + /* Configure LPUART2 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + imxrt_config_gpio(GPIO_LPUART2_RX); + imxrt_config_gpio(GPIO_LPUART2_TX); +#ifdef CONFIG_LPUART2_OFLOWCONTROL + imxrt_config_gpio(GPIO_LPUART2_CTS); +#endif +#if ((defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_LPUART2_RS485RTSCONTROL)) || \ + (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART2_IFLOWCONTROL))) + imxrt_config_gpio(GPIO_LPUART2_RTS); +#endif +#endif + +#ifdef CONFIG_IMXRT_LPUART3 + + /* Configure LPUART3 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + imxrt_config_gpio(GPIO_LPUART3_RX); + imxrt_config_gpio(GPIO_LPUART3_TX); +#ifdef CONFIG_LPUART3_OFLOWCONTROL + imxrt_config_gpio(GPIO_LPUART3_CTS); +#endif +#if ((defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_LPUART3_RS485RTSCONTROL)) || \ + (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART3_IFLOWCONTROL))) + imxrt_config_gpio(GPIO_LPUART3_RTS); +#endif +#endif + +#ifdef CONFIG_IMXRT_LPUART4 + + /* Configure LPUART4 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + imxrt_config_gpio(GPIO_LPUART4_RX); + imxrt_config_gpio(GPIO_LPUART4_TX); +#ifdef CONFIG_LPUART4_OFLOWCONTROL + imxrt_config_gpio(GPIO_LPUART4_CTS); +#endif +#if ((defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_LPUART4_RS485RTSCONTROL)) || \ + (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART4_IFLOWCONTROL))) + imxrt_config_gpio(GPIO_LPUART4_RTS); +#endif +#endif + +#ifdef CONFIG_IMXRT_LPUART5 + + /* Configure LPUART5 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + imxrt_config_gpio(GPIO_LPUART5_RX); + imxrt_config_gpio(GPIO_LPUART5_TX); +#ifdef CONFIG_LPUART5_OFLOWCONTROL + imxrt_config_gpio(GPIO_LPUART5_CTS); +#endif +#if ((defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_LPUART5_RS485RTSCONTROL)) || \ + (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART5_IFLOWCONTROL))) + imxrt_config_gpio(GPIO_LPUART5_RTS); +#endif +#endif + +#ifdef CONFIG_IMXRT_LPUART6 + + /* Configure LPUART6 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + imxrt_config_gpio(GPIO_LPUART6_RX); + imxrt_config_gpio(GPIO_LPUART6_TX); +#ifdef CONFIG_LPUART6_OFLOWCONTROL + imxrt_config_gpio(GPIO_LPUART6_CTS); +#endif +#if ((defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_LPUART6_RS485RTSCONTROL)) || \ + (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART6_IFLOWCONTROL))) + imxrt_config_gpio(GPIO_LPUART6_RTS); +#endif +#endif + +#ifdef CONFIG_IMXRT_LPUART7 + + /* Configure LPUART7 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + imxrt_config_gpio(GPIO_LPUART7_RX); + imxrt_config_gpio(GPIO_LPUART7_TX); +#ifdef CONFIG_LPUART7_OFLOWCONTROL + imxrt_config_gpio(GPIO_LPUART7_CTS); +#endif +#if ((defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_LPUART7_RS485RTSCONTROL)) || \ + (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART7_IFLOWCONTROL))) + imxrt_config_gpio(GPIO_LPUART7_RTS); +#endif +#endif + +#ifdef CONFIG_IMXRT_LPUART8 + + /* Configure LPUART8 pins: RXD and TXD. Also configure RTS and CTS if flow + * control is enabled. + */ + + imxrt_config_gpio(GPIO_LPUART8_RX); + imxrt_config_gpio(GPIO_LPUART8_TX); +#ifdef CONFIG_LPUART8_OFLOWCONTROL + imxrt_config_gpio(GPIO_LPUART8_CTS); +#endif +#if ((defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_LPUART8_RS485RTSCONTROL)) || \ + (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART8_IFLOWCONTROL))) + imxrt_config_gpio(GPIO_LPUART8_RTS); +#endif +#endif + +#ifdef HAVE_LPUART_CONSOLE + /* Configure the serial console for initial, non-interrupt driver mode */ + + imxrt_lpuart_configure(IMXRT_CONSOLE_BASE, &g_console_config); +#endif +#endif /* HAVE_LPUART_DEVICE */ +#endif /* CONFIG_SUPPRESS_LPUART_CONFIG */ +} + +/**************************************************************************** + * Name: imxrt_lpuart_configure + * + * Description: + * Configure a UART for non-interrupt driven operation + * + ****************************************************************************/ + +#ifdef HAVE_LPUART_DEVICE +int imxrt_lpuart_configure(uint32_t base, + FAR const struct uart_config_s *config) +{ + uint32_t src_freq = 0; + uint32_t pll3_div = 0; + uint32_t uart_div = 0; + uint32_t lpuart_freq = 0; + uint16_t sbr; + uint16_t temp_sbr; + uint32_t osr; + uint32_t temp_osr; + uint32_t temp_diff; + uint32_t calculated_baud; + uint32_t baud_diff; + uint32_t regval; + uint32_t regval2; + + if ((getreg32(IMXRT_CCM_CSCDR1) & CCM_CSCDR1_UART_CLK_SEL) != 0) + { + src_freq = BOARD_XTAL_FREQUENCY; + } + else + { + if ((getreg32(IMXRT_CCM_ANALOG_PLL_USB2) & + CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK) != 0) + { + pll3_div = 22; + } + else + { + pll3_div = 20; + } + + src_freq = (BOARD_XTAL_FREQUENCY * pll3_div) / 6; + } + + uart_div = (getreg32(IMXRT_CCM_CSCDR1) & + CCM_CSCDR1_UART_CLK_PODF_MASK) + 1; + lpuart_freq = src_freq / uart_div; + + /* This LPUART instantiation uses a slightly different baud rate + * calculation. The idea is to use the best OSR (over-sampling rate) + * possible. + * + * NOTE: OSR is typically hard-set to 16 in other LPUART instantiations + * loop to find the best OSR value possible, one that generates minimum + * baud_diff iterate through the rest of the supported values of OSR + */ + + baud_diff = config->baud; + osr = 0; + sbr = 0; + + for (temp_osr = 4; temp_osr <= 32; temp_osr++) + { + /* Calculate the temporary sbr value */ + + temp_sbr = (lpuart_freq / (config->baud * temp_osr)); + + /* Set temp_sbr to 1 if the sourceClockInHz can not satisfy the + * desired baud rate. + */ + + if (temp_sbr == 0) + { + temp_sbr = 1; + } + + /* Calculate the baud rate based on the temporary OSR and SBR values */ + + calculated_baud = (lpuart_freq / (temp_osr * temp_sbr)); + temp_diff = calculated_baud - config->baud; + + /* Select the better value between srb and (sbr + 1) */ + + if (temp_diff > (config->baud - + (lpuart_freq / (temp_osr * (temp_sbr + 1))))) + { + temp_diff = config->baud - + (lpuart_freq / (temp_osr * (temp_sbr + 1))); + temp_sbr++; + } + + if (temp_diff <= baud_diff) + { + baud_diff = temp_diff; + osr = temp_osr; + sbr = temp_sbr; + } + } + + if (baud_diff > ((config->baud / 100) * 3)) + { + /* Unacceptable baud rate difference of more than 3% */ + + return ERROR; + } + + /* Enable lpuart clock */ + + imxrt_lpuart_clock_enable(base); + + /* Reset all internal logic and registers, except the Global Register */ + + regval = getreg32(base + IMXRT_LPUART_GLOBAL_OFFSET); + regval |= LPUART_GLOBAL_RST; + putreg32(regval, base + IMXRT_LPUART_GLOBAL_OFFSET); + + regval &= ~LPUART_GLOBAL_RST; + putreg32(regval, base + IMXRT_LPUART_GLOBAL_OFFSET); + + /* Construct MODIR register */ + + regval = 0; + + if (config->userts) + { + regval |= LPUART_MODIR_RXRTSE; + } + else if (config->users485) + { + /* Both TX and RX side can't control RTS, so this gives + * the RX side precedence. This should have been filtered + * in layers above anyway, but it's just a precaution. + */ + + regval |= LPUART_MODIR_TXRTSE; + } + + if (config->usects) + { + regval |= LPUART_MODIR_TXCTSE; + } + + if (config->invrts) + { + regval |= LPUART_MODIR_TXRTSPOL; + } + + putreg32(regval, base + IMXRT_LPUART_MODIR_OFFSET); + + regval = 0; + + if ((osr > 3) && (osr < 8)) + { + regval |= LPUART_BAUD_BOTHEDGE; + } + + if (config->stopbits2) + { + regval |= LPUART_BAUD_SBNS; + } + + regval |= LPUART_BAUD_OSR(osr) | LPUART_BAUD_SBR(sbr); + putreg32(regval, base + IMXRT_LPUART_BAUD_OFFSET); + + regval = 0; + if (config->parity == 1) + { + regval |= LPUART_CTRL_PE | LPUART_CTRL_PT_ODD; + } + else if (config->parity == 2) + { + regval |= LPUART_CTRL_PE | LPUART_CTRL_PT_EVEN; + } + + if (config->bits == 9 || (config->bits == 8 && config->parity != 0)) + { + regval |= LPUART_CTRL_M; + } + else if ((config->bits == 8)) + { + regval &= ~LPUART_CTRL_M; + } + else + { + /* Here should be added support of other bit modes. */ + +#warning missing logic + return ERROR; + } + + regval2 = getreg32(base + IMXRT_LPUART_FIFO_OFFSET); + regval2 |= LPUART_FIFO_RXFLUSH | LPUART_FIFO_TXFLUSH | + LPUART_FIFO_RXFE | LPUART_FIFO_RXIDEN_1 | LPUART_FIFO_TXFE; + putreg32(regval2 , base + IMXRT_LPUART_FIFO_OFFSET); + + regval |= LPUART_CTRL_RE | LPUART_CTRL_TE; + putreg32(regval, base + IMXRT_LPUART_CTRL_OFFSET); + + return OK; +} +#endif /* HAVE_LPUART_DEVICE */ + +/**************************************************************************** + * Name: imxrt_lowputc + * + * Description: + * Output a byte with as few system dependencies as possible. This will + * even work BEFORE the console is initialized if we are booting from U- + * Boot (and the same UART is used for the console, of course.) + * + ****************************************************************************/ + +#if defined(HAVE_LPUART_DEVICE) && defined(CONFIG_DEBUG_FEATURES) +void imxrt_lowputc(int ch) +{ + while ((getreg32(IMXRT_CONSOLE_BASE + IMXRT_LPUART_STAT_OFFSET) & + LPUART_STAT_TDRE) == 0) + { + } + + /* If the character to output is a newline, then pre-pend a carriage + * return + */ + + if (ch == '\n') + { + /* Send the carriage return by writing it into the UART_TXD register. */ + + putreg32((uint32_t)'\r', IMXRT_CONSOLE_BASE + + IMXRT_LPUART_DATA_OFFSET); + + /* Wait for the transmit register to be emptied. When the TXFE bit is + * non-zero, the TX Buffer FIFO is empty. + */ + + while ((getreg32(IMXRT_CONSOLE_BASE + IMXRT_LPUART_STAT_OFFSET) & + LPUART_STAT_TDRE) == 0) + { + } + } + + /* Send the character by writing it into the UART_TXD register. */ + + putreg32((uint32_t)ch, IMXRT_CONSOLE_BASE + IMXRT_LPUART_DATA_OFFSET); +} +#endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_lpi2c.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_lpi2c.c new file mode 100644 index 000000000..20d8e1914 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_lpi2c.c @@ -0,0 +1,1997 @@ +/**************************************************************************** + * arch/arm/src/imxrt/imxrt_lpi2c.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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "arm_arch.h" + +#include "imxrt_lpi2c.h" +#include "imxrt_gpio.h" + +#include "hardware/imxrt_pinmux.h" +#include "hardware/imxrt_ccm.h" +#include "imxrt_periphclks.h" + +/* At least one I2C peripheral must be enabled */ + +#if defined(CONFIG_IMXRT_LPI2C1) || defined(CONFIG_IMXRT_LPI2C2) || \ + defined(CONFIG_IMXRT_LPI2C3) || defined(CONFIG_IMXRT_LPI2C4) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* CONFIG_I2C_POLLED may be set so that I2C interrupts will not be used. + * Instead, CPU-intensive polling will be used. + */ + +/* Interrupt wait timeout in seconds and milliseconds */ + +#if !defined(CONFIG_IMXRT_LPI2C_TIMEOSEC) && \ + !defined(CONFIG_IMXRT_LPI2C_TIMEOMS) +# define CONFIG_IMXRT_LPI2C_TIMEOSEC 0 +# define CONFIG_IMXRT_LPI2C_TIMEOMS 500 /* Default is 500 milliseconds */ +#elif !defined(CONFIG_IMXRT_LPI2C_TIMEOSEC) +# define CONFIG_IMXRT_LPI2C_TIMEOSEC 0 /* User provided milliseconds */ +#elif !defined(CONFIG_IMXRT_LPI2C_TIMEOMS) +# define CONFIG_IMXRT_LPI2C_TIMEOMS 0 /* User provided seconds */ +#endif + +/* Interrupt wait time timeout in system timer ticks */ + +#ifndef CONFIG_IMXRT_LPI2C_TIMEOTICKS +# define CONFIG_IMXRT_LPI2C_TIMEOTICKS \ + (SEC2TICK(CONFIG_IMXRT_LPI2C_TIMEOSEC) + \ + MSEC2TICK(CONFIG_IMXRT_LPI2C_TIMEOMS)) +#endif + +#ifndef CONFIG_IMXRT_LPI2C_DYNTIMEO_STARTSTOP +# define CONFIG_IMXRT_LPI2C_DYNTIMEO_STARTSTOP \ + TICK2USEC(CONFIG_IMXRT_LPI2C_TIMEOTICKS) +#endif + +/* Debug ********************************************************************/ + +/* I2C event trace logic. NOTE: trace uses the internal, non-standard, + * low-level debug interface syslog() but does not require that any other + * debug is enabled. + */ + +#ifndef CONFIG_I2C_TRACE +# define imxrt_lpi2c_tracereset(p) +# define imxrt_lpi2c_tracenew(p,s) +# define imxrt_lpi2c_traceevent(p,e,a) +# define imxrt_lpi2c_tracedump(p) +#endif + +#ifndef CONFIG_I2C_NTRACE +# define CONFIG_I2C_NTRACE 32 +#endif + +#ifdef CONFIG_I2C_SLAVE +# error I2C slave logic is not supported yet for IMXRT +#endif + +#define LPI2C_MASTER 1 +#define LPI2C_SLAVE 2 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Interrupt state */ + +enum imxrt_intstate_e +{ + INTSTATE_IDLE = 0, /* No I2C activity */ + INTSTATE_WAITING, /* Waiting for completion of interrupt activity */ + INTSTATE_DONE, /* Interrupt activity complete */ +}; + +/* Trace events */ + +enum imxrt_trace_e +{ + I2CEVENT_NONE = 0, /* No events have occurred with this status */ + I2CEVENT_SENDADDR, /* Start/Master bit set and address sent, param = msgc */ + I2CEVENT_SENDBYTE, /* Send byte, param = dcnt */ + I2CEVENT_RCVBYTE, /* Read more dta, param = dcnt */ + I2CEVENT_NOSTART, /* BTF on last byte with no restart, param = msgc */ + I2CEVENT_STARTRESTART, /* Last byte sent, re-starting, param = msgc */ + I2CEVENT_STOP, /* Last byte sten, send stop, param = 0 */ + I2CEVENT_ERROR /* Error occurred, param = 0 */ +}; + +/* Trace data */ + +struct imxrt_trace_s +{ + uint32_t status; /* I2C 32-bit SR2|SR1 status */ + uint32_t count; /* Interrupt count when status change */ + enum imxrt_intstate_e event; /* Last event that occurred with this status */ + uint32_t parm; /* Parameter associated with the event */ + clock_t time; /* First of event or first status */ +}; + +/* I2C Device hardware configuration */ + +struct imxrt_lpi2c_config_s +{ + uint32_t base; /* LPI2C base address */ + uint16_t busy_idle; /* LPI2C Bus Idle Timeout */ + uint8_t filtscl; /* Glitch Filter for SCL pin */ + uint8_t filtsda; /* Glitch Filter for SDA pin */ + uint32_t scl_pin; /* Peripheral configuration for SCL as SCL */ + uint32_t sda_pin; /* Peripheral configuration for SDA as SDA */ +#if defined(CONFIG_I2C_RESET) + uint32_t reset_scl_pin; /* GPIO configuration for SCL as SCL */ + uint32_t reset_sda_pin; /* GPIO configuration for SDA as SDA */ +#endif + uint8_t mode; /* Master or Slave mode */ +#ifndef CONFIG_I2C_POLLED + uint32_t irq; /* Event IRQ */ +#endif +}; + +/* I2C Device Private Data */ + +struct imxrt_lpi2c_priv_s +{ + /* Standard I2C operations */ + + const struct i2c_ops_s *ops; + + /* Port configuration */ + + const struct imxrt_lpi2c_config_s *config; + + int refs; /* Reference count */ + sem_t sem_excl; /* Mutual exclusion semaphore */ +#ifndef CONFIG_I2C_POLLED + sem_t sem_isr; /* Interrupt wait semaphore */ +#endif + volatile uint8_t intstate; /* Interrupt handshake (see enum imxrt_intstate_e) */ + + uint8_t msgc; /* Message count */ + struct i2c_msg_s *msgv; /* Message list */ + uint8_t *ptr; /* Current message buffer */ + uint32_t frequency; /* Current I2C frequency */ + int dcnt; /* Current message length */ + uint16_t flags; /* Current message flags */ + + /* I2C trace support */ + +#ifdef CONFIG_I2C_TRACE + int tndx; /* Trace array index */ + clock_t start_time; /* Time when the trace was started */ + + /* The actual trace data */ + + struct imxrt_trace_s trace[CONFIG_I2C_NTRACE]; +#endif + + uint32_t status; /* End of transfer SR2|SR1 status */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline uint32_t + imxrt_lpi2c_getreg(FAR struct imxrt_lpi2c_priv_s *priv, uint16_t offset); +static inline void imxrt_lpi2c_putreg(FAR struct imxrt_lpi2c_priv_s *priv, + uint16_t offset, uint32_t value); +static inline void imxrt_lpi2c_modifyreg(FAR struct imxrt_lpi2c_priv_s *priv, + uint16_t offset, uint32_t clearbits, + uint32_t setbits); +static inline int imxrt_lpi2c_sem_wait(FAR struct imxrt_lpi2c_priv_s *priv); +#ifdef CONFIG_I2C_RESET +static int + imxrt_lpi2c_sem_wait_noncancelable(FAR struct imxrt_lpi2c_priv_s *priv); +#endif + +#ifdef CONFIG_IMXRT_LPI2C_DYNTIMEO +static useconds_t imxrt_lpi2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs); +#endif /* CONFIG_IMXRT_LPI2C_DYNTIMEO */ + +static inline int + imxrt_lpi2c_sem_waitdone(FAR struct imxrt_lpi2c_priv_s *priv); +static inline void + imxrt_lpi2c_sem_waitstop(FAR struct imxrt_lpi2c_priv_s *priv); +static inline void + imxrt_lpi2c_sem_post(FAR struct imxrt_lpi2c_priv_s *priv); +static inline void + imxrt_lpi2c_sem_init(FAR struct imxrt_lpi2c_priv_s *priv); +static inline void + imxrt_lpi2c_sem_destroy(FAR struct imxrt_lpi2c_priv_s *priv); + +#ifdef CONFIG_I2C_TRACE +static void imxrt_lpi2c_tracereset(FAR struct imxrt_lpi2c_priv_s *priv); +static void imxrt_lpi2c_tracenew(FAR struct imxrt_lpi2c_priv_s *priv, + uint32_t status); +static void imxrt_lpi2c_traceevent(FAR struct imxrt_lpi2c_priv_s *priv, + enum imxrt_trace_e event, uint32_t parm); +static void imxrt_lpi2c_tracedump(FAR struct imxrt_lpi2c_priv_s *priv); +#endif /* CONFIG_I2C_TRACE */ + +static void imxrt_lpi2c_setclock(FAR struct imxrt_lpi2c_priv_s *priv, + uint32_t frequency); +static inline void imxrt_lpi2c_sendstart(FAR struct imxrt_lpi2c_priv_s *priv, + uint8_t address); +static inline void imxrt_lpi2c_sendstop(FAR struct imxrt_lpi2c_priv_s *priv); +static inline uint32_t + imxrt_lpi2c_getstatus(FAR struct imxrt_lpi2c_priv_s *priv); + +static int imxrt_lpi2c_isr_process(struct imxrt_lpi2c_priv_s * priv); + +#ifndef CONFIG_I2C_POLLED +static int imxrt_lpi2c_isr(int irq, void *context, FAR void *arg); +#endif /* !CONFIG_I2C_POLLED */ + +void imxrt_lpi2c_clock_enable (uint32_t base); +void imxrt_lpi2c_clock_disable (uint32_t base); +static int imxrt_lpi2c_init(FAR struct imxrt_lpi2c_priv_s *priv); +static int imxrt_lpi2c_deinit(FAR struct imxrt_lpi2c_priv_s *priv); +static int imxrt_lpi2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int imxrt_lpi2c_reset(FAR struct i2c_master_s *dev); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Trace events strings */ + +#ifdef CONFIG_I2C_TRACE +static const char *g_trace_names[] = +{ + "NONE ", + "SENDADDR ", + "SENDBYTE ", + "RCVBYTE ", + "NOSTART ", + "START/RESTART ", + "STOP ", + "ERROR " +}; +#endif + +/* I2C interface */ + +static const struct i2c_ops_s imxrt_lpi2c_ops = +{ + .transfer = imxrt_lpi2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = imxrt_lpi2c_reset +#endif +}; + +/* I2C device structures */ + +#ifdef CONFIG_IMXRT_LPI2C1 +static const struct imxrt_lpi2c_config_s imxrt_lpi2c1_config = +{ + .base = IMXRT_LPI2C1_BASE, + .busy_idle = CONFIG_LPI2C1_BUSYIDLE, + .filtscl = CONFIG_LPI2C1_FILTSCL, + .filtsda = CONFIG_LPI2C1_FILTSDA, + .scl_pin = GPIO_LPI2C1_SCL, + .sda_pin = GPIO_LPI2C1_SDA, +#if defined(CONFIG_I2C_RESET) + .reset_scl_pin = GPIO_LPI2C1_SCL_RESET, + .reset_sda_pin = GPIO_LPI2C1_SDA_RESET, +#endif +#ifndef CONFIG_I2C_SLAVE + .mode = LPI2C_MASTER, +#else + .mode = LPI2C_SLAVE, +#endif +#ifndef CONFIG_I2C_POLLED + .irq = IMXRT_IRQ_LPI2C1, +#endif +}; + +static struct imxrt_lpi2c_priv_s imxrt_lpi2c1_priv = +{ + .ops = &imxrt_lpi2c_ops, + .config = &imxrt_lpi2c1_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +#ifdef CONFIG_IMXRT_LPI2C2 +static const struct imxrt_lpi2c_config_s imxrt_lpi2c2_config = +{ + .base = IMXRT_LPI2C2_BASE, + .busy_idle = CONFIG_LPI2C2_BUSYIDLE, + .filtscl = CONFIG_LPI2C2_FILTSCL, + .filtsda = CONFIG_LPI2C2_FILTSDA, + .scl_pin = GPIO_LPI2C2_SCL, + .sda_pin = GPIO_LPI2C2_SDA, +#if defined(CONFIG_I2C_RESET) + .reset_scl_pin = GPIO_LPI2C2_SCL_RESET, + .reset_sda_pin = GPIO_LPI2C2_SDA_RESET, +#endif +#ifndef CONFIG_I2C_SLAVE + .mode = LPI2C_MASTER, +#else + .mode = LPI2C_SLAVE, +#endif +#ifndef CONFIG_I2C_POLLED + .irq = IMXRT_IRQ_LPI2C2, +#endif +}; + +static struct imxrt_lpi2c_priv_s imxrt_lpi2c2_priv = +{ + .ops = &imxrt_lpi2c_ops, + .config = &imxrt_lpi2c2_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +#ifdef CONFIG_IMXRT_LPI2C3 +static const struct imxrt_lpi2c_config_s imxrt_lpi2c3_config = +{ + .base = IMXRT_LPI2C3_BASE, + .busy_idle = CONFIG_LPI2C3_BUSYIDLE, + .filtscl = CONFIG_LPI2C3_FILTSCL, + .filtsda = CONFIG_LPI2C3_FILTSDA, + .scl_pin = GPIO_LPI2C3_SCL, + .sda_pin = GPIO_LPI2C3_SDA, +#if defined(CONFIG_I2C_RESET) + .reset_scl_pin = GPIO_LPI2C3_SCL_RESET, + .reset_sda_pin = GPIO_LPI2C3_SDA_RESET, +#endif +#ifndef CONFIG_I2C_SLAVE + .mode = LPI2C_MASTER, +#else + .mode = LPI2C_SLAVE, +#endif +#ifndef CONFIG_I2C_POLLED + .irq = IMXRT_IRQ_LPI2C3, +#endif +}; + +static struct imxrt_lpi2c_priv_s imxrt_lpi2c3_priv = +{ + .ops = &imxrt_lpi2c_ops, + .config = &imxrt_lpi2c3_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +#ifdef CONFIG_IMXRT_LPI2C4 +static const struct imxrt_lpi2c_config_s imxrt_lpi2c4_config = +{ + .base = IMXRT_LPI2C4_BASE, + .busy_idle = CONFIG_LPI2C4_BUSYIDLE, + .filtscl = CONFIG_LPI2C4_FILTSCL, + .filtsda = CONFIG_LPI2C4_FILTSDA, + .scl_pin = GPIO_LPI2C4_SCL, + .sda_pin = GPIO_LPI2C4_SDA, +#if defined(CONFIG_I2C_RESET) + .reset_scl_pin = GPIO_LPI2C4_SCL_RESET, + .reset_sda_pin = GPIO_LPI2C4_SDA_RESET, +#endif +#ifndef CONFIG_I2C_SLAVE + .mode = LPI2C_MASTER, +#else + .mode = LPI2C_SLAVE, +#endif +#ifndef CONFIG_I2C_POLLED + .irq = IMXRT_IRQ_LPI2C4, +#endif +}; + +static struct imxrt_lpi2c_priv_s imxrt_lpi2c4_priv = +{ + .ops = &imxrt_lpi2c_ops, + .config = &imxrt_lpi2c4_config, + .refs = 0, + .intstate = INTSTATE_IDLE, + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .dcnt = 0, + .flags = 0, + .status = 0 +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_lpi2c_getreg + * + * Description: + * Get a 32-bit register value by offset + * + ****************************************************************************/ + +static inline uint32_t + imxrt_lpi2c_getreg(FAR struct imxrt_lpi2c_priv_s *priv, uint16_t offset) +{ + return getreg32(priv->config->base + offset); +} + +/**************************************************************************** + * Name: imxrt_lpi2c_putreg + * + * Description: + * Put a 32-bit register value by offset + * + ****************************************************************************/ + +static inline void imxrt_lpi2c_putreg(FAR struct imxrt_lpi2c_priv_s *priv, + uint16_t offset, uint32_t value) +{ + putreg32(value, priv->config->base + offset); +} + +/**************************************************************************** + * Name: imxrt_lpi2c_modifyreg + * + * Description: + * Modify a 32-bit register value by offset + * + ****************************************************************************/ + +static inline void imxrt_lpi2c_modifyreg(FAR struct imxrt_lpi2c_priv_s *priv, + uint16_t offset, uint32_t clearbits, + uint32_t setbits) +{ + modifyreg32(priv->config->base + offset, clearbits, setbits); +} + +/**************************************************************************** + * Name: imxrt_lpi2c_sem_wait + * + * Description: + * Take the exclusive access, waiting as necessary. May be interrupted by + * a signal. + * + ****************************************************************************/ + +static inline int imxrt_lpi2c_sem_wait(FAR struct imxrt_lpi2c_priv_s *priv) +{ + return nxsem_wait(&priv->sem_excl); +} + +/**************************************************************************** + * Name: imxrt_lpi2c_sem_wait_noncancelable + * + * Description: + * Take the exclusive access, waiting as necessary. + * + ****************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int + imxrt_lpi2c_sem_wait_noncancelable(FAR struct imxrt_lpi2c_priv_s *priv) +{ + return nxsem_wait_uninterruptible(&priv->sem_excl); +} +#endif + +/**************************************************************************** + * Name: imxrt_lpi2c_tousecs + * + * Description: + * Return a micro-second delay based on the number of bytes left to be + * processed. + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_LPI2C_DYNTIMEO +static useconds_t imxrt_lpi2c_tousecs(int msgc, FAR struct i2c_msg_s *msgs) +{ + size_t bytecount = 0; + int i; + + /* Count the number of bytes left to process */ + + for (i = 0; i < msgc; i++) + { + bytecount += msgs[i].length; + } + + /* Then return a number of microseconds based on a user provided scaling + * factor. + */ + + return (useconds_t)(CONFIG_IMXRT_LPI2C_DYNTIMEO_USECPERBYTE * bytecount); +} +#endif + +/**************************************************************************** + * Name: imxrt_lpi2c_sem_waitdone + * + * Description: + * Wait for a transfer to complete + * + ****************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static inline int + imxrt_lpi2c_sem_waitdone(FAR struct imxrt_lpi2c_priv_s *priv) +{ + struct timespec abstime; + irqstate_t flags; + uint32_t regval; + int ret; + + flags = enter_critical_section(); + + /* Enable Interrupts when master mode */ + + if (priv->config->mode == LPI2C_MASTER) + { + if ((priv->flags & I2C_M_READ) != 0) + { + regval = LPI2C_MIER_TDIE | LPI2C_MIER_RDIE | LPI2C_MIER_NDIE | \ + LPI2C_MIER_ALIE | LPI2C_MIER_SDIE; + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MIER_OFFSET, regval); + } + else + { + regval = LPI2C_MIER_TDIE | LPI2C_MIER_NDIE | \ + LPI2C_MIER_ALIE | LPI2C_MIER_SDIE; + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MIER_OFFSET, regval); + } + } + + /* Enable Interrupts when slave mode */ + + else + { +#warning Missing logic for I2C Slave mode + } + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * nxsem_timedwait() sleeps. + */ + + priv->intstate = INTSTATE_WAITING; + do + { + /* Get the current time */ + + clock_gettime(CLOCK_REALTIME, &abstime); + + /* Calculate a time in the future */ + +#if CONFIG_IMXRT_LPI2C_TIMEOSEC > 0 + abstime.tv_sec += CONFIG_IMXRT_LPI2C_TIMEOSEC; +#endif + + /* Add a value proportional to the number of bytes in the transfer */ + +#ifdef CONFIG_IMXRT_LPI2C_DYNTIMEO + abstime.tv_nsec += 1000 * imxrt_lpi2c_tousecs(priv->msgc, priv->msgv); + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } + +#elif CONFIG_IMXRT_LPI2C_TIMEOMS > 0 + abstime.tv_nsec += CONFIG_IMXRT_LPI2C_TIMEOMS * 1000 * 1000; + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } +#endif + + /* Wait until either the transfer is complete or the timeout expires */ + + ret = nxsem_timedwait_uninterruptible(&priv->sem_isr, &abstime); + if (ret < 0) + { + /* Break out of the loop on irrecoverable errors. This would + * include timeouts and mystery errors reported by nxsem_timedwait. + */ + + break; + } + } + + /* Loop until the interrupt level transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE); + + /* Set the interrupt state back to IDLE */ + + priv->intstate = INTSTATE_IDLE; + + /* Disable I2C interrupts */ + + /* Enable Interrupts when master mode */ + + if (priv->config->mode == LPI2C_MASTER) + { + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MIER_OFFSET, 0); + } + + /* Enable Interrupts when slave mode */ + + else + { + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_SIER_OFFSET, 0); + } + + leave_critical_section(flags); + return ret; +} +#else +static inline int + imxrt_lpi2c_sem_waitdone(FAR struct imxrt_lpi2c_priv_s *priv) +{ + clock_t timeout; + clock_t start; + clock_t elapsed; + int ret; + + /* Get the timeout value */ + +#ifdef CONFIG_IMXRT_LPI2C_DYNTIMEO + timeout = USEC2TICK(imxrt_lpi2c_tousecs(priv->msgc, priv->msgv)); +#else + timeout = CONFIG_IMXRT_LPI2C_TIMEOTICKS; +#endif + + /* Signal the interrupt handler that we are waiting. NOTE: Interrupts + * are currently disabled but will be temporarily re-enabled below when + * nxsem_timedwait() sleeps. + */ + + priv->intstate = INTSTATE_WAITING; + start = clock_systime_ticks(); + + do + { + /* Calculate the elapsed time */ + + elapsed = clock_systime_ticks() - start; + + /* Poll by simply calling the timer interrupt handler until it + * reports that it is done. + */ + + imxrt_lpi2c_isr_process(priv); + } + + /* Loop until the transfer is complete. */ + + while (priv->intstate != INTSTATE_DONE && elapsed < timeout); + + i2cinfo("intstate: %d elapsed: %ld threshold: %ld status: %08x\n", + priv->intstate, (long)elapsed, (long)timeout, priv->status); + + /* Set the interrupt state back to IDLE */ + + ret = priv->intstate == INTSTATE_DONE ? OK : -ETIMEDOUT; + priv->intstate = INTSTATE_IDLE; + return ret; +} +#endif + +/**************************************************************************** + * Name: imxrt_lpi2c_sem_waitstop + * + * Description: + * Wait for a STOP to complete + * + ****************************************************************************/ + +static inline void + imxrt_lpi2c_sem_waitstop(FAR struct imxrt_lpi2c_priv_s *priv) +{ + clock_t start; + clock_t elapsed; + clock_t timeout; + uint32_t regval; + + /* Select a timeout */ + +#ifdef CONFIG_IMXRT_LPI2C_DYNTIMEO + timeout = USEC2TICK(CONFIG_IMXRT_LPI2C_DYNTIMEO_STARTSTOP); +#else + timeout = CONFIG_IMXRT_LPI2C_TIMEOTICKS; +#endif + + /* Wait as stop might still be in progress; but stop might also + * be set because of a timeout error: "The [STOP] bit is set and + * cleared by software, cleared by hardware when a Stop condition is + * detected, set by hardware when a timeout error is detected." + */ + + start = clock_systime_ticks(); + do + { + /* Calculate the elapsed time */ + + elapsed = clock_systime_ticks() - start; + + /* Check for STOP condition */ + + if (priv->config->mode == LPI2C_MASTER) + { + regval = imxrt_lpi2c_getreg(priv, IMXRT_LPI2C_MSR_OFFSET); + if ((regval & LPI2C_MSR_SDF) == LPI2C_MSR_SDF) + { + return; + } + } + + /* Enable Interrupts when slave mode */ + + else + { + regval = imxrt_lpi2c_getreg(priv, IMXRT_LPI2C_SSR_OFFSET); + if ((regval & LPI2C_SSR_SDF) == LPI2C_SSR_SDF) + { + return; + } + } + + /* Check for NACK error */ + + if (priv->config->mode == LPI2C_MASTER) + { + regval = imxrt_lpi2c_getreg(priv, IMXRT_LPI2C_MSR_OFFSET); + if ((regval & LPI2C_MSR_NDF) == LPI2C_MSR_NDF) + { + return; + } + } + + /* Enable Interrupts when slave mode */ + + else + { +#warning Missing logic for I2C Slave + } + } + + /* Loop until the stop is complete or a timeout occurs. */ + + while (elapsed < timeout); + + /* If we get here then a timeout occurred with the STOP condition + * still pending. + */ + + i2cinfo("Timeout with Status Register: %" PRIx32 "\n", regval); +} + +/**************************************************************************** + * Name: imxrt_lpi2c_sem_post + * + * Description: + * Release the mutual exclusion semaphore + * + ****************************************************************************/ + +static inline void imxrt_lpi2c_sem_post(struct imxrt_lpi2c_priv_s *priv) +{ + nxsem_post(&priv->sem_excl); +} + +/**************************************************************************** + * Name: imxrt_lpi2c_sem_init + * + * Description: + * Initialize semaphores + * + ****************************************************************************/ + +static inline void imxrt_lpi2c_sem_init(FAR struct imxrt_lpi2c_priv_s *priv) +{ + nxsem_init(&priv->sem_excl, 0, 1); + +#ifndef CONFIG_I2C_POLLED + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + nxsem_init(&priv->sem_isr, 0, 0); + nxsem_set_protocol(&priv->sem_isr, SEM_PRIO_NONE); +#endif +} + +/**************************************************************************** + * Name: imxrt_lpi2c_sem_destroy + * + * Description: + * Destroy semaphores. + * + ****************************************************************************/ + +static inline void + imxrt_lpi2c_sem_destroy(FAR struct imxrt_lpi2c_priv_s *priv) +{ + nxsem_destroy(&priv->sem_excl); +#ifndef CONFIG_I2C_POLLED + nxsem_destroy(&priv->sem_isr); +#endif +} + +/**************************************************************************** + * Name: imxrt_lpi2c_trace* + * + * Description: + * I2C trace instrumentation + * + ****************************************************************************/ + +#ifdef CONFIG_I2C_TRACE +static void imxrt_lpi2c_traceclear(FAR struct imxrt_lpi2c_priv_s *priv) +{ + struct imxrt_trace_s *trace = &priv->trace[priv->tndx]; + + trace->status = 0; /* I2C 32-bit SR2|SR1 status */ + trace->count = 0; /* Interrupt count when status change */ + trace->event = I2CEVENT_NONE; /* Last event that occurred with this status */ + trace->parm = 0; /* Parameter associated with the event */ + trace->time = 0; /* Time of first status or event */ +} + +static void imxrt_lpi2c_tracereset(FAR struct imxrt_lpi2c_priv_s *priv) +{ + /* Reset the trace info for a new data collection */ + + priv->tndx = 0; + priv->start_time = clock_systime_ticks(); + imxrt_lpi2c_traceclear(priv); +} + +static void imxrt_lpi2c_tracenew(FAR struct imxrt_lpi2c_priv_s *priv, + uint32_t status) +{ + struct imxrt_trace_s *trace = &priv->trace[priv->tndx]; + + /* Is the current entry uninitialized? Has the status changed? */ + + if (trace->count == 0 || status != trace->status) + { + /* Yes.. Was it the status changed? */ + + if (trace->count != 0) + { + /* Yes.. bump up the trace index (unless out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE - 1)) + { + i2cerr("ERROR: Trace table overflow\n"); + return; + } + + priv->tndx++; + trace = &priv->trace[priv->tndx]; + } + + /* Initialize the new trace entry */ + + imxrt_lpi2c_traceclear(priv); + trace->status = status; + trace->count = 1; + trace->time = clock_systime_ticks(); + } + else + { + /* Just increment the count of times that we have seen this status */ + + trace->count++; + } +} + +static void imxrt_lpi2c_traceevent(FAR struct imxrt_lpi2c_priv_s *priv, + enum imxrt_trace_e event, uint32_t parm) +{ + struct imxrt_trace_s *trace; + + if (event != I2CEVENT_NONE) + { + trace = &priv->trace[priv->tndx]; + + /* Initialize the new trace entry */ + + trace->event = event; + trace->parm = parm; + + /* Bump up the trace index (unless we are out of trace entries) */ + + if (priv->tndx >= (CONFIG_I2C_NTRACE - 1)) + { + i2cerr("ERROR: Trace table overflow\n"); + return; + } + + priv->tndx++; + imxrt_lpi2c_traceclear(priv); + } +} + +static void imxrt_lpi2c_tracedump(FAR struct imxrt_lpi2c_priv_s *priv) +{ + struct imxrt_trace_s *trace; + int i; + + syslog(LOG_DEBUG, "Elapsed time: %ld\n", + (long)(clock_systime_ticks() - priv->start_time)); + + for (i = 0; i < priv->tndx; i++) + { + trace = &priv->trace[i]; + syslog(LOG_DEBUG, + "%2d. STATUS: %08x COUNT: %3d EVENT: %s(%2d) PARM: %08x " + "TIME: %d\n", + i + 1, trace->status, trace->count, + g_trace_names[trace->event], + trace->event, trace->parm, trace->time - priv->start_time); + } +} +#endif /* CONFIG_I2C_TRACE */ + +/**************************************************************************** + * Name: imxrt_lpi2c_setclock + * + * Description: + * Set the I2C clock + * + ****************************************************************************/ + +static void imxrt_lpi2c_setclock(FAR struct imxrt_lpi2c_priv_s *priv, + uint32_t frequency) +{ + uint32_t src_freq = 0; + uint32_t pll3_div = 0; + uint32_t lpi2c_clk_div; + uint32_t regval; + uint32_t men; + uint32_t prescale = 0; + uint32_t best_prescale = 0; + uint32_t best_clk_hi = 0; + uint32_t abs_error = 0; + uint32_t best_error = 0xffffffff; + uint32_t clk_hi_cycle; + uint32_t computed_rate; + uint32_t count; + + /* Has the I2C bus frequency changed? */ + + if (priv->config->mode == LPI2C_MASTER) + { + if (frequency != priv->frequency) + { + /* Disable the selected LPI2C peripheral to configure the new + * clock if it is enabled. + */ + + men = imxrt_lpi2c_getreg(priv, IMXRT_LPI2C_MCR_OFFSET) & + LPI2C_MCR_MEN; + if (men) + { + imxrt_lpi2c_modifyreg(priv, IMXRT_LPI2C_MCR_OFFSET, + LPI2C_MCR_MEN, 0); + } + + /* Get the LPI2C clock source frequency */ + + if ((getreg32(IMXRT_CCM_CSCDR2) & CCM_CSCDR2_LPI2C_CLK_SEL) == + CCM_CSCDR2_LPI2C_CLK_SEL_OSC_CLK) + { + src_freq = BOARD_XTAL_FREQUENCY; + } + else + { + if ((getreg32(IMXRT_CCM_ANALOG_PLL_USB2) & + CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK) != 0) + { + pll3_div = 22; + } + else + { + pll3_div = 20; + } + + lpi2c_clk_div = (getreg32(IMXRT_CCM_CSCDR2) & + CCM_CSCDR2_LPI2C_CLK_PODF_MASK) >> + CCM_CSCDR2_LPI2C_CLK_PODF_SHIFT; + lpi2c_clk_div = lpi2c_clk_div + 1; + src_freq = (BOARD_XTAL_FREQUENCY * pll3_div) / + (8 * lpi2c_clk_div) ; + } + + /* LPI2C output frequency = (Source Clock (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) && (best_error != 0); + prescale *= 2) + { + for (clk_hi_cycle = 1; clk_hi_cycle < 32; clk_hi_cycle++) + { + if (clk_hi_cycle == 1) + { + computed_rate = (src_freq / prescale) / + (6 + (2 / prescale)); + } + else + { + computed_rate = (src_freq / prescale) / + ((3 * clk_hi_cycle + 2) + + (2 / prescale)); + } + + if (frequency > computed_rate) + { + abs_error = frequency - computed_rate; + } + else + { + abs_error = computed_rate - frequency; + } + + if (abs_error < best_error) + { + best_prescale = prescale; + best_clk_hi = clk_hi_cycle; + best_error = abs_error; + + if (abs_error == 0) + { + break; + } + } + } + } + + regval = LPI2C_MCCR0_CLKHI(best_clk_hi); + + if (best_clk_hi < 2) + { + regval |= LPI2C_MCCR0_CLKLO(3) | LPI2C_MCCR0_SETHOLD(2) | + LPI2C_MCCR0_DATAVD(1); + } + else + { + regval |= LPI2C_MCCR0_CLKLO(2 * best_clk_hi) | + LPI2C_MCCR0_SETHOLD(best_clk_hi) | + LPI2C_MCCR0_DATAVD(best_clk_hi / 2); + } + + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MCCR0_OFFSET, regval); + + for (count = 0; count < 8; count++) + { + if (best_prescale == (1 << count)) + { + best_prescale = count; + break; + } + } + + imxrt_lpi2c_modifyreg(priv, IMXRT_LPI2C_MCFGR1_OFFSET, + LPI2C_MCFGR1_PRESCALE_MASK, + LPI2C_MCFGR1_PRESCALE(best_prescale)); + + /* Re-enable LPI2C if it was enabled previously */ + + if (men) + { + imxrt_lpi2c_modifyreg(priv, IMXRT_LPI2C_MCR_OFFSET, 0, + LPI2C_MCR_MEN); + } + + /* Save the new LPI2C frequency */ + + priv->frequency = frequency; + } + } +} + +/**************************************************************************** + * Name: imxrt_lpi2c_sendstart + * + * Description: + * Send the START conditions/force Master mode + * + ****************************************************************************/ + +static inline void imxrt_lpi2c_sendstart(FAR struct imxrt_lpi2c_priv_s *priv, + uint8_t address) +{ + uint32_t txcount = 0; + uint32_t status = 0; + uint8_t addr; + + /* Generate START condition and send the address */ + + /* Turn off auto_stop option */ + + imxrt_lpi2c_modifyreg(priv, IMXRT_LPI2C_MCFGR1_OFFSET, + LPI2C_MCFGR1_IGNACK, 0); + + do + { + txcount = (imxrt_lpi2c_getreg(priv, IMXRT_LPI2C_MFSR_OFFSET) & + LPI2C_MFSR_TXCOUNT_MASK) >> LPI2C_MFSR_TXCOUNT_SHIFT; + txcount = 4 - txcount; + + status = imxrt_lpi2c_getreg(priv, IMXRT_LPI2C_MSR_OFFSET); + + if (status & LPI2C_MSR_ERROR_MASK) + { + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MSR_OFFSET, + status & LPI2C_MSR_ERROR_MASK); + } + } + while (txcount == 0); + + if ((priv->flags & I2C_M_READ) != 0) + { + addr = I2C_READADDR8(address); + } + else + { + addr = I2C_WRITEADDR8(address); + } + + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MTDR_OFFSET, + (LPI2C_MTDR_CMD_START | LPI2C_MTDR_DATA(addr))); +} + +/**************************************************************************** + * Name: imxrt_lpi2c_sendstop + * + * Description: + * Send the STOP conditions + * + ****************************************************************************/ + +static inline void imxrt_lpi2c_sendstop(FAR struct imxrt_lpi2c_priv_s *priv) +{ + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MTDR_OFFSET, LPI2C_MTDR_CMD_STOP); +} + +/**************************************************************************** + * Name: imxrt_lpi2c_getstatus + * + * Description: + * Get 32-bit status + * + ****************************************************************************/ + +static inline uint32_t + imxrt_lpi2c_getstatus(FAR struct imxrt_lpi2c_priv_s *priv) +{ + return imxrt_lpi2c_getreg(priv, IMXRT_LPI2C_MSR_OFFSET); +} + +/**************************************************************************** + * Name: imxrt_lpi2c_isr_process + * + * Description: + * Common Interrupt Service Routine + * + ****************************************************************************/ + +static int imxrt_lpi2c_isr_process(struct imxrt_lpi2c_priv_s *priv) +{ + uint32_t status = imxrt_lpi2c_getstatus(priv); + + /* Check for new trace setup */ + + imxrt_lpi2c_tracenew(priv, status); + + /* After an error we can get an SDF */ + + if (priv->intstate == INTSTATE_DONE && (status & LPI2C_MSR_SDF) != 0) + { + imxrt_lpi2c_traceevent(priv, I2CEVENT_STOP, 0); + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MSR_OFFSET, LPI2C_MSR_SDF); + } + + /* Check if there is more bytes to send */ + + else if (((priv->flags & I2C_M_READ) == 0) && + (status & LPI2C_MSR_TDF) != 0) + { + if (priv->dcnt > 0) + { + imxrt_lpi2c_traceevent(priv, I2CEVENT_SENDBYTE, priv->dcnt); + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MTDR_OFFSET, + LPI2C_MTDR_CMD_TXD | + LPI2C_MTDR_DATA(*priv->ptr++)); + priv->dcnt--; + + if ((priv->msgc <= 0) && (priv->dcnt == 0)) + { + imxrt_lpi2c_sendstop(priv); + } + } + } + + /* Check if there is more bytes to read */ + + else if (((priv->flags & I2C_M_READ) != 0) && + (status & LPI2C_MSR_RDF) != 0) + { + /* Read a byte, if dcnt goes < 0, then read dummy bytes to ack ISRs */ + + if (priv->dcnt > 0) + { + imxrt_lpi2c_traceevent(priv, I2CEVENT_RCVBYTE, priv->dcnt); + + /* No interrupts or context switches should occur in the following + * sequence. Otherwise, additional bytes may be sent by the device. + */ + +#ifdef CONFIG_I2C_POLLED + irqstate_t flags = enter_critical_section(); +#endif + + /* Receive a byte */ + + *priv->ptr++ = imxrt_lpi2c_getreg(priv, IMXRT_LPI2C_MRDR_OFFSET) & + LPI2C_MRDR_DATA_MASK; + priv->dcnt--; + +#ifdef CONFIG_I2C_POLLED + leave_critical_section(flags); +#endif + if ((priv->msgc <= 0) && (priv->dcnt == 0)) + { + imxrt_lpi2c_sendstop(priv); + } + } + else + { + imxrt_lpi2c_getreg(priv, IMXRT_LPI2C_MRDR_OFFSET); + } + } + + if (priv->dcnt <= 0) + { + if (priv->msgc > 0 && priv->msgv != NULL) + { + priv->ptr = priv->msgv->buffer; + priv->dcnt = priv->msgv->length; + priv->flags = priv->msgv->flags; + + if ((priv->msgv->flags & I2C_M_NOSTART) == 0) + { + imxrt_lpi2c_traceevent(priv, I2CEVENT_STARTRESTART, + priv->msgc); + imxrt_lpi2c_sendstart(priv, priv->msgv->addr); + } + else + { + imxrt_lpi2c_traceevent(priv, I2CEVENT_NOSTART, priv->msgc); + } + + priv->msgv++; + priv->msgc--; + + if ((priv->flags & I2C_M_READ) != 0) + { +#ifndef CONFIG_I2C_POLLED + /* Stop TX interrupt */ + + imxrt_lpi2c_modifyreg(priv, IMXRT_LPI2C_MIER_OFFSET, + LPI2C_MIER_TDIE, LPI2C_MIER_RDIE); +#endif + /* Set LPI2C in read mode */ + + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MTDR_OFFSET, + LPI2C_MTDR_CMD_RXD | + LPI2C_MTDR_DATA((priv->dcnt - 1))); + } + else + { + /* Send the first byte from tx buffer */ + + imxrt_lpi2c_traceevent(priv, I2CEVENT_SENDBYTE, priv->dcnt); + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MTDR_OFFSET, + LPI2C_MTDR_CMD_TXD | + LPI2C_MTDR_DATA(*priv->ptr++)); + priv->dcnt--; + if ((priv->msgc <= 0) && (priv->dcnt == 0)) + { + imxrt_lpi2c_sendstop(priv); + } + } + } + else if (priv->msgv && ((status & LPI2C_MSR_SDF) != 0)) + { + imxrt_lpi2c_traceevent(priv, I2CEVENT_STOP, 0); + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MSR_OFFSET, LPI2C_MSR_SDF); + + /* Check is there thread waiting for this event (there should be) */ + +#ifndef CONFIG_I2C_POLLED + if (priv->intstate == INTSTATE_WAITING) + { + /* Update Status once at the end */ + + priv->status = status; + + /* inform the thread that transfer is complete + * and wake it up + */ + + nxsem_post(&priv->sem_isr); + priv->intstate = INTSTATE_DONE; + } +#else + priv->status = status; + priv->intstate = INTSTATE_DONE; +#endif + /* Mark that this transaction stopped */ + + priv->msgv = NULL; + } +#ifndef CONFIG_I2C_POLLED + else + { + imxrt_lpi2c_modifyreg(priv, IMXRT_LPI2C_MIER_OFFSET, + LPI2C_MIER_TDIE | LPI2C_MIER_RDIE, 0); + } +#endif + } + + /* Check for errors */ + + if ((status & LPI2C_MSR_EPF) != 0) + { + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MSR_OFFSET, LPI2C_MSR_EPF); + } + + if ((status & LPI2C_MSR_ERROR_MASK) != 0) + { + imxrt_lpi2c_traceevent(priv, I2CEVENT_ERROR, 0); + + /* Clear the TX and RX FIFOs */ + + imxrt_lpi2c_modifyreg(priv, IMXRT_LPI2C_MCR_OFFSET, 0, + LPI2C_MCR_RTF | LPI2C_MCR_RRF); + + /* Clear the error */ + + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MSR_OFFSET, + (status & (LPI2C_MSR_NDF | LPI2C_MSR_ALF | + LPI2C_MSR_FEF))); + +#ifndef CONFIG_I2C_POLLED + if (priv->intstate == INTSTATE_WAITING) + { + /* Update Status once at the end */ + + priv->status = status; + + /* inform the thread that transfer is complete + * and wake it up + */ + + nxsem_post(&priv->sem_isr); + priv->intstate = INTSTATE_DONE; + } +#else + priv->status = status; + priv->intstate = INTSTATE_DONE; +#endif + } + + return OK; +} + +/**************************************************************************** + * Name: imxrt_lpi2c_isr + * + * Description: + * Common I2C interrupt service routine + * + ****************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static int imxrt_lpi2c_isr(int irq, void *context, FAR void *arg) +{ + struct imxrt_lpi2c_priv_s *priv = (struct imxrt_lpi2c_priv_s *)arg; + + DEBUGASSERT(priv != NULL); + return imxrt_lpi2c_isr_process(priv); +} +#endif + +/**************************************************************************** + * Name: imxrt_lpi2c_clock_enable + * + * Description: + * Ungate LPI2C clock + * + ****************************************************************************/ + +void imxrt_lpi2c_clock_enable (uint32_t base) +{ + if (base == IMXRT_LPI2C1_BASE) + { + imxrt_clockall_lpi2c1(); + } + else if (base == IMXRT_LPI2C2_BASE) + { + imxrt_clockall_lpi2c2(); + } + else if (base == IMXRT_LPI2C3_BASE) + { + imxrt_clockall_lpi2c3(); + } + else if (base == IMXRT_LPI2C4_BASE) + { + imxrt_clockall_lpi2c4_serial(); + } +} + +/**************************************************************************** + * Name: imxrt_lpi2c_clock_disable + * + * Description: + * Gate LPI2C clock + * + ****************************************************************************/ + +void imxrt_lpi2c_clock_disable (uint32_t base) +{ + if (base == IMXRT_LPI2C1_BASE) + { + imxrt_clockoff_lpi2c1(); + } + else if (base == IMXRT_LPI2C2_BASE) + { + imxrt_clockoff_lpi2c2(); + } + else if (base == IMXRT_LPI2C3_BASE) + { + imxrt_clockoff_lpi2c3(); + } + else if (base == IMXRT_LPI2C4_BASE) + { + imxrt_clockoff_lpi2c4_serial(); + } +} + +/**************************************************************************** + * Name: imxrt_lpi2c_init + * + * Description: + * Setup the I2C hardware, ready for operation with defaults + * + ****************************************************************************/ + +static int imxrt_lpi2c_init(FAR struct imxrt_lpi2c_priv_s *priv) +{ + /* Power-up and configure GPIOs */ + + /* Configure pins */ + + imxrt_config_gpio(priv->config->scl_pin); + imxrt_config_gpio(priv->config->sda_pin); + + /* Enable power and reset the peripheral */ + + imxrt_lpi2c_clock_enable(priv->config->base); + + /* Reset LPI2C before configuring it */ + + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MCR_OFFSET, LPI2C_MCR_RST); + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MCR_OFFSET, 0); + + /* Disable doze mode (Set DOZEN bit in 1 to disable) */ + + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MCR_OFFSET, LPI2C_MCR_DOZEN); + + /* Disable host request */ + + imxrt_lpi2c_modifyreg(priv, IMXRT_LPI2C_MCFGR0_OFFSET, + LPI2C_MCFG0_HREN | LPI2C_MCFG0_HRSEL, + LPI2C_MCFG0_HRPOL); + + /* Pin config and ignore NACK disable */ + + imxrt_lpi2c_modifyreg(priv, IMXRT_LPI2C_MCFGR1_OFFSET, + LPI2C_MCFGR1_IGNACK | LPI2C_MCFGR1_PINCFG_MASK, 0); + + /* Set tx and rx watermarks */ + + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MFCR_OFFSET, + LPI2C_MFCR_TXWATER(0) | LPI2C_MFCR_RXWATER(0)); + + /* Force a frequency update */ + + priv->frequency = 0; + imxrt_lpi2c_setclock(priv, 100000); + + /* Set scl, sda glitch filters and busy idle */ + + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MCFGR2_OFFSET, + LPI2C_MCFG2_BUSIDLE(priv->config->busy_idle) | + LPI2C_MCFG2_FILTSCL_CYCLES(priv->config->filtscl) | + LPI2C_MCFG2_FILTSDA_CYCLES(priv->config->filtsda)); + + /* Set pin low cycles to 0 (disable) */ + + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MCFGR3_OFFSET, + LPI2C_MCFG3_PINLOW_CYCLES(0)); + + /* Attach ISRs */ + +#ifndef CONFIG_I2C_POLLED + irq_attach(priv->config->irq, imxrt_lpi2c_isr, priv); + up_enable_irq(priv->config->irq); +#endif + + /* Enable I2C */ + + imxrt_lpi2c_modifyreg(priv, IMXRT_LPI2C_MCR_OFFSET, 0, LPI2C_MCR_MEN); + return OK; +} + +/**************************************************************************** + * Name: imxrt_lpi2c_deinit + * + * Description: + * Shutdown the I2C hardware + * + ****************************************************************************/ + +static int imxrt_lpi2c_deinit(FAR struct imxrt_lpi2c_priv_s *priv) +{ + /* Disable I2C */ + + imxrt_lpi2c_modifyreg(priv, IMXRT_LPI2C_MCR_OFFSET, LPI2C_MCR_MEN, 0); + + /* Reset LPI2C */ + + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MCR_OFFSET, LPI2C_MCR_RST); + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MCR_OFFSET, 0); + + /* Disable and detach interrupts */ + +#ifndef CONFIG_I2C_POLLED + up_disable_irq(priv->config->irq); + irq_detach(priv->config->irq); +#endif + + /* Disable clocking */ + + imxrt_lpi2c_clock_disable(priv->config->base); + + return OK; +} + +/**************************************************************************** + * Device Driver Operations + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_lpi2c_transfer + * + * Description: + * Generic I2C transfer function + * + ****************************************************************************/ + +static int imxrt_lpi2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + FAR struct imxrt_lpi2c_priv_s *priv = (struct imxrt_lpi2c_priv_s *)dev; + int ret; + + DEBUGASSERT(count > 0); + + /* Ensure that address or flags don't change meanwhile */ + + ret = imxrt_lpi2c_sem_wait(priv); + if (ret < 0) + { + return ret; + } + + /* Clear any pending error interrupts */ + + imxrt_lpi2c_putreg(priv, IMXRT_LPI2C_MSR_OFFSET, 0xffffffff); + + /* Old transfers are done */ + + /* Reset ptr and dcnt to ensure an unexpected data interrupt doesn't + * overwrite stale data. + */ + + priv->dcnt = 0; + priv->ptr = NULL; + + priv->msgv = msgs; + priv->msgc = count; + priv->flags = msgs->flags; + + i2cinfo("Flags %x, len %d \n", msgs->flags, msgs->length); + + /* Reset I2C trace logic */ + + imxrt_lpi2c_tracereset(priv); + + /* Set I2C clock frequency */ + + imxrt_lpi2c_setclock(priv, msgs->frequency); + + priv->status = 0; + + /* Wait for an ISR, if there was a timeout, fetch latest status to get + * the BUSY flag. + */ + + if (imxrt_lpi2c_sem_waitdone(priv) < 0) + { + ret = -ETIMEDOUT; + + i2cerr("ERROR: Timed out: MCR: status: 0x%" PRIx32 "\n", priv->status); + } + + /* Check for error status conditions */ + + else if ((priv->status & LPI2C_MSR_ERROR_MASK) != 0) + { + /* I2C_SR1_ERRORMASK is the 'OR' of the following individual bits: */ + + if (priv->status & LPI2C_MSR_ALF) + { + /* Arbitration Lost (master mode) */ + + i2cerr("Arbitration lost\n"); + ret = -EAGAIN; + } + else if (priv->status & LPI2C_MSR_NDF) + { + /* Acknowledge Failure */ + + i2cerr("Ack failure\n"); + ret = -ENXIO; + } + else + { + /* FIFO Error */ + + i2cerr("Transfer without start condition\n"); + ret = -EINVAL; + } + } + + /* Dump the trace result */ + + imxrt_lpi2c_tracedump(priv); + + /* Ensure that any ISR happening after we finish can't overwrite any user + * data. + */ + + priv->dcnt = 0; + priv->ptr = NULL; + + imxrt_lpi2c_sem_post(priv); + return ret; +} + +/**************************************************************************** + * Name: imxrt_lpi2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int imxrt_lpi2c_reset(FAR struct i2c_master_s *dev) +{ + FAR struct imxrt_lpi2c_priv_s *priv = (FAR struct imxrt_lpi2c_priv_s *)dev; + unsigned int clock_count; + unsigned int stretch_count; + uint32_t scl_gpio; + uint32_t sda_gpio; + uint32_t frequency; + int ret; + + DEBUGASSERT(dev); + + /* Our caller must own a ref */ + + DEBUGASSERT(priv->refs > 0); + + /* Lock out other clients */ + + ret = imxrt_lpi2c_sem_wait_noncancelable(priv); + if (ret < 0) + { + return ret; + } + + ret = -EIO; + + /* Save the current frequency */ + + frequency = priv->frequency; + + /* De-init the port */ + + imxrt_lpi2c_deinit(priv); + + /* Use GPIO configuration to un-wedge the bus */ + + scl_gpio = priv->config->reset_scl_pin | GPIO_SION_ENABLE; + sda_gpio = priv->config->reset_sda_pin | GPIO_SION_ENABLE; + + imxrt_config_gpio(scl_gpio); + imxrt_config_gpio(sda_gpio); + + /* Let SDA go high */ + + imxrt_gpio_write(sda_gpio, 1); + + /* Clock the bus until any slaves currently driving it let it go. */ + + clock_count = 0; + while (!imxrt_gpio_read(sda_gpio)) + { + /* Give up if we have tried too hard */ + + if (clock_count++ > 10) + { + goto out; + } + + /* Sniff to make sure that clock stretching has finished. + * + * If the bus never relaxes, the reset has failed. + */ + + stretch_count = 0; + while (!imxrt_gpio_read(scl_gpio)) + { + /* Give up if we have tried too hard */ + + if (stretch_count++ > 10) + { + goto out; + } + + up_udelay(10); + } + + /* Drive SCL low */ + + imxrt_gpio_write(scl_gpio, 0); + up_udelay(10); + + /* Drive SCL high again */ + + imxrt_gpio_write(scl_gpio, 1); + up_udelay(10); + } + + /* Generate a start followed by a stop to reset slave + * state machines. + */ + + imxrt_gpio_write(sda_gpio, 0); + up_udelay(10); + imxrt_gpio_write(scl_gpio, 0); + up_udelay(10); + imxrt_gpio_write(scl_gpio, 1); + up_udelay(10); + imxrt_gpio_write(sda_gpio, 1); + up_udelay(10); + + imxrt_config_gpio(sda_gpio); + imxrt_config_gpio(scl_gpio); + + /* Re-init the port */ + + imxrt_lpi2c_init(priv); + + /* Restore the frequency */ + + imxrt_lpi2c_setclock(priv, frequency); + ret = OK; + +out: + + /* Release the port for re-use by other clients */ + + imxrt_lpi2c_sem_post(priv); + return ret; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_i2cbus_initialize + * + * Description: + * Initialize one I2C bus + * + ****************************************************************************/ + +FAR struct i2c_master_s *imxrt_i2cbus_initialize(int port) +{ + struct imxrt_lpi2c_priv_s * priv = NULL; + irqstate_t flags; + + /* Get I2C private structure */ + + switch (port) + { +#ifdef CONFIG_IMXRT_LPI2C1 + case 1: + priv = (struct imxrt_lpi2c_priv_s *)&imxrt_lpi2c1_priv; + break; +#endif +#ifdef CONFIG_IMXRT_LPI2C2 + case 2: + priv = (struct imxrt_lpi2c_priv_s *)&imxrt_lpi2c2_priv; + break; +#endif +#ifdef CONFIG_IMXRT_LPI2C3 + case 3: + priv = (struct imxrt_lpi2c_priv_s *)&imxrt_lpi2c3_priv; + break; +#endif +#ifdef CONFIG_IMXRT_LPI2C4 + case 4: + priv = (struct imxrt_lpi2c_priv_s *)&imxrt_lpi2c4_priv; + break; +#endif + default: + return NULL; + } + + /* Initialize private data for the first time, increment reference count, + * power-up hardware and configure GPIOs. + */ + + flags = enter_critical_section(); + + if ((volatile int)priv->refs++ == 0) + { + imxrt_lpi2c_sem_init(priv); + imxrt_lpi2c_init(priv); + } + + leave_critical_section(flags); + + return (struct i2c_master_s *)priv; +} + +/**************************************************************************** + * Name: imxrt_i2cbus_uninitialize + * + * Description: + * Uninitialize an I2C bus + * + ****************************************************************************/ + +int imxrt_i2cbus_uninitialize(FAR struct i2c_master_s *dev) +{ + FAR struct imxrt_lpi2c_priv_s *priv = (struct imxrt_lpi2c_priv_s *)dev; + irqstate_t flags; + + DEBUGASSERT(dev); + + /* Decrement reference count and check for underflow */ + + if (priv->refs == 0) + { + return ERROR; + } + + flags = enter_critical_section(); + + if (--priv->refs > 0) + { + leave_critical_section(flags); + return OK; + } + + leave_critical_section(flags); + + /* Disable power and other HW resource (GPIO's) */ + + imxrt_lpi2c_deinit(priv); + + /* Release unused resources */ + + imxrt_lpi2c_sem_destroy(priv); + return OK; +} + +#endif /* CONFIG_IMXRT_LPI2C1 || CONFIG_IMXRT_LPI2C2 || \ + * CONFIG_IMXRT_LPI2C3 || CONFIG_IMXRT_LPI2C4 */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_lpspi.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_lpspi.c new file mode 100644 index 000000000..3abe7d9d2 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_lpspi.c @@ -0,0 +1,1706 @@ +/**************************************************************************** + * arch/arm/src/imxrt/imxrt_lpspi.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. + * + ****************************************************************************/ + +/**************************************************************************** + * The external functions, imxrt_lpspi1/2/3/4select and + * imxrt_lpspi1/2/3/4status must be provided by board-specific logic. + * They are implementations of the select and status methods of the SPI + * interface defined by struct imxrt_lpspi_ops_s (see + * include/nuttx/spi/spi.h). All other methods (including + * imxrt_lpspibus_initialize()) are provided by common IMXRT logic. + * To use this common SPI logic on your board: + * + * 1. Provide logic in imxrt_boardinitialize() to configure SPI chip + * select pins. + * 2. Provide imxrt_lpspi1/2/3/4select() and imxrt_lpspi1/2/3/4status() + * functions in your board-specific logic. These functions will + * perform chip selection and status operations using GPIOs in the way + * your board is configured. + * 3. Add a calls to imxrt_lpspibus_initialize() in your low level + * application initialization logic + * 4. The handle returned by imxrt_lpspibus_initialize() may then be + * used to bind the SPI driver to higher level logic (e.g., calling + * mmcsd_lpspislotinitialize(), for example, will bind the SPI + * driver to the SPI MMC/SD driver). + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "arm_internal.h" +#include "arm_arch.h" + +#include "chip.h" + +#include "imxrt_lpspi.h" +#include "imxrt_gpio.h" +#include "hardware/imxrt_pinmux.h" +#include "hardware/imxrt_lpspi.h" +#include "hardware/imxrt_ccm.h" +#include "imxrt_periphclks.h" + +#if defined(CONFIG_IMXRT_LPSPI1) || defined(CONFIG_IMXRT_LPSPI2) || \ + defined(CONFIG_IMXRT_LPSPI3) || defined(CONFIG_IMXRT_LPSPI4) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* SPI interrupts */ + +#ifdef CONFIG_IMXRT_LPSPI_INTERRUPTS +# error "Interrupt driven SPI not yet supported" +#endif + +#if defined(CONFIG_IMXRT_LPSPI_DMA) +# error "DMA mode is not yet supported" +#endif + +/* Can't have both interrupt driven SPI and SPI DMA */ + +#if defined(CONFIG_IMXRT_LPSPI_INTERRUPTS) && defined(CONFIG_IMXRT_LPSPI_DMA) +# error "Cannot enable both interrupt mode and DMA mode for SPI" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct imxrt_lpspidev_s +{ + struct spi_dev_s spidev; /* Externally visible part of the SPI interface */ + uint32_t spibase; /* SPIn base address */ +#ifdef CONFIG_IMXRT_LPSPI_INTERRUPTS + uint8_t spiirq; /* SPI IRQ number */ +#endif + sem_t exclsem; /* Held while chip is selected for mutual exclusion */ + uint32_t frequency; /* Requested clock frequency */ + uint32_t actual; /* Actual clock frequency */ + int8_t nbits; /* Width of word in bits */ + uint8_t mode; /* Mode 0,1,2,3 */ +}; + +enum imxrt_delay_e +{ + LPSPI_PCS_TO_SCK = 1, /* PCS-to-SCK delay. */ + LPSPI_LAST_SCK_TO_PCS, /* Last SCK edge to PCS delay. */ + LPSPI_BETWEEN_TRANSFER /* Delay between transfers. */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Helpers */ + +static inline uint32_t +imxrt_lpspi_getreg32(FAR struct imxrt_lpspidev_s *priv, + uint8_t offset); +static inline void imxrt_lpspi_putreg32(FAR struct imxrt_lpspidev_s *priv, + uint8_t offset, uint32_t value); +static inline uint32_t imxrt_lpspi_readword( + FAR struct imxrt_lpspidev_s *priv); +static inline void imxrt_lpspi_writeword(FAR struct imxrt_lpspidev_s *priv, + uint16_t byte); +static inline bool imxrt_lpspi_9to16bitmode( + FAR struct imxrt_lpspidev_s *priv); +static inline void imxrt_lpspi_master_set_delays(FAR struct imxrt_lpspidev_s + *priv, uint32_t delay_ns, + enum imxrt_delay_e type); +static inline void imxrt_lpspi_master_set_delay_scaler( + FAR struct imxrt_lpspidev_s *priv, + uint32_t scaler, + enum imxrt_delay_e type); + +/* SPI methods */ + +static int imxrt_lpspi_lock(FAR struct spi_dev_s *dev, bool lock); +static uint32_t imxrt_lpspi_setfrequency(FAR struct spi_dev_s *dev, + uint32_t frequency); +static void imxrt_lpspi_setmode(FAR struct spi_dev_s *dev, + enum spi_mode_e mode); +static void imxrt_lpspi_setbits(FAR struct spi_dev_s *dev, int nbits); +#ifdef CONFIG_SPI_HWFEATURES +static int imxrt_lpspi_hwfeatures(FAR struct spi_dev_s *dev, + imxrt_lpspi_hwfeatures_t features); +#endif +static uint32_t imxrt_lpspi_send(FAR struct spi_dev_s *dev, uint32_t wd); +static void imxrt_lpspi_exchange(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, + FAR void *rxbuffer, + size_t nwords); +#ifndef CONFIG_SPI_EXCHANGE +static void imxrt_lpspi_sndblock(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, size_t nwords); +static void imxrt_lpspi_recvblock(FAR struct spi_dev_s *dev, + FAR void *rxbuffer, + size_t nwords); +#endif + +/* Initialization */ + +static void imxrt_lpspi_bus_initialize(FAR struct imxrt_lpspidev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_LPSPI1 +static const struct spi_ops_s g_spi1ops = +{ + .lock = imxrt_lpspi_lock, + .select = imxrt_lpspi1select, + .setfrequency = imxrt_lpspi_setfrequency, + .setmode = imxrt_lpspi_setmode, + .setbits = imxrt_lpspi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = imxrt_lpspi_hwfeatures, +#endif + .status = imxrt_lpspi1status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = imxrt_lpspi1cmddata, +#endif + .send = imxrt_lpspi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = imxrt_lpspi_exchange, +#else + .sndblock = imxrt_lpspi_sndblock, + .recvblock = imxrt_lpspi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = imxrt_lpspi1register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct imxrt_lpspidev_s g_lpspi1dev = +{ + .spidev = + { + &g_spi1ops + }, + .spibase = IMXRT_LPSPI1_BASE, +#ifdef CONFIG_IMXRT_LPSPI_INTERRUPTS + .spiirq = IMXRT_IRQ_LPSPI1, +#endif +#ifdef CONFIG_IMXRT_LPSPI_DMA + .rxch = DMAMAP_LPSPI1_RX, + .txch = DMAMAP_LPSPI1_TX, +#endif +}; +#endif + +#ifdef CONFIG_IMXRT_LPSPI2 +static const struct spi_ops_s g_spi2ops = +{ + .lock = imxrt_lpspi_lock, + .select = imxrt_lpspi2select, + .setfrequency = imxrt_lpspi_setfrequency, + .setmode = imxrt_lpspi_setmode, + .setbits = imxrt_lpspi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = imxrt_lpspi_hwfeatures, +#endif + .status = imxrt_lpspi2status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = imxrt_lpspi2cmddata, +#endif + .send = imxrt_lpspi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = imxrt_lpspi_exchange, +#else + .sndblock = imxrt_lpspi_sndblock, + .recvblock = imxrt_lpspi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = imxrt_lpspi2register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct imxrt_lpspidev_s g_lpspi2dev = +{ + .spidev = + { + &g_spi2ops + }, + .spibase = IMXRT_LPSPI2_BASE, +#ifdef CONFIG_IMXRT_LPSPI_INTERRUPTS + .spiirq = IMXRT_IRQ_LPSPI2, +#endif +#ifdef CONFIG_IMXRT_LPSPI_DMA + .rxch = DMAMAP_LPSPI2_RX, + .txch = DMAMAP_LPSPI2_TX, +#endif +}; +#endif + +#ifdef CONFIG_IMXRT_LPSPI3 +static const struct spi_ops_s g_spi3ops = +{ + .lock = imxrt_lpspi_lock, + .select = imxrt_lpspi3select, + .setfrequency = imxrt_lpspi_setfrequency, + .setmode = imxrt_lpspi_setmode, + .setbits = imxrt_lpspi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = imxrt_lpspi_hwfeatures, +#endif + .status = imxrt_lpspi3status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = imxrt_lpspi3cmddata, +#endif + .send = imxrt_lpspi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = imxrt_lpspi_exchange, +#else + .sndblock = imxrt_lpspi_sndblock, + .recvblock = imxrt_lpspi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = imxrt_lpspi3register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct imxrt_lpspidev_s g_lpspi3dev = +{ + .spidev = + { + &g_spi3ops + }, + .spibase = IMXRT_LPSPI3_BASE, +#ifdef CONFIG_IMXRT_LPSPI_INTERRUPTS + .spiirq = IMXRT_IRQ_LPSPI3, +#endif +#ifdef CONFIG_IMXRT_LPSPI_DMA + .rxch = DMAMAP_LPSPI3_RX, + .txch = DMAMAP_LPSPI3_TX, +#endif +}; +#endif + +#ifdef CONFIG_IMXRT_LPSPI4 +static const struct spi_ops_s g_spi4ops = +{ + .lock = imxrt_lpspi_lock, + .select = imxrt_lpspi4select, + .setfrequency = imxrt_lpspi_setfrequency, + .setmode = imxrt_lpspi_setmode, + .setbits = imxrt_lpspi_setbits, +#ifdef CONFIG_SPI_HWFEATURES + .hwfeatures = imxrt_lpspi_hwfeatures, +#endif + .status = imxrt_lpspi4status, +#ifdef CONFIG_SPI_CMDDATA + .cmddata = imxrt_lpspi4cmddata, +#endif + .send = imxrt_lpspi_send, +#ifdef CONFIG_SPI_EXCHANGE + .exchange = imxrt_lpspi_exchange, +#else + .sndblock = imxrt_lpspi_sndblock, + .recvblock = imxrt_lpspi_recvblock, +#endif +#ifdef CONFIG_SPI_CALLBACK + .registercallback = imxrt_lpspi4register, /* Provided externally */ +#else + .registercallback = 0, /* Not implemented */ +#endif +}; + +static struct imxrt_lpspidev_s g_lpspi4dev = +{ + .spidev = + { + &g_spi4ops + }, + .spibase = IMXRT_LPSPI4_BASE, +#ifdef CONFIG_IMXRT_LPSPI_INTERRUPTS + .spiirq = IMXRT_IRQ_LPSPI4, +#endif +#ifdef CONFIG_IMXRT_LPSPI_DMA + .rxch = DMAMAP_LPSPI4_RX, + .txch = DMAMAP_LPSPI4_TX, +#endif +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_lpspi_getreg8 + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 8-bit register + * + ****************************************************************************/ + +static inline uint8_t imxrt_lpspi_getreg8(FAR struct imxrt_lpspidev_s *priv, + uint8_t offset) +{ + return getreg8(priv->spibase + offset); +} + +/**************************************************************************** + * Name: imxrt_lpspi_putreg8 + * + * Description: + * Write a 8-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 8-bit value to be written + * + ****************************************************************************/ + +static inline void imxrt_lpspi_putreg8(FAR struct imxrt_lpspidev_s *priv, + uint8_t offset, uint8_t value) +{ + putreg8(value, priv->spibase + offset); +} + +/**************************************************************************** + * Name: imxrt_lpspi_getreg + * + * Description: + * Get the contents of the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * + * Returned Value: + * The contents of the 32-bit register + * + ****************************************************************************/ + +static inline uint32_t +imxrt_lpspi_getreg32(FAR struct imxrt_lpspidev_s *priv, + uint8_t offset) +{ + return getreg32(priv->spibase + offset); +} + +/**************************************************************************** + * Name: imxrt_lpspi_putreg + * + * Description: + * Write a 16-bit value to the SPI register at offset + * + * Input Parameters: + * priv - private SPI device structure + * offset - offset to the register of interest + * value - the 32-bit value to be written + * + * Returned Value: + * The contents of the 32-bit register + * + ****************************************************************************/ + +static inline void imxrt_lpspi_putreg32(FAR struct imxrt_lpspidev_s *priv, + uint8_t offset, uint32_t value) +{ + putreg32(value, priv->spibase + offset); +} + +/**************************************************************************** + * Name: imxrt_lpspi_readword + * + * Description: + * Read one word from SPI + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * word as read + * + ****************************************************************************/ + +static inline uint32_t +imxrt_lpspi_readword(FAR struct imxrt_lpspidev_s *priv) +{ + /* Wait until the receive buffer is not empty */ + + while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) + & LPSPI_SR_RDF) == 0); + + /* Then return the received byte */ + + return imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_RDR_OFFSET); +} + +/**************************************************************************** + * Name: imxrt_lpspi_writeword + * + * Description: + * Write one word to SPI + * + * Input Parameters: + * priv - Device-specific state data + * word - word to send + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void imxrt_lpspi_writeword(FAR struct imxrt_lpspidev_s *priv, + uint16_t word) +{ + /* Wait until the transmit buffer is empty */ + + while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) + & LPSPI_SR_TDF) == 0); + + /* Then send the word */ + + imxrt_lpspi_putreg32(priv, IMXRT_LPSPI_TDR_OFFSET, word); +} + +/**************************************************************************** + * Name: imxrt_lpspi_readbyte + * + * Description: + * Read one byte from SPI + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * Byte as read + * + ****************************************************************************/ + +static inline uint8_t imxrt_lpspi_readbyte(FAR struct imxrt_lpspidev_s *priv) +{ + /* Wait until the receive buffer is not empty */ + + while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) + & LPSPI_SR_RDF) == 0); + + /* Then return the received byte */ + + return imxrt_lpspi_getreg8(priv, IMXRT_LPSPI_RDR_OFFSET); +} + +/**************************************************************************** + * Name: imxrt_lpspi_writebyte + * + * Description: + * Write one 8-bit frame to the SPI FIFO + * + * Input Parameters: + * priv - Device-specific state data + * byte - Byte to send + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void imxrt_lpspi_writebyte(FAR struct imxrt_lpspidev_s *priv, + uint8_t byte) +{ + /* Wait until the transmit buffer is empty */ + + while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) + & LPSPI_SR_TDF) == 0); + + /* Then send the byte */ + + imxrt_lpspi_putreg8(priv, IMXRT_LPSPI_TDR_OFFSET, byte); +} + +/**************************************************************************** + * Name: imxrt_lpspi_9to16bitmode + * + * Description: + * Check if the SPI is operating in more then 8 bit mode + * + * Input Parameters: + * priv - Device-specific state data + * + * Returned Value: + * true: >8 bit mode-bit mode, false: <= 8-bit mode + * + ****************************************************************************/ + +static inline bool +imxrt_lpspi_9to16bitmode(FAR struct imxrt_lpspidev_s *priv) +{ + bool ret; + + if (((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_TCR_OFFSET) & + LPSPI_TCR_FRAMESZ_MASK) + 1) < 9) + { + ret = false; + } + else + { + ret = true; + } + + return ret; +} + +/**************************************************************************** + * Name: imxrt_lpspi_modifyreg + * + * Description: + * Clear and set bits in register + * + * Input Parameters: + * priv - Device-specific state data + * offset - Register offset + * clrbits - The bits to clear + * setbits - The bits to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void imxrt_lpspi_modifyreg32(FAR struct imxrt_lpspidev_s *priv, + uint8_t offset, uint32_t clrbits, + uint32_t setbits) +{ + modifyreg32(priv->spibase + offset, clrbits, setbits); +} + +/**************************************************************************** + * Name: imxrt_lpspi_master_set_delays + * + * Description: + * SET LPSPI Delay times + * + * Input Parameters: + * priv - Device-specific state data + * scaler - scaler value + * type - delay time type + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void imxrt_lpspi_master_set_delay_scaler( + FAR struct imxrt_lpspidev_s *priv, + uint32_t scaler, + enum imxrt_delay_e type) +{ + switch (type) + { + case LPSPI_PCS_TO_SCK: + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CCR_OFFSET, + LPSPI_CCR_PCSSCK_MASK, 0); + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CCR_OFFSET, 0, + LPSPI_CCR_PCSSCK(scaler)); + break; + + case LPSPI_LAST_SCK_TO_PCS: + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CCR_OFFSET, + LPSPI_CCR_SCKPCS_MASK, 0); + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CCR_OFFSET, 0, + LPSPI_CCR_SCKPCS(scaler)); + break; + + case LPSPI_BETWEEN_TRANSFER: + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CCR_OFFSET, + LPSPI_CCR_DBT_MASK, 0); + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CCR_OFFSET, 0, + LPSPI_CCR_DBT(scaler)); + break; + } +} + +/**************************************************************************** + * Name: imxrt_lpspi_master_set_delays + * + * Description: + * SET LPSPI Delay times + * + * Input Parameters: + * priv - Device-specific state data + * delay_ns - delay time in nano seconds + * type - delay time type + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void imxrt_lpspi_master_set_delays( + FAR struct imxrt_lpspidev_s *priv, + uint32_t delay_ns, + enum imxrt_delay_e type) +{ + uint32_t pll3_div; + uint32_t pll_freq; + uint32_t src_freq; + uint64_t real_delay; + uint64_t best_delay; + uint32_t scaler; + uint32_t best_scaler; + uint32_t diff; + uint32_t min_diff; + uint64_t initial_delay_ns; + uint32_t clock_div_prescaler; + uint32_t additional_scaler; + + if ((getreg32(IMXRT_CCM_ANALOG_PLL_USB2) & + CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK) != 0) + { + pll3_div = 22; + } + else + { + pll3_div = 20; + } + + pll_freq = BOARD_XTAL_FREQUENCY * pll3_div; + + /* Assumption this formula will work only if the LPSPI Clock Source is PLL3 + * PFD0 so check if LPSPI clock source is set to 1 (PLL3 PFD0) in CCM_CBCMR + * register bits 4-5 + */ + + src_freq = pll_freq / + ((getreg32(IMXRT_CCM_ANALOG_PFD_480) + & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> + CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT); + src_freq *= 18; + src_freq /= ((getreg32(IMXRT_CCM_CBCMR) & CCM_CBCMR_LPSPI_PODF_MASK) >> + CCM_CBCMR_LPSPI_PODF_SHIFT) + 1; + + clock_div_prescaler = src_freq / + (1 << ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_TCR_OFFSET) & + LPSPI_TCR_PRESCALE_MASK) >> LPSPI_TCR_PRESCALE_SHIFT)); + + min_diff = 0xffffffff; + + /* Initialize scaler to max value to generate the max delay */ + + best_scaler = 0xff; + + if (type == LPSPI_BETWEEN_TRANSFER) + { + /* First calculate the initial, default delay, note min delay is 2 + * clock cycles. Due to large size of * calculated values (uint64_t), + * we need to break up the calculation into several steps to ensure + * accurate calculated results + */ + + initial_delay_ns = 1000000000U; + initial_delay_ns *= 2; + initial_delay_ns /= clock_div_prescaler; + + /* Calculate the maximum delay */ + + best_delay = 1000000000U; + + /* based on DBT+2, or 255 + 2 */ + + best_delay *= 257; + best_delay /= clock_div_prescaler; + + additional_scaler = 1U; + } + else + { + /* First calculate the initial, default delay, min delay is 1 clock + * cycle. Due to large size of calculated values (uint64_t), we need to + * break up the calculation into several steps to ensure accurate + * calculated * results. + */ + + initial_delay_ns = 1000000000U; + initial_delay_ns /= clock_div_prescaler; + + /* Calculate the maximum delay */ + + best_delay = 1000000000U; + + /* Based on SCKPCS+1 or PCSSCK+1, or 255 + 1 */ + + best_delay *= 256; + best_delay /= clock_div_prescaler; + + additional_scaler = 0; + } + + /* If the initial, default delay is already greater than the desired delay, + * then * set the delay to their initial value (0) and return the delay. In + * other words, * there is no way to decrease the delay value further. + */ + + if (initial_delay_ns >= delay_ns) + { + imxrt_lpspi_master_set_delay_scaler(priv, 0, type); + } + else + { + /* If min_diff = 0, the exit for loop */ + + for (scaler = 0; (scaler < 256) && min_diff; scaler++) + { + /* Calculate the real delay value as we cycle through the scaler + * values. Due to large size of calculated values (uint64_t), + * we need to break up the calculation into several steps to + * ensure accurate calculated results + */ + + real_delay = 1000000000U; + real_delay *= (scaler + 1 + additional_scaler); + real_delay /= clock_div_prescaler; + + /* calculate the delay difference based on the conditional + * statement that states that the calculated delay must not be + * less then the desired delay + */ + + if (real_delay >= delay_ns) + { + diff = real_delay - delay_ns; + if (min_diff > diff) + { + /* A better match found */ + + min_diff = diff; + best_scaler = scaler; + best_delay = real_delay; + } + } + } + + imxrt_lpspi_master_set_delay_scaler(priv, best_scaler, type); + } +} + +/**************************************************************************** + * Name: imxrt_lpspi_lock + * + * Description: + * On SPI buses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI bus is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int imxrt_lpspi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + FAR struct imxrt_lpspidev_s *priv = (FAR struct imxrt_lpspidev_s *)dev; + int ret; + + if (lock) + { + ret = nxsem_wait_uninterruptible(&priv->exclsem); + } + else + { + ret = nxsem_post(&priv->exclsem); + } + + return ret; +} + +/**************************************************************************** + * Name: imxrt_lpspi_setfrequency + * + * Description: + * Set the SPI frequency. + * + * Input Parameters: + * dev - Device-specific state data + * frequency - The SPI frequency requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static uint32_t imxrt_lpspi_setfrequency(FAR struct spi_dev_s *dev, + uint32_t frequency) +{ + FAR struct imxrt_lpspidev_s *priv = (FAR struct imxrt_lpspidev_s *)dev; + + uint32_t men; + uint32_t pll_freq; + uint32_t pll3_div; + uint32_t src_freq = 0; + uint32_t prescaler; + uint32_t best_prescaler; + uint32_t scaler; + uint32_t best_scaler; + uint32_t real_frequency; + uint32_t best_frequency; + uint32_t diff; + uint32_t min_diff; + + /* Has the LPSPI bus frequency changed? */ + + if (frequency != priv->frequency) + { + /* Disable LPSPI if it is enabled */ + + men = imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) & LPSPI_CR_MEN; + if (men) + { + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, + LPSPI_CR_MEN, 0); + } + + if ((getreg32(IMXRT_CCM_ANALOG_PLL_USB2) & + CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK) != 0) + { + pll3_div = 22; + } + else + { + pll3_div = 20; + } + + pll_freq = BOARD_XTAL_FREQUENCY * pll3_div; + + /* Assumption this formula will work only if the LPSPI Clock Source is + * PLL3 PFD0 * so check if LPSPI clock source is set to 1 (PLL3 PFD0) + * in CCM_CBCMR register bits 4-5 + */ + + src_freq = pll_freq / + ((getreg32(IMXRT_CCM_ANALOG_PFD_480) + & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> + CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT); + src_freq *= 18; + src_freq /= ((getreg32(IMXRT_CCM_CBCMR) & CCM_CBCMR_LPSPI_PODF_MASK) >> + CCM_CBCMR_LPSPI_PODF_SHIFT) + 1; + + min_diff = 0xffffffff; + + best_prescaler = 7; + best_scaler = 255; + + best_frequency = 0; + + for (prescaler = 0; (prescaler < 8) && min_diff; prescaler++) + { + for (scaler = 0; (scaler < 256) && min_diff; scaler++) + { + real_frequency = src_freq / ((1 << prescaler) * (scaler + 2)); + + /* Calculate the frequency difference based on conditional + * statement that states that the calculated frequency must not + * exceed desired frequency. + */ + + if (frequency >= real_frequency) + { + diff = frequency - real_frequency; + if (min_diff > diff) + { + /* A better match found */ + + min_diff = diff; + best_prescaler = prescaler; + best_scaler = scaler; + best_frequency = real_frequency; + } + } + } + } + + /* Write the best values in the CCR register */ + + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CCR_OFFSET, + LPSPI_CCR_SCKDIV_MASK, + LPSPI_CCR_SCKDIV(best_scaler)); + + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_TCR_OFFSET, + LPSPI_TCR_PRESCALE_MASK, + LPSPI_TCR_PRESCALE(best_prescaler)); + + priv->frequency = frequency; + priv->actual = best_frequency; + + imxrt_lpspi_master_set_delays(priv, 1000000000 / best_frequency, + LPSPI_PCS_TO_SCK); + imxrt_lpspi_master_set_delays(priv, 1000000000 / best_frequency, + LPSPI_LAST_SCK_TO_PCS); + imxrt_lpspi_master_set_delays(priv, 1000000000 / best_frequency, + LPSPI_BETWEEN_TRANSFER); + + /* Re-enable LPSPI if it was enabled previously */ + + if (men) + { + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, + LPSPI_CR_MEN); + } + } + + return priv->actual; +} + +/**************************************************************************** + * Name: imxrt_lpspi_setmode + * + * Description: + * Set the SPI mode. see enum spi_mode_e mode for mode definitions + * + * Input Parameters: + * dev - Device-specific state data + * mode - The SPI mode requested + * + * Returned Value: + * Returns the actual frequency selected + * + ****************************************************************************/ + +static void imxrt_lpspi_setmode(FAR struct spi_dev_s *dev, + enum spi_mode_e mode) +{ + FAR struct imxrt_lpspidev_s *priv = (FAR struct imxrt_lpspidev_s *)dev; + uint32_t setbits; + uint32_t clrbits; + uint32_t men; + + spiinfo("mode=%d\n", mode); + + /* Has the mode changed? */ + + if (mode != priv->mode) + { + /* Disable LPSPI if it is enabled */ + + men = imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) & LPSPI_CR_MEN; + if (men) + { + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, + LPSPI_CR_MEN, 0); + } + + switch (mode) + { + case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */ + setbits = 0; + clrbits = LPSPI_TCR_CPOL | LPSPI_TCR_CPHA; + break; + + case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */ + setbits = LPSPI_TCR_CPHA; + clrbits = LPSPI_TCR_CPOL; + break; + + case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */ + setbits = LPSPI_TCR_CPOL; + clrbits = LPSPI_TCR_CPHA; + break; + + case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */ + setbits = LPSPI_TCR_CPOL | LPSPI_TCR_CPHA; + clrbits = 0; + break; + + default: + return; + } + + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_TCR_OFFSET, + clrbits, setbits); + + while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_RSR_OFFSET) & + LPSPI_RSR_RXEMPTY) != LPSPI_RSR_RXEMPTY) + { + /* Flush SPI read FIFO */ + + imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_RSR_OFFSET); + } + + /* Save the mode so that subsequent re-configurations will be faster */ + + priv->mode = mode; + + /* Re-enable LPSPI if it was enabled previously */ + + if (men) + { + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, + LPSPI_CR_MEN); + } + } +} + +/**************************************************************************** + * Name: imxrt_lpspi_setbits + * + * Description: + * Set the number of bits per word. + * + * Input Parameters: + * dev - Device-specific state data + * nbits - The number of bits requested + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void imxrt_lpspi_setbits(FAR struct spi_dev_s *dev, int nbits) +{ + FAR struct imxrt_lpspidev_s *priv = (FAR struct imxrt_lpspidev_s *)dev; + uint32_t men; + + spiinfo("nbits=%d\n", nbits); + + /* Has the number of bits changed? */ + + if (nbits != priv->nbits) + { + if (nbits < 2 || nbits > 4096) + { + return; + } + + /* Disable LPSPI if it is enabled */ + + men = imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) & LPSPI_CR_MEN; + if (men) + { + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, + LPSPI_CR_MEN, 0); + } + + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_TCR_OFFSET, + LPSPI_TCR_FRAMESZ_MASK, + LPSPI_TCR_FRAMESZ(nbits - 1)); + + /* Save the selection so the subsequent re-configurations + * will be faster. + */ + + priv->nbits = nbits; + + /* Re-enable LPSPI if it was enabled previously */ + + if (men) + { + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, + LPSPI_CR_MEN); + } + } +} + +/**************************************************************************** + * Name: imxrt_lpspi_hwfeatures + * + * Description: + * Set hardware-specific feature flags. + * + * Input Parameters: + * dev - Device-specific state data + * features - H/W feature flags + * + * Returned Value: + * Zero (OK) if the selected H/W features are enabled; A negated errno + * value if any H/W feature is not supportable. + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_HWFEATURES +static int imxrt_lpspi_hwfeatures(FAR struct spi_dev_s *dev, + imxrt_lpspi_hwfeatures_t features) +{ +#ifdef CONFIG_SPI_BITORDER + FAR struct imxrt_lpspidev_s *priv = (FAR struct imxrt_lpspidev_s *)dev; + uint32_t setbits; + uint32_t clrbits; + + spiinfo("features=%08x\n", features); + + /* Transfer data LSB first? */ + + if ((features & HWFEAT_LSBFIRST) != 0) + { + setbits = LPSPI_TCR_LSBF; + clrbits = 0; + } + else + { + setbits = 0; + clrbits = LPSPI_TCR_LSBF; + } + + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_TCR_OFFSET, clrbits, setbits); + + /* Other H/W features are not supported */ + + return ((features & ~HWFEAT_LSBFIRST) == 0) ? OK : -ENOSYS; +#else + return -ENOSYS; +#endif +} +#endif + +/**************************************************************************** + * Name: imxrt_lpspi_send + * + * Description: + * Exchange one word on SPI + * + * Input Parameters: + * dev - Device-specific state data + * wd - The word to send. the size of the data is determined by the + * number of bits selected for the SPI interface. + * + * Returned Value: + * response + * + ****************************************************************************/ + +static uint32_t imxrt_lpspi_send(FAR struct spi_dev_s *dev, uint32_t wd) +{ + FAR struct imxrt_lpspidev_s *priv = (FAR struct imxrt_lpspidev_s *)dev; + uint32_t regval; + uint32_t ret; + + DEBUGASSERT(priv && priv->spibase); + + imxrt_lpspi_writeword(priv, wd); + + while ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET) & + LPSPI_SR_RDF) != LPSPI_SR_RDF); + + ret = imxrt_lpspi_readword(priv); + + /* Check and clear any error flags (Reading from the SR clears the error + * flags). + */ + + regval = imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_SR_OFFSET); + + spiinfo( + "Sent: %04" PRIx32 " Return: %04" PRIx32 " Status: %02" PRIx32 "\n", + wd, ret, regval); + + UNUSED(regval); + return ret; +} + +/**************************************************************************** + * Name: imxrt_lpspi_exchange (no DMA). aka imxrt_lpspi_exchange_nodma + * + * Description: + * Exchange a block of data on SPI without using DMA + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * rxbuffer - A pointer to a buffer in which to receive data + * nwords - the length of data to be exchanged in units of words. + * The wordsize is determined by the number of bits-per-word + * selected for the SPI interface. If nbits <= 8, the data is + * packed into uint8_t's; if nbits >8, the data is packed + * into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if !defined(CONFIG_IMXRT_LPSPI_DMA) || defined(CONFIG_IMXRT_DMACAPABLE) +#if !defined(CONFIG_IMXRT_LPSPI_DMA) +static void imxrt_lpspi_exchange(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, + FAR void *rxbuffer, + size_t nwords) +#else +static void imxrt_lpspi_exchange_nodma(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, + FAR void *rxbuffer, size_t nwords) +#endif +{ + FAR struct imxrt_lpspidev_s *priv = (FAR struct imxrt_lpspidev_s *)dev; + DEBUGASSERT(priv && priv->spibase); + + spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); + + /* 8- or 16-bit mode? */ + + if (imxrt_lpspi_9to16bitmode(priv)) + { + /* 16-bit mode */ + + const uint16_t *src = (const uint16_t *)txbuffer; + uint16_t *dest = (uint16_t *) rxbuffer; + uint16_t word; + + while (nwords-- > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xffff; + } + + /* Exchange one word */ + + word = (uint16_t) imxrt_lpspi_send(dev, (uint32_t) word); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } + else + { + /* 8-bit mode */ + + const uint8_t *src = (const uint8_t *)txbuffer; + uint8_t *dest = (uint8_t *) rxbuffer; + uint8_t word; + + while (nwords-- > 0) + { + /* Get the next word to write. Is there a source buffer? */ + + if (src) + { + word = *src++; + } + else + { + word = 0xff; + } + + /* Exchange one word */ + + word = (uint8_t) imxrt_lpspi_send(dev, (uint32_t) word); + + /* Is there a buffer to receive the return value? */ + + if (dest) + { + *dest++ = word; + } + } + } +} +#endif /* !CONFIG_IMXRT_LPSPI_DMA || CONFIG_IMXRT_DMACAPABLE */ + +/**************************************************************************** + * Name: imxrt_lpspi_sndblock + * + * Description: + * Send a block of data on SPI + * + * Input Parameters: + * dev - Device-specific state data + * txbuffer - A pointer to the buffer of data to be sent + * nwords - the length of data to send from the buffer in number of + * words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If nbits <= 8, + * the data is packed into uint8_t's; if nbits >8, the data is + * packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void imxrt_lpspi_sndblock(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, size_t nwords) +{ + spiinfo("txbuffer=%p nwords=%d\n", txbuffer, nwords); + return imxrt_lpspi_exchange(dev, txbuffer, NULL, nwords); +} +#endif + +/**************************************************************************** + * Name: imxrt_lpspi_recvblock + * + * Description: + * Receive a block of data from SPI + * + * Input Parameters: + * dev - Device-specific state data + * rxbuffer - A pointer to the buffer in which to receive data + * nwords - the length of data that can be received in the buffer in + * number of words. The wordsize is determined by the number of + * bits-per-word selected for the SPI interface. If nbits <= 8, + * the data is packed into uint8_t's; if nbits >8, the data is + * packed into uint16_t's + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_EXCHANGE +static void imxrt_lpspi_recvblock(FAR struct spi_dev_s *dev, + FAR void *rxbuffer, size_t nwords) +{ + spiinfo("rxbuffer=%p nwords=%d\n", rxbuffer, nwords); + return imxrt_lpspi_exchange(dev, NULL, rxbuffer, nwords); +} +#endif + +/**************************************************************************** + * Name: imxrt_lpspi_clock_enable + * + * Description: + * Ungate LPSPI clock + * + ****************************************************************************/ + +void imxrt_lpspi_clock_enable(uint32_t base) +{ + if (base == IMXRT_LPSPI1_BASE) + { + imxrt_clockall_lpspi1(); + } + else if (base == IMXRT_LPSPI2_BASE) + { + imxrt_clockall_lpspi2(); + } + else if (base == IMXRT_LPSPI3_BASE) + { + imxrt_clockall_lpspi3(); + } + else if (base == IMXRT_LPSPI4_BASE) + { + imxrt_clockall_lpspi4(); + } +} + +/**************************************************************************** + * Name: imxrt_lpspi_clock_disable + * + * Description: + * Gate LPSPI clock + * + ****************************************************************************/ + +void imxrt_lpspi_clock_disable(uint32_t base) +{ + if (base == IMXRT_LPSPI1_BASE) + { + imxrt_clockoff_lpspi1(); + } + else if (base == IMXRT_LPSPI2_BASE) + { + imxrt_clockoff_lpspi2(); + } + else if (base == IMXRT_LPSPI3_BASE) + { + imxrt_clockoff_lpspi3(); + } + else if (base == IMXRT_LPSPI4_BASE) + { + imxrt_clockoff_lpspi4(); + } +} + +/**************************************************************************** + * Name: imxrt_lpspi_bus_initialize + * + * Description: + * Initialize the selected SPI bus in its default state + * (Master, 8-bit, mode 0, etc.) + * + * Input Parameters: + * priv - private SPI device structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void imxrt_lpspi_bus_initialize(struct imxrt_lpspidev_s *priv) +{ + uint32_t reg = 0; + + /* Enable power and reset the peripheral */ + + imxrt_lpspi_clock_enable(priv->spibase); + + /* Reset to known status */ + + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, LPSPI_CR_RST); + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, + LPSPI_CR_RTF | LPSPI_CR_RRF); + imxrt_lpspi_putreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0x00); + + /* Set LPSPI to master */ + + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CFGR1_OFFSET, 0, + LPSPI_CFGR1_MASTER); + + /* Set specific PCS to active high or low + * TODO: Not needed for now + */ + + /* Set Configuration Register 1 related setting. */ + + reg = imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CFGR1_OFFSET); + reg &= ~(LPSPI_CFGR1_OUTCFG | LPSPI_CFGR1_PINCFG_MASK + | LPSPI_CFGR1_NOSTALL); + reg |= LPSPI_CFGR1_OUTCFG_RETAIN | LPSPI_CFGR1_PINCFG_SIN_SOUT; + imxrt_lpspi_putreg32(priv, IMXRT_LPSPI_CFGR1_OFFSET, reg); + + /* Set frequency and delay times */ + + imxrt_lpspi_setfrequency((FAR struct spi_dev_s *)priv, 400000); + + /* Set default watermarks */ + + imxrt_lpspi_putreg32(priv, IMXRT_LPSPI_FCR_OFFSET, + LPSPI_FCR_TXWATER(0) | LPSPI_FCR_RXWATER(0)); + + /* Set Transmit Command Register */ + + imxrt_lpspi_setbits((FAR struct spi_dev_s *)priv, 8); + + imxrt_lpspi_setmode((FAR struct spi_dev_s *)priv, SPIDEV_MODE0); + + /* Initialize the SPI semaphore that enforces mutually exclusive access */ + + nxsem_init(&priv->exclsem, 0, 1); + + /* Enable LPSPI */ + + imxrt_lpspi_modifyreg32(priv, IMXRT_LPSPI_CR_OFFSET, 0, LPSPI_CR_MEN); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_lpspibus_initialize + * + * Description: + * Initialize the selected SPI bus + * + * Input Parameters: + * Port number (for hardware that has multiple SPI interfaces) + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_dev_s *imxrt_lpspibus_initialize(int bus) +{ + FAR struct imxrt_lpspidev_s *priv = NULL; + + irqstate_t flags = enter_critical_section(); + +#ifdef CONFIG_IMXRT_LPSPI1 + if (bus == 1) + { + /* Select SPI1 */ + + priv = &g_lpspi1dev; + + /* Only configure if the bus is not already configured */ + + if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) + & LPSPI_CR_MEN) == 0) + { + /* Configure SPI1 pins: SCK, MISO, and MOSI */ + + imxrt_config_gpio(GPIO_LPSPI1_SCK); + imxrt_config_gpio(GPIO_LPSPI1_MISO); + imxrt_config_gpio(GPIO_LPSPI1_MOSI); +#ifdef GPIO_LPSPI1_CS + imxrt_config_gpio(GPIO_LPSPI1_CS); +#endif +#if defined(GPIO_LPSPI1_DC) && defined(CONFIG_SPI_CMDDATA) + imxrt_config_gpio(GPIO_LPSPI1_DC); +#endif + + /* Set up default configuration: Master, 8-bit, etc. */ + + imxrt_lpspi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_IMXRT_LPSPI2 + if (bus == 2) + { + /* Select SPI2 */ + + priv = &g_lpspi2dev; + + /* Only configure if the bus is not already configured */ + + if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) + & LPSPI_CR_MEN) == 0) + { + /* Configure SPI2 pins: SCK, MISO, and MOSI */ + + imxrt_config_gpio(GPIO_LPSPI2_SCK); + imxrt_config_gpio(GPIO_LPSPI2_MISO); + imxrt_config_gpio(GPIO_LPSPI2_MOSI); +#ifdef GPIO_LPSPI2_CS + imxrt_config_gpio(GPIO_LPSPI2_CS); +#endif +#if defined(GPIO_LPSPI2_DC) && defined(CONFIG_SPI_CMDDATA) + imxrt_config_gpio(GPIO_LPSPI2_DC); +#endif + + /* Set up default configuration: Master, 8-bit, etc. */ + + imxrt_lpspi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_IMXRT_LPSPI3 + if (bus == 3) + { + /* Select SPI3 */ + + priv = &g_lpspi3dev; + + /* Only configure if the bus is not already configured */ + + if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) + & LPSPI_CR_MEN) == 0) + { + /* Configure SPI3 pins: SCK, MISO, and MOSI */ + + imxrt_config_gpio(GPIO_LPSPI3_SCK); + imxrt_config_gpio(GPIO_LPSPI3_MISO); + imxrt_config_gpio(GPIO_LPSPI3_MOSI); +#ifdef GPIO_LPSPI3_CS + imxrt_config_gpio(GPIO_LPSPI3_CS); +#endif +#if defined(GPIO_LPSPI3_DC) && defined(CONFIG_SPI_CMDDATA) + imxrt_config_gpio(GPIO_LPSPI3_DC); +#endif + + /* Set up default configuration: Master, 8-bit, etc. */ + + imxrt_lpspi_bus_initialize(priv); + } + } + else +#endif +#ifdef CONFIG_IMXRT_LPSPI4 + if (bus == 4) + { + /* Select SPI4 */ + + priv = &g_lpspi4dev; + + /* Only configure if the bus is not already configured */ + + if ((imxrt_lpspi_getreg32(priv, IMXRT_LPSPI_CR_OFFSET) + & LPSPI_CR_MEN) == 0) + { + /* Configure SPI4 pins: SCK, MISO, and MOSI */ + + imxrt_config_gpio(GPIO_LPSPI4_SCK); + imxrt_config_gpio(GPIO_LPSPI4_MISO); + imxrt_config_gpio(GPIO_LPSPI4_MOSI); +#ifdef GPIO_LPSPI4_CS + imxrt_config_gpio(GPIO_LPSPI4_CS); +#endif +#if defined(GPIO_LPSPI4_DC) && defined(CONFIG_SPI_CMDDATA) + imxrt_config_gpio(GPIO_LPSPI4_DC); +#endif + + /* Set up default configuration: Master, 8-bit, etc. */ + + imxrt_lpspi_bus_initialize(priv); + } + } + else +#endif + { + spierr("ERROR: Unsupported SPI bus: %d\n", bus); + return NULL; + } + + leave_critical_section(flags); + + return (FAR struct spi_dev_s *)priv; +} + +#endif /* CONFIG_IMXRT_LPSPI1 */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_usbdev.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_usbdev.c new file mode 100644 index 000000000..3f0d6ff03 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/imxrt/imxrt_usbdev.c @@ -0,0 +1,3061 @@ +/**************************************************************************** + * arch/arm/src/imxrt/imxrt_usbdev.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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "arm_arch.h" +#include "arm_internal.h" + +#include "hardware/imxrt_usbotg.h" +#include "hardware/imxrt_usbphy.h" +#include "hardware/rt106x/imxrt106x_ccm.h" +#include "imxrt_periphclks.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 /* mA */ +#endif + +/* Enable reading SOF from interrupt handler vs. simply reading on demand. + * Probably a bad idea... Unless there is some issue with sampling the SOF + * from hardware asynchronously. + */ + +#ifdef CONFIG_IMXRT_USBDEV_FRAME_INTERRUPT +# define USB_FRAME_INT USBDEV_USBINTR_SRE +#else +# define USB_FRAME_INT 0 +#endif + +#ifdef CONFIG_DEBUG_FEATURES +# define USB_ERROR_INT USBDEV_USBINTR_UEE +#else +# define USB_ERROR_INT 0 +#endif + +/* Debug ********************************************************************/ + +/* Trace error codes */ + +#define IMXRT_TRACEERR_ALLOCFAIL 0x0001 +#define IMXRT_TRACEERR_BADCLEARFEATURE 0x0002 +#define IMXRT_TRACEERR_BADDEVGETSTATUS 0x0003 +#define IMXRT_TRACEERR_BADEPNO 0x0004 +#define IMXRT_TRACEERR_BADEPGETSTATUS 0x0005 +#define IMXRT_TRACEERR_BADEPTYPE 0x0006 +#define IMXRT_TRACEERR_BADGETCONFIG 0x0007 +#define IMXRT_TRACEERR_BADGETSETDESC 0x0008 +#define IMXRT_TRACEERR_BADGETSTATUS 0x0009 +#define IMXRT_TRACEERR_BADSETADDRESS 0x000a +#define IMXRT_TRACEERR_BADSETCONFIG 0x000b +#define IMXRT_TRACEERR_BADSETFEATURE 0x000c +#define IMXRT_TRACEERR_BINDFAILED 0x000d +#define IMXRT_TRACEERR_DISPATCHSTALL 0x000e +#define IMXRT_TRACEERR_DRIVER 0x000f +#define IMXRT_TRACEERR_DRIVERREGISTERED 0x0010 +#define IMXRT_TRACEERR_EP0SETUPSTALLED 0x0011 +#define IMXRT_TRACEERR_EPINNULLPACKET 0x0012 +#define IMXRT_TRACEERR_EPOUTNULLPACKET 0x0013 +#define IMXRT_TRACEERR_INVALIDCTRLREQ 0x0014 +#define IMXRT_TRACEERR_INVALIDPARMS 0x0015 +#define IMXRT_TRACEERR_IRQREGISTRATION 0x0016 +#define IMXRT_TRACEERR_NOEP 0x0017 +#define IMXRT_TRACEERR_NOTCONFIGURED 0x0018 +#define IMXRT_TRACEERR_REQABORTED 0x0019 + +/* Trace interrupt codes */ + +#define IMXRT_TRACEINTID_USB 0x0001 +#define IMXRT_TRACEINTID_CLEARFEATURE 0x0002 +#define IMXRT_TRACEINTID_DEVGETSTATUS 0x0003 +#define IMXRT_TRACEINTID_DEVRESET 0x0004 +#define IMXRT_TRACEINTID_DISPATCH 0x0005 +#define IMXRT_TRACEINTID_EP0COMPLETE 0x0006 +#define IMXRT_TRACEINTID_EP0NAK 0x0007 +#define IMXRT_TRACEINTID_EP0SETUP 0x0008 +#define IMXRT_TRACEINTID_EPGETSTATUS 0x0009 +#define IMXRT_TRACEINTID_EPIN 0x000a +#define IMXRT_TRACEINTID_EPINQEMPTY 0x000b +#define IMXRT_TRACEINTID_EP0INSETADDRESS 0x000c +#define IMXRT_TRACEINTID_EPOUT 0x000d +#define IMXRT_TRACEINTID_EPOUTQEMPTY 0x000e +#define IMXRT_TRACEINTID_EP0SETUPSETADDRESS 0x000f +#define IMXRT_TRACEINTID_FRAME 0x0010 +#define IMXRT_TRACEINTID_GETCONFIG 0x0011 +#define IMXRT_TRACEINTID_GETSETDESC 0x0012 +#define IMXRT_TRACEINTID_GETSETIF 0x0013 +#define IMXRT_TRACEINTID_GETSTATUS 0x0014 +#define IMXRT_TRACEINTID_IFGETSTATUS 0x0015 +#define IMXRT_TRACEINTID_SETCONFIG 0x0016 +#define IMXRT_TRACEINTID_SETFEATURE 0x0017 +#define IMXRT_TRACEINTID_SUSPENDED 0x0018 +#define IMXRT_TRACEINTID_RESUMED 0x0019 +#define IMXRT_TRACEINTID_SYNCHFRAME 0x001a + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_deverror[] = +{ + TRACE_STR(IMXRT_TRACEERR_ALLOCFAIL), + TRACE_STR(IMXRT_TRACEERR_BADCLEARFEATURE), + TRACE_STR(IMXRT_TRACEERR_BADDEVGETSTATUS), + TRACE_STR(IMXRT_TRACEERR_BADEPNO), + TRACE_STR(IMXRT_TRACEERR_BADEPGETSTATUS), + TRACE_STR(IMXRT_TRACEERR_BADEPTYPE), + TRACE_STR(IMXRT_TRACEERR_BADGETCONFIG), + TRACE_STR(IMXRT_TRACEERR_BADGETSETDESC), + TRACE_STR(IMXRT_TRACEERR_BADGETSTATUS), + TRACE_STR(IMXRT_TRACEERR_BADSETADDRESS), + TRACE_STR(IMXRT_TRACEERR_BADSETCONFIG), + TRACE_STR(IMXRT_TRACEERR_BADSETFEATURE), + TRACE_STR(IMXRT_TRACEERR_BINDFAILED), + TRACE_STR(IMXRT_TRACEERR_DISPATCHSTALL), + TRACE_STR(IMXRT_TRACEERR_DRIVER), + TRACE_STR(IMXRT_TRACEERR_DRIVERREGISTERED), + TRACE_STR(IMXRT_TRACEERR_EP0SETUPSTALLED), + TRACE_STR(IMXRT_TRACEERR_EPINNULLPACKET), + TRACE_STR(IMXRT_TRACEERR_EPOUTNULLPACKET), + TRACE_STR(IMXRT_TRACEERR_INVALIDCTRLREQ), + TRACE_STR(IMXRT_TRACEERR_INVALIDPARMS), + TRACE_STR(IMXRT_TRACEERR_IRQREGISTRATION), + TRACE_STR(IMXRT_TRACEERR_NOEP), + TRACE_STR(IMXRT_TRACEERR_NOTCONFIGURED), + TRACE_STR(IMXRT_TRACEERR_REQABORTED), + TRACE_STR_END +}; + +const struct trace_msg_t g_usb_trace_strings_intdecode[] = +{ + TRACE_STR(IMXRT_TRACEINTID_USB), + TRACE_STR(IMXRT_TRACEINTID_CLEARFEATURE), + TRACE_STR(IMXRT_TRACEINTID_DEVGETSTATUS), + TRACE_STR(IMXRT_TRACEINTID_DEVRESET), + TRACE_STR(IMXRT_TRACEINTID_DISPATCH), + TRACE_STR(IMXRT_TRACEINTID_EP0COMPLETE), + TRACE_STR(IMXRT_TRACEINTID_EP0NAK), + TRACE_STR(IMXRT_TRACEINTID_EP0SETUP), + TRACE_STR(IMXRT_TRACEINTID_EPGETSTATUS), + TRACE_STR(IMXRT_TRACEINTID_EPIN), + TRACE_STR(IMXRT_TRACEINTID_EPINQEMPTY), + TRACE_STR(IMXRT_TRACEINTID_EP0INSETADDRESS), + TRACE_STR(IMXRT_TRACEINTID_EPOUT), + TRACE_STR(IMXRT_TRACEINTID_EPOUTQEMPTY), + TRACE_STR(IMXRT_TRACEINTID_EP0SETUPSETADDRESS), + TRACE_STR(IMXRT_TRACEINTID_FRAME), + TRACE_STR(IMXRT_TRACEINTID_GETCONFIG), + TRACE_STR(IMXRT_TRACEINTID_GETSETDESC), + TRACE_STR(IMXRT_TRACEINTID_GETSETIF), + TRACE_STR(IMXRT_TRACEINTID_GETSTATUS), + TRACE_STR(IMXRT_TRACEINTID_IFGETSTATUS), + TRACE_STR(IMXRT_TRACEINTID_SETCONFIG), + TRACE_STR(IMXRT_TRACEINTID_SETFEATURE), + TRACE_STR(IMXRT_TRACEINTID_SUSPENDED), + TRACE_STR(IMXRT_TRACEINTID_RESUMED), + TRACE_STR(IMXRT_TRACEINTID_SYNCHFRAME), + TRACE_STR_END +}; +#endif + +/* Hardware interface *******************************************************/ + +/* This represents a Endpoint Transfer Descriptor - note these must be 32 + * byte aligned. + */ + +struct imxrt_dtd_s +{ + volatile uint32_t nextdesc; /* Address of the next DMA descripto in RAM */ + volatile uint32_t config; /* Misc. bit encoded configuration information */ + uint32_t buffer0; /* Buffer start address */ + uint32_t buffer1; /* Buffer start address */ + uint32_t buffer2; /* Buffer start address */ + uint32_t buffer3; /* Buffer start address */ + uint32_t buffer4; /* Buffer start address */ + uint32_t xfer_len; /* Software only - transfer len that was queued */ +}; + +/* DTD nextdesc field */ + +#define DTD_NEXTDESC_INVALID (1 << 0) /* Bit 0 : Next Descriptor Invalid. The "Terminate" bit. */ + +/* DTD config field */ + +#define DTD_CONFIG_LENGTH(n) ((n) << 16) /* Bits 16-31 : Total bytes to transfer */ +#define DTD_CONFIG_IOC (1 << 15) /* Bit 15 : Interrupt on Completion */ +#define DTD_CONFIG_MULT_VARIABLE (0 << 10) /* Bits 10-11 : Number of packets executed per transacation descriptor (override) */ +#define DTD_CONFIG_MULT_NUM(n) ((n) << 10) +#define DTD_CONFIG_ACTIVE (1 << 7) /* Bit 7 : Status Active */ +#define DTD_CONFIG_HALTED (1 << 6) /* Bit 6 : Status Halted */ +#define DTD_CONFIG_BUFFER_ERROR (1 << 5) /* Bit 6 : Status Buffer Error */ +#define DTD_CONFIG_TRANSACTION_ERROR (1 << 3) /* Bit 3 : Status Transaction Error */ + +/* This represents a queue head - not these must be aligned to a 2048 byte + * boundary + */ + +struct imxrt_dqh_s +{ + uint32_t capability; /* Endpoint capability */ + uint32_t currdesc; /* Current dTD pointer */ + struct imxrt_dtd_s overlay; /* DTD overlay */ + volatile uint32_t setup[2]; /* Set-up buffer */ + uint32_t gap[4]; /* align to 64 bytes */ +}; + +/* DQH capability field */ + +#define DQH_CAPABILITY_MULT_VARIABLE (0 << 30) /* Bits 30-31 : Number of packets executed per transaction descriptor */ +#define DQH_CAPABILITY_MULT_NUM(n) ((n) << 30) +#define DQH_CAPABILITY_ZLT (1 << 29) /* Bit 29 : Zero Length Termination Select */ +#define DQH_CAPABILITY_MAX_PACKET(n) ((n) << 16) /* Bits 16-29 : Maximum packet size of associated endpoint (<1024) */ +#define DQH_CAPABILITY_IOS (1 << 15) /* Bit 15 : Interrupt on Setup */ + +/* Endpoints ****************************************************************/ + +/* Number of endpoints */ + +#define IMXRT_NLOGENDPOINTS (8) /* ep0-7 */ +#define IMXRT_NPHYSENDPOINTS (16) /* x2 for IN and OUT */ + +/* Odd physical endpoint numbers are IN; even are OUT */ + +#define IMXRT_EPPHYIN(epphy) (((epphy) & 1) != 0) +#define IMXRT_EPPHYOUT(epphy) (((epphy) & 1) == 0) + +#define IMXRT_EPPHYIN2LOG(epphy) (((uint8_t)(epphy) >> 1) |USB_DIR_IN) +#define IMXRT_EPPHYOUT2LOG(epphy) (((uint8_t)(epphy) >> 1) | USB_DIR_OUT) + +/* Endpoint 0 is special... */ + +#define IMXRT_EP0_OUT (0) +#define IMXRT_EP0_IN (1) + +/* Each endpoint has somewhat different characteristics */ + +#define IMXRT_EPALLSET (0xffff) /* All endpoints */ +#define IMXRT_EPOUTSET (0x5555) /* Even phy endpoint numbers are OUT EPs */ +#define IMXRT_EPINSET (0xaaaa) /* Odd endpoint numbers are IN EPs */ +#define IMXRT_EPCTRLSET (0x0003) /* EP0 IN/OUT are control endpoints */ +#define IMXRT_EPINTRSET (0xfffc) /* Interrupt endpoints */ +#define IMXRT_EPBULKSET (0xfffc) /* Bulk endpoints */ +#define IMXRT_EPISOCSET (0xfffc) /* Isochronous endpoints */ + +/* Maximum packet sizes for endpoints */ + +#define IMXRT_EP0MAXPACKET (64) /* EP0 max packet size (1-64) */ +#define IMXRT_BULKMAXPACKET (512) /* Bulk endpoint max packet (8/16/32/64/512) */ +#define IMXRT_INTRMAXPACKET (1024) /* Interrupt endpoint max packet (1 to 1024) */ +#define IMXRT_ISOCMAXPACKET (512) /* Acutally 1..1023 */ + +/* Endpoint bit position in SETUPSTAT, PRIME, FLUSH, STAT, COMPLETE + * registers + */ + +#define IMXRT_ENDPTSHIFT(epphy) (IMXRT_EPPHYIN(epphy) ? (16 + ((epphy) >> 1)) : ((epphy) >> 1)) +#define IMXRT_ENDPTMASK(epphy) (1 << IMXRT_ENDPTSHIFT(epphy)) +#define IMXRT_ENDPTMASK_ALL 0x00ff00ff + +/* Request queue operations *************************************************/ + +#define imxrt_rqempty(ep) ((ep)->head == NULL) +#define imxrt_rqpeek(ep) ((ep)->head) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* A container for a request so that the request may be retained in a list */ + +struct imxrt_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct imxrt_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct imxrt_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct imxrt_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* IMXRTXX-specific fields */ + + struct imxrt_usbdev_s *dev; /* Reference to private driver data */ + struct imxrt_req_s *head; /* Request list for this endpoint */ + struct imxrt_req_s *tail; + uint8_t epphy; /* Physical EP address */ + uint8_t stalled:1; /* 1: Endpoint is stalled */ +}; + +/* This structure retains the state of the USB device controller */ + +struct imxrt_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to struct imxrt_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* IMXRTXX-specific fields */ + + uint8_t ep0state; /* State of certain EP0 operations */ + uint8_t ep0buf[64]; /* buffer for EP0 short transfers */ + uint8_t paddr; /* Address assigned by SETADDRESS */ + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t paddrset:1; /* 1: Peripheral addr has been set */ + uint8_t attached:1; /* 1: Host attached */ + uint8_t suspended:1; /* 1: Suspended */ + uint32_t softprio; /* Bitset of high priority interrupts */ + uint32_t epavail; /* Bitset of available endpoints */ +#ifdef CONFIG_IMXRT_USBDEV_FRAME_INTERRUPT + uint32_t sof; /* Last start-of-frame */ +#endif + + uint16_t ep0buf_len; + struct usb_ctrlreq_s ep0ctrl; + + /* The endpoint list */ + + struct imxrt_ep_s eplist[IMXRT_NPHYSENDPOINTS]; +}; + +#define EP0STATE_IDLE 0 /* Idle State, leave on receiving a setup packet or epsubmit */ +#define EP0STATE_SETUP_OUT 1 /* Setup Packet received - SET/CLEAR */ +#define EP0STATE_SETUP_IN 2 /* Setup Packet received - GET */ +#define EP0STATE_SHORTREAD 3 /* Short read without a usb_request */ +#define EP0STATE_SHORTWRITE 4 /* Short write without a usb_request */ +#define EP0STATE_WAIT_NAK_OUT 5 /* Waiting for Host to illicit status phase (GET) */ +#define EP0STATE_WAIT_NAK_IN 6 /* Waiting for Host to illicit status phase (SET/CLEAR) */ +#define EP0STATE_WAIT_STATUS_OUT 7 /* Wait for status phase to complete */ +#define EP0STATE_WAIT_STATUS_IN 8 /* Wait for status phase to complete */ +#define EP0STATE_DATA_IN 9 +#define EP0STATE_DATA_OUT 10 + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ******************************************************/ + +#ifdef CONFIG_IMXRT_USBDEV_REGDEBUG +static uint32_t imxrt_getreg(uint32_t addr); +static void imxrt_putreg(uint32_t val, uint32_t addr); +#else +# define imxrt_getreg(addr) getreg32(addr) +# define imxrt_putreg(val,addr) putreg32(val,addr) +#endif + +static inline void imxrt_clrbits(uint32_t mask, uint32_t addr); +static inline void imxrt_setbits(uint32_t mask, uint32_t addr); +static inline void imxrt_chgbits(uint32_t mask, uint32_t val, uint32_t addr); + +/* Request queue operations *************************************************/ + +static FAR struct imxrt_req_s *imxrt_rqdequeue( + FAR struct imxrt_ep_s *privep); +static bool imxrt_rqenqueue(FAR struct imxrt_ep_s *privep, + FAR struct imxrt_req_s *req); + +/* Low level data transfers and request operations **************************/ + +static inline void imxrt_writedtd(struct imxrt_dtd_s *dtd, + const uint8_t *data, + uint32_t nbytes); +static inline void imxrt_queuedtd(uint8_t epphy, struct imxrt_dtd_s *dtd); +static inline void imxrt_ep0xfer(uint8_t epphy, uint8_t *data, + uint32_t nbytes); +static void imxrt_readsetup(uint8_t epphy, + struct usb_ctrlreq_s *ctrl); + +static inline void imxrt_set_address(struct imxrt_usbdev_s *priv, + uint16_t address); + +static void imxrt_flushep(struct imxrt_ep_s *privep); + +static int imxrt_progressep(struct imxrt_ep_s *privep); +static void imxrt_reqcomplete(struct imxrt_ep_s *privep, + struct imxrt_req_s *privreq, int16_t result); + +static void imxrt_cancelrequests(struct imxrt_ep_s *privep, + int16_t status); + +/* Interrupt handling *******************************************************/ + +static struct imxrt_ep_s *imxrt_epfindbyaddr(struct imxrt_usbdev_s *priv, + uint16_t eplog); +static void imxrt_dispatchrequest(struct imxrt_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl); +static void imxrt_ep0configure(struct imxrt_usbdev_s *priv); +static void imxrt_usbreset(struct imxrt_usbdev_s *priv); + +static inline void imxrt_ep0state(struct imxrt_usbdev_s *priv, + uint16_t state); +static void imxrt_ep0setup(struct imxrt_usbdev_s *priv); + +static void imxrt_ep0complete(struct imxrt_usbdev_s *priv, + uint8_t epphy); +static void imxrt_ep0nak(struct imxrt_usbdev_s *priv, uint8_t epphy); +static bool imxrt_epcomplete(struct imxrt_usbdev_s *priv, + uint8_t epphy); + +static int imxrt_usbinterrupt(int irq, FAR void *context, + FAR void *arg); + +/* Endpoint operations ******************************************************/ + +/* USB device controller operations *****************************************/ + +static int imxrt_epconfigure(FAR struct usbdev_ep_s *ep, + const struct usb_epdesc_s *desc, bool last); +static int imxrt_epdisable(FAR struct usbdev_ep_s *ep); +static FAR struct usbdev_req_s *imxrt_epallocreq(FAR struct usbdev_ep_s *ep); +static void imxrt_epfreereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *); +#ifdef CONFIG_USBDEV_DMA +static void *imxrt_epallocbuffer(FAR struct usbdev_ep_s *ep, + uint16_t bytes); +static void imxrt_epfreebuffer(FAR struct usbdev_ep_s *ep, + FAR void *buf); +#endif +static int imxrt_epsubmit(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int imxrt_epcancel(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); +static int imxrt_epstall(FAR struct usbdev_ep_s *ep, bool resume); + +static FAR struct usbdev_ep_s *imxrt_allocep(FAR struct usbdev_s *dev, + uint8_t epno, bool in, uint8_t eptype); +static void imxrt_freeep(FAR struct usbdev_s *dev, + FAR struct usbdev_ep_s *ep); +static int imxrt_getframe(struct usbdev_s *dev); +static int imxrt_wakeup(struct usbdev_s *dev); +static int imxrt_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int imxrt_pullup(struct usbdev_s *dev, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct imxrt_usbdev_s g_usbdev; + +static struct imxrt_dqh_s g_qh[IMXRT_NPHYSENDPOINTS] + aligned_data(2048); + +static struct imxrt_dtd_s g_td[IMXRT_NPHYSENDPOINTS] + aligned_data(32); + +static const struct usbdev_epops_s g_epops = +{ + .configure = imxrt_epconfigure, + .disable = imxrt_epdisable, + .allocreq = imxrt_epallocreq, + .freereq = imxrt_epfreereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = imxrt_epallocbuffer, + .freebuffer = imxrt_epfreebuffer, +#endif + .submit = imxrt_epsubmit, + .cancel = imxrt_epcancel, + .stall = imxrt_epstall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = imxrt_allocep, + .freeep = imxrt_freeep, + .getframe = imxrt_getframe, + .wakeup = imxrt_wakeup, + .selfpowered = imxrt_selfpowered, + .pullup = imxrt_pullup, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_getreg + * + * Description: + * Get the contents of an IMXRT3x register + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_USBDEV_REGDEBUG +static uint32_t imxrt_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same register last time? + * Are we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + uinfo("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + uinfo("[repeats %d more times]\n", count - 3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + uinfo("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: imxrt_putreg + * + * Description: + * Set the contents of an IMXRT3x register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_IMXRT_USBDEV_REGDEBUG +static void imxrt_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + uinfo("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: imxrt_clrbits + * + * Description: + * Clear bits in a register + * + ****************************************************************************/ + +static inline void imxrt_clrbits(uint32_t mask, uint32_t addr) +{ + uint32_t reg = imxrt_getreg(addr); + reg &= ~mask; + imxrt_putreg(reg, addr); +} + +/**************************************************************************** + * Name: imxrt_setbits + * + * Description: + * Set bits in a register + * + ****************************************************************************/ + +static inline void imxrt_setbits(uint32_t mask, uint32_t addr) +{ + uint32_t reg = imxrt_getreg(addr); + reg |= mask; + imxrt_putreg(reg, addr); +} + +/**************************************************************************** + * Name: imxrt_chgbits + * + * Description: + * Change bits in a register + * + ****************************************************************************/ + +static inline void imxrt_chgbits(uint32_t mask, uint32_t val, uint32_t addr) +{ + uint32_t reg = imxrt_getreg(addr); + reg &= ~mask; + reg |= val; + imxrt_putreg(reg, addr); +} + +/**************************************************************************** + * Name: imxrt_rqdequeue + * + * Description: + * Remove a request from an endpoint request queue + * + ****************************************************************************/ + +static FAR struct imxrt_req_s *imxrt_rqdequeue(FAR struct imxrt_ep_s *privep) +{ + FAR struct imxrt_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: imxrt_rqenqueue + * + * Description: + * Add a request from an endpoint request queue + * + ****************************************************************************/ + +static bool imxrt_rqenqueue(FAR struct imxrt_ep_s *privep, + FAR struct imxrt_req_s *req) +{ + bool is_empty = !privep->head; + + req->flink = NULL; + if (is_empty) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } + + return is_empty; +} + +/**************************************************************************** + * Name: imxrt_writedtd + * + * Description: + * Initialise a DTD to transfer the data + * + ****************************************************************************/ + +static inline void imxrt_writedtd(struct imxrt_dtd_s *dtd, + const uint8_t *data, + uint32_t nbytes) +{ + dtd->nextdesc = DTD_NEXTDESC_INVALID; + dtd->config = DTD_CONFIG_LENGTH(nbytes) | DTD_CONFIG_IOC | + DTD_CONFIG_ACTIVE; + dtd->buffer0 = ((uint32_t) data); + dtd->buffer1 = (((uint32_t) data) + 0x1000) & 0xfffff000; + dtd->buffer2 = (((uint32_t) data) + 0x2000) & 0xfffff000; + dtd->buffer3 = (((uint32_t) data) + 0x3000) & 0xfffff000; + dtd->buffer4 = (((uint32_t) data) + 0x4000) & 0xfffff000; + dtd->xfer_len = nbytes; + + up_flush_dcache((uintptr_t)dtd, + (uintptr_t)dtd + sizeof(struct imxrt_dtd_s)); + up_flush_dcache((uintptr_t)data, + (uintptr_t)data + nbytes); +} + +/**************************************************************************** + * Name: imxrt_queuedtd + * + * Description: + * Add the DTD to the device list + * + * Assumptions: + * DTD is already flushed to RAM. + * + ****************************************************************************/ + +static void imxrt_queuedtd(uint8_t epphy, struct imxrt_dtd_s *dtd) +{ + struct imxrt_dqh_s *dqh = &g_qh[epphy]; + + /* Queue the DTD onto the Endpoint + * NOTE - this only works when no DTD is currently queued + */ + + dqh->overlay.nextdesc = (uint32_t) dtd; + dqh->overlay.config &= ~(DTD_CONFIG_ACTIVE | DTD_CONFIG_HALTED); + + up_flush_dcache((uintptr_t)dqh, + (uintptr_t)dqh + sizeof(struct imxrt_dqh_s)); + + uint32_t bit = IMXRT_ENDPTMASK(epphy); + + imxrt_setbits (bit, IMXRT_USBDEV_ENDPTPRIME); + + while (imxrt_getreg (IMXRT_USBDEV_ENDPTPRIME) & bit) + ; +} + +/**************************************************************************** + * Name: imxrt_ep0xfer + * + * Description: + * Schedule a short transfer for Endpoint 0 (IN or OUT) + * + ****************************************************************************/ + +static inline void imxrt_ep0xfer(uint8_t epphy, uint8_t *buf, + uint32_t nbytes) +{ + struct imxrt_dtd_s *dtd = &g_td[epphy]; + + imxrt_writedtd(dtd, buf, nbytes); + + imxrt_queuedtd(epphy, dtd); +} + +/**************************************************************************** + * Name: imxrt_readsetup + * + * Description: + * Read a Setup packet from the DTD. + * + ****************************************************************************/ + +static void imxrt_readsetup(uint8_t epphy, struct usb_ctrlreq_s *ctrl) +{ + struct imxrt_dqh_s *dqh = &g_qh[epphy]; + int i; + + do + { + /* Set the trip wire */ + + imxrt_setbits(USBDEV_USBCMD_SUTW, IMXRT_USBDEV_USBCMD); + + up_invalidate_dcache((uintptr_t)dqh, + (uintptr_t)dqh + sizeof(struct imxrt_dqh_s)); + + /* Copy the request... */ + + for (i = 0; i < 8; i++) + { + ((uint8_t *) ctrl)[i] = ((uint8_t *) dqh->setup)[i]; + } + } + while (!(imxrt_getreg(IMXRT_USBDEV_USBCMD) & USBDEV_USBCMD_SUTW)); + + /* Clear the trip wire */ + + imxrt_clrbits(USBDEV_USBCMD_SUTW, IMXRT_USBDEV_USBCMD); + + /* Clear the Setup Interrupt */ + + imxrt_putreg (IMXRT_ENDPTMASK(IMXRT_EP0_OUT), IMXRT_USBDEV_ENDPTSETUPSTAT); +} + +/**************************************************************************** + * Name: imxrt_set_address + * + * Description: + * Set the devices USB address + * + ****************************************************************************/ + +static inline void imxrt_set_address(struct imxrt_usbdev_s *priv, + uint16_t address) +{ + priv->paddr = address; + priv->paddrset = address != 0; + + imxrt_chgbits(USBDEV_DEVICEADDR_MASK, + priv->paddr << USBDEV_DEVICEADDR_SHIFT, + IMXRT_USBDEV_DEVICEADDR); +} + +/**************************************************************************** + * Name: imxrt_flushep + * + * Description: + * Flush any primed descriptors from this ep + * + ****************************************************************************/ + +static void imxrt_flushep(struct imxrt_ep_s *privep) +{ + uint32_t mask = IMXRT_ENDPTMASK(privep->epphy); + do + { + imxrt_putreg (mask, IMXRT_USBDEV_ENDPTFLUSH); + while ((imxrt_getreg(IMXRT_USBDEV_ENDPTFLUSH) & mask) != 0) + ; + } + while ((imxrt_getreg(IMXRT_USBDEV_ENDPTSTATUS) & mask) != 0); +} + +/**************************************************************************** + * Name: imxrt_progressep + * + * Description: + * Progress the Endpoint by priming the first request into the queue head + * + ****************************************************************************/ + +static int imxrt_progressep(struct imxrt_ep_s *privep) +{ + struct imxrt_dtd_s *dtd = &g_td[privep->epphy]; + struct imxrt_req_s *privreq; + + /* Check the request from the head of the endpoint request queue */ + + privreq = imxrt_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_EPINQEMPTY), 0); + return OK; + } + + /* Ignore any attempt to send a zero length packet */ + + if (privreq->req.len == 0) + { + /* If the class driver is responding to a setup packet, then wait for + * the host to illicit thr response + */ + + if (privep->epphy == IMXRT_EP0_IN && + privep->dev->ep0state == EP0STATE_SETUP_OUT) + { + imxrt_ep0state (privep->dev, EP0STATE_WAIT_NAK_IN); + } + else + { + if (IMXRT_EPPHYIN(privep->epphy)) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_EPINNULLPACKET), 0); + } + else + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_EPOUTNULLPACKET), 0); + } + } + + imxrt_reqcomplete(privep, imxrt_rqdequeue(privep), OK); + return OK; + } + + if (privep->epphy == IMXRT_EP0_IN) + { + imxrt_ep0state (privep->dev, EP0STATE_DATA_IN); + } + else if (privep->epphy == IMXRT_EP0_OUT) + { + imxrt_ep0state (privep->dev, EP0STATE_DATA_OUT); + } + + int bytesleft = privreq->req.len - privreq->req.xfrd; + + if (IMXRT_EPPHYIN(privep->epphy)) + { + usbtrace(TRACE_WRITE(privep->epphy), privreq->req.xfrd); + } + else + { + usbtrace(TRACE_READ(privep->epphy), privreq->req.xfrd); + } + + /* Initialise the DTD to transfer the next chunk */ + + imxrt_writedtd (dtd, privreq->req.buf + privreq->req.xfrd, bytesleft); + + /* Then queue onto the DQH */ + + imxrt_queuedtd(privep->epphy, dtd); + + return OK; +} + +/**************************************************************************** + * Name: imxrt_reqcomplete + * + * Description: + * Handle termination of the request at the head of the endpoint request + * queue. + * + ****************************************************************************/ + +static void imxrt_reqcomplete(struct imxrt_ep_s *privep, + struct imxrt_req_s *privreq, int16_t result) +{ + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + bool stalled = privep->stalled; + if (privep->epphy == IMXRT_EP0_IN) + privep->stalled = privep->dev->stalled; + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; +} + +/**************************************************************************** + * Name: imxrt_cancelrequests + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void imxrt_cancelrequests(struct imxrt_ep_s *privep, int16_t status) +{ + if (!imxrt_rqempty(privep)) + imxrt_flushep(privep); + + while (!imxrt_rqempty(privep)) + { + /* FIXME: the entry at the head should be sync'd with the DTD + * FIXME: only report the error status if the transfer hasn't completed + */ + + usbtrace(TRACE_COMPLETE(privep->epphy), + (imxrt_rqpeek(privep))->req.xfrd); + imxrt_reqcomplete(privep, imxrt_rqdequeue(privep), status); + } +} + +/**************************************************************************** + * Name: imxrt_epfindbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct imxrt_ep_s *imxrt_epfindbyaddr(struct imxrt_usbdev_s *priv, + uint16_t eplog) +{ + struct imxrt_ep_s *privep; + int i; + + /* Endpoint zero is a special case */ + + if (USB_EPNO(eplog) == 0) + { + return &priv->eplist[0]; + } + + /* Handle the remaining */ + + for (i = 1; i < IMXRT_NPHYSENDPOINTS; i++) + { + privep = &priv->eplist[i]; + + /* Same logical endpoint number? (includes direction bit) */ + + if (eplog == privep->ep.eplog) + { + /* Return endpoint found */ + + return privep; + } + } + + /* Return endpoint not found */ + + return NULL; +} + +/**************************************************************************** + * Name: imxrt_dispatchrequest + * + * Description: + * Provide unhandled setup actions to the class driver. This is logically + * part of the USB interrupt handler. + * + ****************************************************************************/ + +static void imxrt_dispatchrequest(struct imxrt_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl) +{ + int ret = -EIO; + + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_DISPATCH), 0); + if (priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, priv->ep0buf, + priv->ep0buf_len); + } + + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_DISPATCHSTALL), 0); + priv->stalled = true; + } +} + +/**************************************************************************** + * Name: imxrt_ep0configure + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void imxrt_ep0configure(struct imxrt_usbdev_s *priv) +{ + /* Enable ep0 IN and ep0 OUT */ + + g_qh[IMXRT_EP0_OUT].capability = + (DQH_CAPABILITY_MAX_PACKET(CONFIG_USBDEV_EP0_MAXSIZE) | + DQH_CAPABILITY_IOS | DQH_CAPABILITY_ZLT); + + g_qh[IMXRT_EP0_IN].capability = + (DQH_CAPABILITY_MAX_PACKET(CONFIG_USBDEV_EP0_MAXSIZE) | + DQH_CAPABILITY_IOS | DQH_CAPABILITY_ZLT); + + g_qh[IMXRT_EP0_OUT].currdesc = DTD_NEXTDESC_INVALID; + g_qh[IMXRT_EP0_IN].currdesc = DTD_NEXTDESC_INVALID; + + up_flush_dcache((uintptr_t)g_qh, + (uintptr_t)g_qh + (sizeof(struct imxrt_dqh_s) * 2)); + + /* Enable EP0 */ + + imxrt_setbits (USBDEV_ENDPTCTRL0_RXE | USBDEV_ENDPTCTRL0_TXE, + IMXRT_USBDEV_ENDPTCTRL0); +} + +/**************************************************************************** + * Name: imxrt_usbreset + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void imxrt_usbreset(struct imxrt_usbdev_s *priv) +{ + int epphy; + + /* Disable all endpoints. Control endpoint 0 is always enabled */ + + imxrt_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, + IMXRT_USBDEV_ENDPTCTRL1); + imxrt_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, + IMXRT_USBDEV_ENDPTCTRL2); + imxrt_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, + IMXRT_USBDEV_ENDPTCTRL3); + imxrt_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, + IMXRT_USBDEV_ENDPTCTRL4); + imxrt_clrbits (USBDEV_ENDPTCTRL_RXE | USBDEV_ENDPTCTRL_TXE, + IMXRT_USBDEV_ENDPTCTRL5); + + /* Clear all pending interrupts */ + + imxrt_putreg (imxrt_getreg(IMXRT_USBDEV_ENDPTNAK), + IMXRT_USBDEV_ENDPTNAK); + imxrt_putreg (imxrt_getreg(IMXRT_USBDEV_ENDPTSETUPSTAT), + IMXRT_USBDEV_ENDPTSETUPSTAT); + imxrt_putreg (imxrt_getreg(IMXRT_USBDEV_ENDPTCOMPLETE), + IMXRT_USBDEV_ENDPTCOMPLETE); + + /* Wait for all prime operations to have completed and then flush all + * DTDs + */ + + while (imxrt_getreg (IMXRT_USBDEV_ENDPTPRIME) != 0) + ; + imxrt_putreg (IMXRT_ENDPTMASK_ALL, IMXRT_USBDEV_ENDPTFLUSH); + while (imxrt_getreg (IMXRT_USBDEV_ENDPTFLUSH)) + ; + + /* Reset endpoints */ + + for (epphy = 0; epphy < IMXRT_NPHYSENDPOINTS; epphy++) + { + struct imxrt_ep_s *privep = &priv->eplist[epphy]; + + imxrt_cancelrequests (privep, -ESHUTDOWN); + + /* Reset endpoint status */ + + privep->stalled = false; + } + + /* Tell the class driver that we are disconnected. The class + * driver should then accept any new configurations. + */ + + if (priv->driver) + { + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } + + /* Set the interrupt Threshold control interval to 0 */ + + imxrt_chgbits(USBDEV_USBCMD_ITC_MASK, USBDEV_USBCMD_ITCIMME, + IMXRT_USBDEV_USBCMD); + + /* Zero out the Endpoint queue heads */ + + memset ((void *) g_qh, 0, sizeof (g_qh)); + memset ((void *) g_td, 0, sizeof (g_td)); + + up_flush_dcache((uintptr_t)g_qh, (uintptr_t)g_qh + sizeof(g_qh)); + up_flush_dcache((uintptr_t)g_td, (uintptr_t)g_td + sizeof(g_td)); + + /* Set USB address to 0 */ + + imxrt_set_address (priv, 0); + + /* Initialise the Enpoint List Address */ + + imxrt_putreg ((uint32_t)g_qh, IMXRT_USBDEV_ENDPOINTLIST); + + /* EndPoint 0 initialization */ + + imxrt_ep0configure(priv); + + /* Enable Device interrupts */ + + imxrt_putreg(USB_FRAME_INT | USB_ERROR_INT | USBDEV_USBINTR_NAKE | + USBDEV_USBINTR_SLE | USBDEV_USBINTR_URE | USBDEV_USBINTR_PCE | + USBDEV_USBINTR_UE, IMXRT_USBDEV_USBINTR); +} + +/**************************************************************************** + * Name: imxrt_setstate + * + * Description: + * Sets the EP0 state and manages the NAK interrupts + * + ****************************************************************************/ + +static inline void imxrt_ep0state(struct imxrt_usbdev_s *priv, + uint16_t state) +{ + priv->ep0state = state; + + switch (state) + { + case EP0STATE_WAIT_NAK_IN: + imxrt_putreg (IMXRT_ENDPTMASK(IMXRT_EP0_IN), IMXRT_USBDEV_ENDPTNAKEN); + break; + + case EP0STATE_WAIT_NAK_OUT: + imxrt_putreg (IMXRT_ENDPTMASK(IMXRT_EP0_OUT), IMXRT_USBDEV_ENDPTNAKEN); + break; + + default: + imxrt_putreg(0, IMXRT_USBDEV_ENDPTNAKEN); + break; + } +} + +/**************************************************************************** + * Name: imxrt_ep0setup + * + * Description: + * USB Ctrl EP Setup Event. This is logically part of the USB interrupt + * handler. This event occurs when a setup packet is receive on EP0 OUT. + * + ****************************************************************************/ + +static inline void imxrt_ep0setup(struct imxrt_usbdev_s *priv) +{ + struct imxrt_ep_s *privep; + struct usb_ctrlreq_s *ctrl; + uint16_t value; + uint16_t index; + uint16_t len; + + ctrl = &priv->ep0ctrl; + + /* Terminate any pending requests - since all DTDs will have been retired + * because of the setup packet. + */ + + imxrt_cancelrequests(&priv->eplist[IMXRT_EP0_OUT], -EPROTO); + imxrt_cancelrequests(&priv->eplist[IMXRT_EP0_IN], -EPROTO); + + /* Assume NOT stalled */ + + priv->eplist[IMXRT_EP0_OUT].stalled = false; + priv->eplist[IMXRT_EP0_IN].stalled = false; + priv->stalled = false; + + /* Read EP0 setup data */ + + imxrt_readsetup(IMXRT_EP0_OUT, ctrl); + + /* And extract the little-endian 16-bit values to host order */ + + value = GETUINT16(ctrl->value); + index = GETUINT16(ctrl->index); + len = GETUINT16(ctrl->len); + + priv->ep0buf_len = len; + + uinfo("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrl->type, ctrl->req, value, index, len); + + /* Starting a control request - update state */ + + if (ctrl->type & USB_REQ_DIR_IN) + { + imxrt_ep0state (priv, EP0STATE_SETUP_IN); + } + else + { + imxrt_ep0state (priv, EP0STATE_SETUP_OUT); + + if (len > 0) + { + imxrt_ep0state(priv, EP0STATE_SHORTREAD); + imxrt_ep0xfer(IMXRT_EP0_OUT, priv->ep0buf, len); + return; + } + } + + /* Dispatch any non-standard requests */ + + if ((ctrl->type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + imxrt_dispatchrequest(priv, ctrl); + } + else + { + /* Handle standard request. Pick off the things of interest to the USB + * device controller driver; pass what is left to the class driver. + */ + + switch (ctrl->req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_GETSTATUS), 0); + if (!priv->paddrset || len != 2 || + (ctrl->type & USB_REQ_DIR_IN) == 0 || value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrl->type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace( + TRACE_INTDECODE(IMXRT_TRACEINTID_EPGETSTATUS), 0); + privep = imxrt_epfindbyaddr(priv, index); + if (!privep) + { + usbtrace( + TRACE_DEVERROR(IMXRT_TRACEERR_BADEPGETSTATUS), + 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + { + priv->ep0buf[0] = 1; /* Stalled */ + } + else + { + priv->ep0buf[0] = 0; /* Not stalled */ + } + + priv->ep0buf[1] = 0; + + imxrt_ep0xfer (IMXRT_EP0_IN, priv->ep0buf, 2); + imxrt_ep0state (priv, EP0STATE_SHORTWRITE); + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (index == 0) + { + usbtrace( + TRACE_INTDECODE(IMXRT_TRACEINTID_DEVGETSTATUS), + 0); + + /* Features: Remote Wakeup=YES; selfpowered=? */ + + priv->ep0buf[0] = + (priv->selfpowered << + USB_FEATURE_SELFPOWERED) | + (1 << USB_FEATURE_REMOTEWAKEUP); + priv->ep0buf[1] = 0; + + imxrt_ep0xfer(IMXRT_EP0_IN, priv->ep0buf, 2); + imxrt_ep0state (priv, EP0STATE_SHORTWRITE); + } + else + { + usbtrace( + TRACE_DEVERROR(IMXRT_TRACEERR_BADDEVGETSTATUS), + 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_IFGETSTATUS), + 0); + priv->ep0buf[0] = 0; + priv->ep0buf[1] = 0; + + imxrt_ep0xfer(IMXRT_EP0_IN, priv->ep0buf, 2); + imxrt_ep0state (priv, EP0STATE_SHORTWRITE); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_BADGETSTATUS), + 0); + priv->stalled = true; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_CLEARFEATURE), 0); + if ((ctrl->type & USB_REQ_RECIPIENT_MASK) != + USB_REQ_RECIPIENT_ENDPOINT) + { + imxrt_dispatchrequest(priv, ctrl); + } + else if (priv->paddrset != 0 && + value == USB_FEATURE_ENDPOINTHALT && + len == 0 && (privep = imxrt_epfindbyaddr(priv, index)) != NULL) + { + imxrt_epstall(&privep->ep, true); + imxrt_ep0state (priv, EP0STATE_WAIT_NAK_IN); + } + else + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_SETFEATURE), 0); + if (((ctrl->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) && value == USB_FEATURE_TESTMODE) + { + uinfo("test mode: %d\n", index); + } + else if ((ctrl->type & USB_REQ_RECIPIENT_MASK) != + USB_REQ_RECIPIENT_ENDPOINT) + { + imxrt_dispatchrequest(priv, ctrl); + } + else if (priv->paddrset != 0 && + value == USB_FEATURE_ENDPOINTHALT && + len == 0 && (privep = imxrt_epfindbyaddr(priv, index)) != NULL) + { + imxrt_epstall(&privep->ep, false); + imxrt_ep0state (priv, EP0STATE_WAIT_NAK_IN); + } + else + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_EP0SETUPSETADDRESS), + value); + if (((ctrl->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) && + index == 0 && len == 0 && value < 128) + { + /* Save the address. We cannot actually change to the next + * address until the completion of the status phase. + */ + + priv->paddr = ctrl->value[0]; + priv->paddrset = false; + imxrt_ep0state (priv, EP0STATE_WAIT_NAK_IN); + } + else + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_GETSETDESC), 0); + if ((ctrl->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) + { + imxrt_dispatchrequest(priv, ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_GETCONFIG), 0); + if (priv->paddrset && + ((ctrl->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) && + value == 0 && index == 0 && len == 1) + { + imxrt_dispatchrequest(priv, ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_SETCONFIG), 0); + if (((ctrl->type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) && index == 0 && len == 0) + { + imxrt_dispatchrequest(priv, ctrl); + } + else + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_GETSETIF), 0); + imxrt_dispatchrequest(priv, ctrl); + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; + } + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_EP0SETUPSTALLED), + priv->ep0state); + imxrt_epstall(&priv->eplist[IMXRT_EP0_IN].ep, false); + imxrt_epstall(&priv->eplist[IMXRT_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: imxrt_ep0complete + * + * Description: + * Transfer complete handler for Endpoint 0 + * + ****************************************************************************/ + +static void imxrt_ep0complete(struct imxrt_usbdev_s *priv, uint8_t epphy) +{ + struct imxrt_ep_s *privep = &priv->eplist[epphy]; + + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_EP0COMPLETE), + (uint16_t)priv->ep0state); + + switch (priv->ep0state) + { + case EP0STATE_DATA_IN: + if (imxrt_rqempty(privep)) + { + return; + } + + if (imxrt_epcomplete (priv, epphy)) + { + imxrt_ep0state (priv, EP0STATE_WAIT_NAK_OUT); + } + break; + + case EP0STATE_DATA_OUT: + if (imxrt_rqempty(privep)) + { + return; + } + + if (imxrt_epcomplete (priv, epphy)) + { + imxrt_ep0state (priv, EP0STATE_WAIT_NAK_IN); + } + break; + + case EP0STATE_SHORTREAD: + + /* Make sure we have updated data after the DMA transfer. + * This invalidation matches the flush in writedtd(). + */ + + up_invalidate_dcache((uintptr_t)priv->ep0buf, + (uintptr_t)priv->ep0buf + sizeof(priv->ep0buf)); + + imxrt_dispatchrequest(priv, &priv->ep0ctrl); + imxrt_ep0state (priv, EP0STATE_WAIT_NAK_IN); + break; + + case EP0STATE_SHORTWRITE: + imxrt_ep0state (priv, EP0STATE_WAIT_NAK_OUT); + break; + + case EP0STATE_WAIT_STATUS_IN: + imxrt_ep0state (priv, EP0STATE_IDLE); + + /* If we've received a SETADDRESS packet, then we set the address + * now that the status phase has completed + */ + + if (! priv->paddrset && priv->paddr != 0) + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_EP0INSETADDRESS), + (uint16_t)priv->paddr); + imxrt_set_address (priv, priv->paddr); + } + + break; + + case EP0STATE_WAIT_STATUS_OUT: + imxrt_ep0state (priv, EP0STATE_IDLE); + break; + + default: +#ifdef CONFIG_DEBUG_FEATURES + DEBUGASSERT(priv->ep0state != EP0STATE_DATA_IN && + priv->ep0state != EP0STATE_DATA_OUT && + priv->ep0state != EP0STATE_SHORTWRITE && + priv->ep0state != EP0STATE_WAIT_STATUS_IN && + priv->ep0state != EP0STATE_WAIT_STATUS_OUT); +#endif + priv->stalled = true; + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_EP0SETUPSTALLED), + priv->ep0state); + imxrt_epstall(&priv->eplist[IMXRT_EP0_IN].ep, false); + imxrt_epstall(&priv->eplist[IMXRT_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: imxrt_ep0nak + * + * Description: + * Handle a NAK interrupt on EP0 + * + ****************************************************************************/ + +static void imxrt_ep0nak(struct imxrt_usbdev_s *priv, uint8_t epphy) +{ + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_EP0NAK), + (uint16_t)priv->ep0state); + + switch (priv->ep0state) + { + case EP0STATE_WAIT_NAK_IN: + imxrt_ep0xfer (IMXRT_EP0_IN, NULL, 0); + imxrt_ep0state (priv, EP0STATE_WAIT_STATUS_IN); + break; + + case EP0STATE_WAIT_NAK_OUT: + imxrt_ep0xfer (IMXRT_EP0_OUT, NULL, 0); + imxrt_ep0state (priv, EP0STATE_WAIT_STATUS_OUT); + break; + + default: +#ifdef CONFIG_DEBUG_FEATURES + DEBUGASSERT(priv->ep0state != EP0STATE_WAIT_NAK_IN && + priv->ep0state != EP0STATE_WAIT_NAK_OUT); +#endif + priv->stalled = true; + break; + } + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_EP0SETUPSTALLED), + priv->ep0state); + imxrt_epstall(&priv->eplist[IMXRT_EP0_IN].ep, false); + imxrt_epstall(&priv->eplist[IMXRT_EP0_OUT].ep, false); + } +} + +/**************************************************************************** + * Name: imxrt_epcomplete + * + * Description: + * Transfer complete handler for Endpoints other than 0 + * returns whether the request at the head has completed + * + ****************************************************************************/ + +bool imxrt_epcomplete(struct imxrt_usbdev_s *priv, uint8_t epphy) +{ + struct imxrt_ep_s *privep = &priv->eplist[epphy]; + struct imxrt_req_s *privreq = privep->head; + struct imxrt_dtd_s *dtd = &g_td[epphy]; + + if (privreq == NULL) /* This shouldn't really happen */ + { + if (IMXRT_EPPHYOUT(privep->epphy)) + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_EPINQEMPTY), 0); + } + else + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_EPOUTQEMPTY), 0); + } + + return true; + } + + /* Make sure we have updated data after the DMA transfer. + * This invalidation matches the flush in writedtd(). + */ + + up_invalidate_dcache((uintptr_t)dtd, + (uintptr_t)dtd + sizeof(struct imxrt_dtd_s)); + up_invalidate_dcache((uintptr_t)dtd->buffer0, + (uintptr_t)dtd->buffer0 + dtd->xfer_len); + + int xfrd = dtd->xfer_len - (dtd->config >> 16); + + privreq->req.xfrd += xfrd; + + bool complete = true; + if (IMXRT_EPPHYOUT(privep->epphy)) + { + /* read(OUT) completes when request filled, or a short transfer is + * received + */ + + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_EPIN), complete); + } + else + { + /* write(IN) completes when request finished, unless we need to + * terminate with a ZLP + */ + + bool need_zlp = (xfrd == privep->ep.maxpacket) && + ((privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0); + + complete = (privreq->req.xfrd >= privreq->req.len && !need_zlp); + + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_EPOUT), complete); + } + + /* If the transfer is complete, then dequeue and progress any further + * queued requests + */ + + if (complete) + { + privreq = imxrt_rqdequeue (privep); + } + + if (!imxrt_rqempty(privep)) + { + imxrt_progressep(privep); + } + + /* Now it's safe to call the completion callback as it may well submit a + * new request + */ + + if (complete) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + imxrt_reqcomplete(privep, privreq, OK); + } + + return complete; +} + +/**************************************************************************** + * Name: imxrt_usbinterrupt + * + * Description: + * USB interrupt handler + * + ****************************************************************************/ + +static int imxrt_usbinterrupt(int irq, FAR void *context, FAR void *arg) +{ + struct imxrt_usbdev_s *priv = &g_usbdev; + uint32_t disr; + uint32_t portsc1; + uint32_t n; + + usbtrace(TRACE_INTENTRY(IMXRT_TRACEINTID_USB), 0); + + /* Read the interrupts and then clear them */ + + disr = imxrt_getreg(IMXRT_USBDEV_USBSTS); + imxrt_putreg(disr, IMXRT_USBDEV_USBSTS); + + if (disr & USBDEV_USBSTS_URI) + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_DEVRESET), 0); + + imxrt_usbreset(priv); + + usbtrace(TRACE_INTEXIT(IMXRT_TRACEINTID_USB), 0); + return OK; + } + + /* When the device controller enters a suspend state from an active state, + * the SLI bit will be set to a one. + */ + + if (!priv->suspended && (disr & USBDEV_USBSTS_SLI) != 0) + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_SUSPENDED), 0); + + /* Inform the Class driver of the suspend event */ + + priv->suspended = 1; + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + + /* TODO: Perform power management operations here. */ + } + + /* The device controller clears the SLI bit upon exiting from a suspend + * state. This bit can also be cleared by software writing a one to it. + */ + + else if (priv->suspended && (disr & USBDEV_USBSTS_SLI) == 0) + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_RESUMED), 0); + + /* Inform the Class driver of the resume event */ + + priv->suspended = 0; + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } + + /* TODO: Perform power management operations here. */ + } + + if (disr & USBDEV_USBSTS_PCI) + { + portsc1 = imxrt_getreg(IMXRT_USBDEV_PORTSC1); + + if (portsc1 & USBDEV_PRTSC1_HSP) + priv->usbdev.speed = USB_SPEED_HIGH; + else + priv->usbdev.speed = USB_SPEED_FULL; + + if (portsc1 & USBDEV_PRTSC1_FPR) + { + /* FIXME: this occurs because of a J-to-K transition detected + * while the port is in SUSPEND state - presumambly this + * is where the host is resuming the device? + * + * - but do we need to "ack" the interrupt + */ + } + } + +#ifdef CONFIG_IMXRT_USBDEV_FRAME_INTERRUPT + if (disr & USBDEV_USBSTS_SRI) + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_FRAME), 0); + + uint32_t frindex = imxrt_getreg(IMXRT_USBDEV_FRINDEX); + uint16_t frame_num = + (frindex & USBDEV_FRINDEX_LFN_MASK) >> USBDEV_FRINDEX_LFN_SHIFT; + + priv->sof = frame_num; + } +#endif + + if (disr & USBDEV_USBSTS_UEI) + { + /* FIXME: these occur when a transfer results in an error condition + * it is set alongside USBINT if the DTD also had its IOC + * bit set. + */ + } + + if (disr & USBDEV_USBSTS_UI) + { + /* Handle completion interrupts */ + + uint32_t mask = imxrt_getreg (IMXRT_USBDEV_ENDPTCOMPLETE); + + if (mask) + { + /* Clear any NAK interrupt and completion interrupts */ + + imxrt_putreg (mask, IMXRT_USBDEV_ENDPTNAK); + imxrt_putreg (mask, IMXRT_USBDEV_ENDPTCOMPLETE); + + if (mask & IMXRT_ENDPTMASK(0)) + { + imxrt_ep0complete(priv, 0); + } + + if (mask & IMXRT_ENDPTMASK(1)) + { + imxrt_ep0complete(priv, 1); + } + + for (n = 1; n < IMXRT_NLOGENDPOINTS; n++) + { + if (mask & IMXRT_ENDPTMASK((n << 1))) + { + imxrt_epcomplete (priv, (n << 1)); + } + + if (mask & IMXRT_ENDPTMASK((n << 1)+1)) + { + imxrt_epcomplete(priv, (n << 1)+1); + } + } + } + + /* Handle setup interrupts */ + + uint32_t setupstat = imxrt_getreg(IMXRT_USBDEV_ENDPTSETUPSTAT); + if (setupstat) + { + /* Clear the endpoint complete CTRL OUT and IN when a Setup is + * received + */ + + imxrt_putreg(IMXRT_ENDPTMASK(IMXRT_EP0_IN) | + IMXRT_ENDPTMASK(IMXRT_EP0_OUT), + IMXRT_USBDEV_ENDPTCOMPLETE); + + if (setupstat & IMXRT_ENDPTMASK(IMXRT_EP0_OUT)) + { + usbtrace(TRACE_INTDECODE(IMXRT_TRACEINTID_EP0SETUP), + setupstat); + imxrt_ep0setup(priv); + } + } + } + + if (disr & USBDEV_USBSTS_NAKI) + { + uint32_t pending = imxrt_getreg(IMXRT_USBDEV_ENDPTNAK) & + imxrt_getreg(IMXRT_USBDEV_ENDPTNAKEN); + if (pending) + { + /* We shouldn't see NAK interrupts except on Endpoint 0 */ + + if (pending & IMXRT_ENDPTMASK(0)) + { + imxrt_ep0nak(priv, 0); + } + + if (pending & IMXRT_ENDPTMASK(1)) + { + imxrt_ep0nak(priv, 1); + } + } + + /* Clear the interrupts */ + + imxrt_putreg(pending, IMXRT_USBDEV_ENDPTNAK); + } + + usbtrace(TRACE_INTEXIT(IMXRT_TRACEINTID_USB), 0); + return OK; +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_epconfigure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this is the last endpoint to be configured. Some + * hardware needs to take special action when all of the endpoints + * have been configured. + * + ****************************************************************************/ + +static int imxrt_epconfigure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, + bool last) +{ + FAR struct imxrt_ep_s *privep = (FAR struct imxrt_ep_s *)ep; + struct imxrt_dqh_s *dqh = &g_qh[privep->epphy]; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + DEBUGASSERT(desc->addr == ep->eplog); + + /* Initialise EP capabilities */ + + uint16_t maxsize = GETUINT16(desc->mxpacketsize); + if ((desc->attr & USB_EP_ATTR_XFERTYPE_MASK) == USB_EP_ATTR_XFER_ISOC) + { + dqh->capability = (DQH_CAPABILITY_MAX_PACKET(maxsize) | + DQH_CAPABILITY_IOS | + DQH_CAPABILITY_ZLT); + } + else + { + dqh->capability = (DQH_CAPABILITY_MAX_PACKET(maxsize) | + DQH_CAPABILITY_ZLT); + } + + up_flush_dcache((uintptr_t)dqh, + (uintptr_t)dqh + sizeof(struct imxrt_dqh_s)); + + /* Setup Endpoint Control Register */ + + if (IMXRT_EPPHYIN(privep->epphy)) + { + /* Reset the data toggles */ + + uint32_t cfg = USBDEV_ENDPTCTRL_TXR; + + /* Set the endpoint type */ + + switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) + { + case USB_EP_ATTR_XFER_CONTROL: + cfg |= USBDEV_ENDPTCTRL_TXT_CTRL; break; + case USB_EP_ATTR_XFER_ISOC: + cfg |= USBDEV_ENDPTCTRL_TXT_ISOC; break; + case USB_EP_ATTR_XFER_BULK: + cfg |= USBDEV_ENDPTCTRL_TXT_BULK; break; + case USB_EP_ATTR_XFER_INT: + cfg |= USBDEV_ENDPTCTRL_TXT_INTR; break; + } + + imxrt_chgbits (0xffff0000, cfg, + IMXRT_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + else + { + /* Reset the data toggles */ + + uint32_t cfg = USBDEV_ENDPTCTRL_RXR; + + /* Set the endpoint type */ + + switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) + { + case USB_EP_ATTR_XFER_CONTROL: + cfg |= USBDEV_ENDPTCTRL_RXT_CTRL; break; + case USB_EP_ATTR_XFER_ISOC: + cfg |= USBDEV_ENDPTCTRL_RXT_ISOC; break; + case USB_EP_ATTR_XFER_BULK: + cfg |= USBDEV_ENDPTCTRL_RXT_BULK; break; + case USB_EP_ATTR_XFER_INT: + cfg |= USBDEV_ENDPTCTRL_RXT_INTR; break; + } + + imxrt_chgbits (0x0000ffff, cfg, + IMXRT_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + + /* Reset endpoint status */ + + privep->stalled = false; + + /* Enable the endpoint */ + + if (IMXRT_EPPHYIN(privep->epphy)) + { + imxrt_setbits (USBDEV_ENDPTCTRL_TXE, + IMXRT_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + else + { + imxrt_setbits (USBDEV_ENDPTCTRL_RXE, + IMXRT_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + + return OK; +} + +/**************************************************************************** + * Name: imxrt_epdisable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int imxrt_epdisable(FAR struct usbdev_ep_s *ep) +{ + FAR struct imxrt_ep_s *privep = (FAR struct imxrt_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + flags = enter_critical_section(); + + /* Disable Endpoint */ + + if (IMXRT_EPPHYIN(privep->epphy)) + { + imxrt_clrbits (USBDEV_ENDPTCTRL_TXE, + IMXRT_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + else + { + imxrt_clrbits (USBDEV_ENDPTCTRL_RXE, + IMXRT_USBDEV_ENDPTCTRL(privep->epphy >> 1)); + } + + privep->stalled = true; + + /* Cancel any ongoing activity */ + + imxrt_cancelrequests(privep, -ESHUTDOWN); + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: imxrt_epallocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static FAR struct usbdev_req_s *imxrt_epallocreq(FAR struct usbdev_ep_s *ep) +{ + FAR struct imxrt_req_s *privreq; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + + usbtrace(TRACE_EPALLOCREQ, ((FAR struct imxrt_ep_s *)ep)->epphy); + + privreq = (FAR struct imxrt_req_s *)kmm_malloc(sizeof(struct imxrt_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct imxrt_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: imxrt_epfreereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void imxrt_epfreereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *req) +{ + FAR struct imxrt_req_s *privreq = (FAR struct imxrt_req_s *)req; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + + usbtrace(TRACE_EPFREEREQ, ((FAR struct imxrt_ep_s *)ep)->epphy); + kmm_free(privreq); +} + +/**************************************************************************** + * Name: imxrt_epallocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *imxrt_epallocbuffer(FAR struct usbdev_ep_s *ep, uint16_t bytes) +{ + /* The USB peripheral DMA is very forgiving, as the dTD allows the buffer + * to start at any address. Hence, no need for alignment. + */ + + FAR struct imxrt_ep_s *privep = (FAR struct imxrt_ep_s *)ep; + + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + return usbdev_dma_alloc(bytes); +#else + return kmm_malloc(bytes); +#endif +} +#endif + +/**************************************************************************** + * Name: imxrt_epfreebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void imxrt_epfreebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf) +{ + FAR struct imxrt_ep_s *privep = (FAR struct imxrt_ep_s *)ep; + + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + usbdev_dma_free(buf); +#else + kmm_free(buf); +#endif +} +#endif + +/**************************************************************************** + * Name: imxrt_epsubmit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int imxrt_epsubmit(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *req) +{ + FAR struct imxrt_req_s *privreq = (FAR struct imxrt_req_s *)req; + FAR struct imxrt_ep_s *privep = (FAR struct imxrt_ep_s *)ep; + FAR struct imxrt_usbdev_s *priv; + irqstate_t flags; + int ret = OK; + +#ifdef CONFIG_DEBUG_FEATURES + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_INVALIDPARMS), 0); + uinfo("req=%p callback=%p buf=%p ep=%p\n", req, + req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, privep->epphy); + priv = privep->dev; + + if (!priv->driver || priv->usbdev.speed == USB_SPEED_UNKNOWN) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_NOTCONFIGURED), + priv->usbdev.speed); + return -ESHUTDOWN; + } + + /* Handle the request from the class driver */ + + req->result = -EINPROGRESS; + req->xfrd = 0; + + /* Disable Interrupts */ + + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (privep->stalled) + { + ret = -EBUSY; + } + else + { + /* Add the new request to the request queue for the endpoint */ + + if (IMXRT_EPPHYIN(privep->epphy)) + { + usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len); + } + else + { + usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len); + } + + if (imxrt_rqenqueue(privep, privreq)) + { + imxrt_progressep(privep); + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: imxrt_epcancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int imxrt_epcancel(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *req) +{ + FAR struct imxrt_ep_s *privep = (FAR struct imxrt_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, privep->epphy); + + flags = enter_critical_section(); + + /* FIXME: if the request is the first, then we need to flush the EP + * otherwise just remove it from the list + * + * but ... all other implementations cancel all requests ... + */ + + imxrt_cancelrequests(privep, -ESHUTDOWN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: imxrt_epstall + * + * Description: + * Stall or resume and endpoint + * + ****************************************************************************/ + +static int imxrt_epstall(FAR struct usbdev_ep_s *ep, bool resume) +{ + FAR struct imxrt_ep_s *privep = (FAR struct imxrt_ep_s *)ep; + irqstate_t flags; + + /* STALL or RESUME the endpoint */ + + flags = enter_critical_section(); + usbtrace(resume ? TRACE_EPRESUME : TRACE_EPSTALL, privep->epphy); + + uint32_t addr = IMXRT_USBDEV_ENDPTCTRL(privep->epphy >> 1); + uint32_t ctrl_xs = IMXRT_EPPHYIN(privep->epphy) ? + USBDEV_ENDPTCTRL_TXS : USBDEV_ENDPTCTRL_RXS; + uint32_t ctrl_xr = IMXRT_EPPHYIN(privep->epphy) ? + USBDEV_ENDPTCTRL_TXR : USBDEV_ENDPTCTRL_RXR; + + if (resume) + { + privep->stalled = false; + + /* Clear stall and reset the data toggle */ + + imxrt_chgbits (ctrl_xs | ctrl_xr, ctrl_xr, addr); + } + else + { + privep->stalled = true; + + imxrt_setbits (ctrl_xs, addr); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: imxrt_allocep + * + * Description: + * Allocate an endpoint matching the parameters. + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). Zero + * means that any endpoint matching the other requirements will + * suffice. The assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, + * USB_EP_ATTR_XFER_BULK, USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static FAR struct usbdev_ep_s *imxrt_allocep(FAR struct usbdev_s *dev, + uint8_t eplog, + bool in, uint8_t eptype) +{ + FAR struct imxrt_usbdev_s *priv = (FAR struct imxrt_usbdev_s *)dev; + uint32_t epset = IMXRT_EPALLSET & ~IMXRT_EPCTRLSET; + irqstate_t flags; + int epndx = 0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)eplog); + + /* Ignore any direction bits in the logical address */ + + eplog = USB_EPNO(eplog); + + /* A logical address of 0 means that any endpoint will do */ + + if (eplog > 0) + { + /* Otherwise, we will return the endpoint structure only for the + * requested 'logical' endpoint. All of the other checks will still be + * performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (eplog >= IMXRT_NLOGENDPOINTS) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_BADEPNO), (uint16_t)eplog); + return NULL; + } + + /* Convert the logical address to a physical OUT endpoint address and + * remove all of the candidate endpoints from the bitset except for the + * the IN/OUT pair for this logical address. + */ + + epset &= 3 << (eplog << 1); + } + + /* Get the subset matching the requested direction */ + + if (in) + { + epset &= IMXRT_EPINSET; + } + else + { + epset &= IMXRT_EPOUTSET; + } + + /* Get the subset matching the requested type */ + + switch (eptype) + { + case USB_EP_ATTR_XFER_INT: /* Interrupt endpoint */ + epset &= IMXRT_EPINTRSET; + break; + + case USB_EP_ATTR_XFER_BULK: /* Bulk endpoint */ + epset &= IMXRT_EPBULKSET; + break; + + case USB_EP_ATTR_XFER_ISOC: /* Isochronous endpoint */ + epset &= IMXRT_EPISOCSET; + break; + + case USB_EP_ATTR_XFER_CONTROL: /* Control endpoint -- not a valid choice */ + default: + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_BADEPTYPE), (uint16_t)eptype); + return NULL; + } + + /* Is the resulting endpoint supported by the IMXRT3x? */ + + if (epset) + { + /* Yes.. now see if any of the request endpoints are available */ + + flags = enter_critical_section(); + epset &= priv->epavail; + if (epset) + { + /* Select the lowest bit in the set of matching, available + * endpoints + */ + + for (epndx = 2; epndx < IMXRT_NPHYSENDPOINTS; epndx++) + { + uint32_t bit = 1 << epndx; + if ((epset & bit) != 0) + { + /* Mark endpoint no longer available */ + + priv->epavail &= ~bit; + leave_critical_section(flags); + + /* And return the pointer to the standard endpoint + * structure + */ + + return &priv->eplist[epndx].ep; + } + } + + /* Shouldn't get here */ + } + + leave_critical_section(flags); + } + + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_NOEP), (uint16_t)eplog); + return NULL; +} + +/**************************************************************************** + * Name: imxrt_freeep + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void imxrt_freeep(FAR struct usbdev_s *dev, + FAR struct usbdev_ep_s *ep) +{ + FAR struct imxrt_usbdev_s *priv = (FAR struct imxrt_usbdev_s *)dev; + FAR struct imxrt_ep_s *privep = (FAR struct imxrt_ep_s *)ep; + irqstate_t flags; + + usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + flags = enter_critical_section(); + priv->epavail |= (1 << privep->epphy); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: imxrt_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int imxrt_getframe(struct usbdev_s *dev) +{ +#ifdef CONFIG_IMXRT_USBDEV_FRAME_INTERRUPT + FAR struct imxrt_usbdev_s *priv = (FAR struct imxrt_usbdev_s *)dev; + + /* Return last valid value of SOF read by the interrupt handler */ + + usbtrace(TRACE_DEVGETFRAME, (uint16_t)priv->sof); + return priv->sof; +#else + uint32_t frindex = imxrt_getreg(IMXRT_USBDEV_FRINDEX); + uint16_t frame_num = + (frindex & USBDEV_FRINDEX_LFN_MASK) >> USBDEV_FRINDEX_LFN_SHIFT; + + /* Return the last frame number detected by the hardware */ + + usbtrace(TRACE_DEVGETFRAME, frame_num); + + return (int)(frame_num); +#endif +} + +/**************************************************************************** + * Name: imxrt_wakeup + * + * Description: + * Tries to wake up the host connected to this device + * + ****************************************************************************/ + +static int imxrt_wakeup(struct usbdev_s *dev) +{ + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, 0); + + flags = enter_critical_section(); + imxrt_setbits(USBDEV_PRTSC1_FPR, IMXRT_USBDEV_PORTSC1); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: imxrt_selfpowered + * + * Description: + * Sets/clears the device selfpowered feature + * + ****************************************************************************/ + +static int imxrt_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + FAR struct imxrt_usbdev_s *priv = (FAR struct imxrt_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG_FEATURES + if (!dev) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: imxrt_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +static int imxrt_pullup(struct usbdev_s *dev, bool enable) +{ + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + irqstate_t flags = enter_critical_section(); + if (enable) + { + imxrt_setbits (USBDEV_USBCMD_RS, IMXRT_USBDEV_USBCMD); + +#ifdef CONFIG_IMXRT_USB0DEV_NOVBUS + /* Create a 'false' power event on the USB port so the MAC connects */ + + imxrt_clrbits (USBOTG_OTGSC_VD, IMXRT_USBOTG_OTGSC); + imxrt_setbits (USBOTG_OTGSC_VC, IMXRT_USBOTG_OTGSC); +#endif + } + else + { + imxrt_clrbits (USBDEV_USBCMD_RS, IMXRT_USBDEV_USBCMD); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_usbinitialize + * + * Description: + * Initialize USB hardware. + * + * Assumptions: + * - This function is called very early in the initialization sequence + * - PLL initialization is not performed here but should been in + * the low-level boot logic: USB1 PLL must be configured for operation + * at 480MHz + * + ****************************************************************************/ + +void arm_usbinitialize(void) +{ + struct imxrt_usbdev_s *priv = &g_usbdev; + int i; + irqstate_t flags; + + flags = enter_critical_section(); + + /* Initialize the device state structure */ + + memset(priv, 0, sizeof(struct imxrt_usbdev_s)); + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->eplist[IMXRT_EP0_IN].ep; + priv->epavail = IMXRT_EPALLSET & ~IMXRT_EPCTRLSET; + + /* Initialize the endpoint list */ + + for (i = 0; i < IMXRT_NPHYSENDPOINTS; i++) + { + uint32_t bit = 1 << i; + + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + priv->eplist[i].ep.ops = &g_epops; + priv->eplist[i].dev = priv; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + priv->eplist[i].epphy = i; + if (IMXRT_EPPHYIN(i)) + { + priv->eplist[i].ep.eplog = IMXRT_EPPHYIN2LOG(i); + } + else + { + priv->eplist[i].ep.eplog = IMXRT_EPPHYOUT2LOG(i); + } + + /* The maximum packet size may depend on the type of endpoint */ + + if ((IMXRT_EPCTRLSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = IMXRT_EP0MAXPACKET; + } + else if ((IMXRT_EPINTRSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = IMXRT_INTRMAXPACKET; + } + else if ((IMXRT_EPBULKSET & bit) != 0) + { + priv->eplist[i].ep.maxpacket = IMXRT_BULKMAXPACKET; + } + else /* if ((IMXRT_EPISOCSET & bit) != 0) */ + { + priv->eplist[i].ep.maxpacket = IMXRT_ISOCMAXPACKET; + } + } + + /* Clock run */ + + imxrt_clockall_usboh3(); + + /* Disable USB interrupts */ + + imxrt_putreg(0, IMXRT_USBDEV_USBINTR); + + /* Soft reset PHY and enable clock */ + + putreg32(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE, IMXRT_USBPHY2_CTRL_CLR); + + /* Disconnect device */ + + imxrt_pullup(&priv->usbdev, false); + + /* Reset the controller */ + + imxrt_setbits (USBDEV_USBCMD_RST, IMXRT_USBDEV_USBCMD); + while (imxrt_getreg (IMXRT_USBDEV_USBCMD) & USBDEV_USBCMD_RST) + ; + + /* Power up the PHY (turn off power disable) - USBPHYx_PWDn + * Manual: The USB PHY Power-Down Register provides overall control of the + * PHY power state. Before programming this register, the PHY clocks must + * be enabled in registers USBPHYx_CTRLn and + * CCM_ANALOG_USBPHYx_PLL_480_CTRLn. + */ + + imxrt_putreg(0, IMXRT_USBPHY2_PWD); + + /* Program the controller to be the USB device controller */ + + imxrt_putreg (USBDEV_USBMODE_SDIS | USBDEV_USBMODE_SLOM | + USBDEV_USBMODE_CM_DEVICE, IMXRT_USBDEV_USBMODE); + + /* Attach USB controller interrupt handler */ + + irq_attach(IMXRT_IRQ_USBOTG2, imxrt_usbinterrupt, NULL); + up_enable_irq(IMXRT_IRQ_USBOTG2); + + leave_critical_section(flags); + + /* Reset/Re-initialize the USB hardware */ + + imxrt_usbreset(priv); + + return; +} + +/**************************************************************************** + * Name: arm_usbuninitialize + ****************************************************************************/ + +void arm_usbuninitialize(void) +{ + struct imxrt_usbdev_s *priv = &g_usbdev; + irqstate_t flags; + + usbtrace(TRACE_DEVUNINIT, 0); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + flags = enter_critical_section(); + + /* Disconnect device */ + + imxrt_pullup(&priv->usbdev, false); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable and detach IRQs */ + + up_disable_irq(IMXRT_IRQ_USBOTG2); + irq_detach(IMXRT_IRQ_USBOTG2); + + /* Reset the controller */ + + imxrt_setbits (USBDEV_USBCMD_RST, IMXRT_USBDEV_USBCMD); + while (imxrt_getreg (IMXRT_USBDEV_USBCMD) & USBDEV_USBCMD_RST) + ; + + /* Turn off USB power and clocking */ + + /* Power down the PHY */ + + imxrt_putreg(0xffffffff, IMXRT_USBPHY2_PWD); + + /* Stop clock + * NOTE: This will interfere with USB OTG 2 and should probably be removed + * if Device or Host code is expanded to support both OTG Cores. + */ + + imxrt_clockoff_usboh3(); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method + * will be called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG_FEATURES + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + g_usbdev.driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &g_usbdev.usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_BINDFAILED), (uint16_t)-ret); + g_usbdev.driver = NULL; + } + else + { + /* Enable USB controller interrupts */ + + up_enable_irq(IMXRT_IRQ_USBOTG2); + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB + * host, it will first disconnect(). The driver is also requested to + * unbind() and clean up any device state, before this procedure finally + * returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG_FEATURES + if (driver != g_usbdev.driver) + { + usbtrace(TRACE_DEVERROR(IMXRT_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &g_usbdev.usbdev); + + /* Disable USB controller interrupts */ + + up_disable_irq(IMXRT_IRQ_USBOTG2); + + /* Unhook the driver */ + + g_usbdev.driver = NULL; + return OK; +} + diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/readme.md b/Ubiquitous/Nuttx_Fusion_XiUOS/readme.md index 9f1567c1b..0ff4065c1 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/readme.md +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/readme.md @@ -266,23 +266,22 @@ git clone https://git.trustie.net/xuos/kconfig-frontends.git #### 在Nuttx\app_match_nuttx目录下执行 ```shell -chmod +x build.sh - source build.sh ``` #### 执行完毕会跳转到Nuttx\nuttx目录,执行 ```shell -sudo ./tools/configure.sh stm32f4discovery:nsh (应用内核一起编译) +./tools/configure.sh stm32f4discovery:nsh (应用内核一起编译) -sudo ./tools/configure.sh stm32f4discovery:kostest (应用内核分开编译) +./tools/configure.sh stm32f4discovery:kostest (应用内核分开编译) +视情况而定,如果需要前面加sudo ``` #### 然后执行 ```shell -sudo make menuconfig +make menuconfig ``` ##### 开启Nuttx Support CLOCK_MONOTONIC @@ -328,7 +327,9 @@ sudo make menuconfig #### 在当前目录执行编译 ```shell -sudo make -j8 +make +或 +make -j8 ``` make时加上V=1参数可以看到较为详细的编译信息,但是编译过程会比较慢。最后在nuttx下会编译出一个nuttx.bin文件(应用内核一起编译) diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/.config b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/.config new file mode 100644 index 000000000..aa3ade701 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/.config @@ -0,0 +1,380 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Configuration +# +CONFIG_ROOT_DIR="../../../.." +CONFIG_BSP_DIR="." +CONFIG_RT_Thread_DIR="../.." +CONFIG_RTT_DIR="../../rt-thread" + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_BIG_ENDIAN is not set +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=256 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=512 + +# +# kservice optimization +# +# CONFIG_RT_KSERVICE_USING_STDLIB is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_ASM_MEMCPY is not set +CONFIG_RT_DEBUG=y +CONFIG_RT_DEBUG_COLOR=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_USING_MEMHEAP_AUTO_BINDING=y +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_SMALL_MEM is not set +# CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP_AS_HEAP=y +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +# CONFIG_RT_PRINTF_LONGLONG is not set +CONFIG_RT_VER_NUM=0x40004 +CONFIG_ARCH_ARM=y +CONFIG_RT_USING_CPU_FFS=y +CONFIG_ARCH_ARM_CORTEX_M=y +CONFIG_ARCH_ARM_CORTEX_M4=y +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 + +# +# C++ features +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Command shell +# +CONFIG_RT_USING_FINSH=y +CONFIG_RT_USING_MSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# Device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_WORKDIR=y +CONFIG_DFS_FILESYSTEMS_MAX=4 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 +CONFIG_DFS_FD_MAX=16 +# CONFIG_RT_USING_DFS_MNTTABLE is not set +CONFIG_RT_USING_DFS_ELMFAT=y + +# +# elm-chan's FatFs, Generic FAT Filesystem Module +# +CONFIG_RT_DFS_ELM_CODE_PAGE=437 +CONFIG_RT_DFS_ELM_WORD_ACCESS=y +# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set +# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set +# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set +CONFIG_RT_DFS_ELM_USE_LFN_3=y +CONFIG_RT_DFS_ELM_USE_LFN=3 +CONFIG_RT_DFS_ELM_LFN_UNICODE_0=y +# CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set +# CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set +# CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set +CONFIG_RT_DFS_ELM_LFN_UNICODE=0 +CONFIG_RT_DFS_ELM_MAX_LFN=255 +CONFIG_RT_DFS_ELM_DRIVES=2 +CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096 +# CONFIG_RT_DFS_ELM_USE_ERASE is not set +CONFIG_RT_DFS_ELM_REENTRANT=y +CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000 +CONFIG_RT_USING_DFS_DEVFS=y +CONFIG_RT_USING_DFS_ROMFS=y +# CONFIG_RT_USING_DFS_RAMFS is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_PIPE_BUFSZ=512 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +# CONFIG_RT_SERIAL_USING_DMA is not set +CONFIG_RT_SERIAL_RB_BUFSZ=64 +CONFIG_RT_USING_CAN=y +# CONFIG_RT_CAN_USING_HDR is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +CONFIG_RT_USING_I2C=y +# CONFIG_RT_I2C_DEBUG is not set +CONFIG_RT_USING_I2C_BITOPS=y +# CONFIG_RT_I2C_BITOPS_DEBUG is not set +# CONFIG_RT_USING_PHY is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_SDIO is not set +CONFIG_RT_USING_SPI=y +# CONFIG_RT_USING_QSPI is not set +CONFIG_RT_USING_SPI_MSD=y +CONFIG_RT_USING_SFUD=y +CONFIG_RT_SFUD_USING_SFDP=y +CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y +# CONFIG_RT_SFUD_USING_QSPI is not set +CONFIG_RT_SFUD_SPI_MAX_HZ=50000000 +# CONFIG_RT_DEBUG_SFUD is not set +# CONFIG_RT_USING_ENC28J60 is not set +# CONFIG_RT_USING_SPI_WIFI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_WIFI is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# POSIX layer and C standard library +# +CONFIG_RT_USING_LIBC=y +CONFIG_RT_USING_PTHREADS=y +CONFIG_PTHREAD_NUM_MAX=8 +CONFIG_RT_USING_POSIX=y +# CONFIG_RT_USING_POSIX_MMAP is not set +# CONFIG_RT_USING_POSIX_TERMIOS is not set +# CONFIG_RT_USING_POSIX_GETLINE is not set +# CONFIG_RT_USING_POSIX_AIO is not set +CONFIG_RT_LIBC_USING_TIME=y +# CONFIG_RT_USING_MODULE is not set +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# Network +# + +# +# Socket abstraction layer +# +# CONFIG_RT_USING_SAL is not set + +# +# Network interface device +# +# CONFIG_RT_USING_NETDEV is not set + +# +# light weight TCP/IP stack +# +# CONFIG_RT_USING_LWIP is not set + +# +# AT commands +# +# CONFIG_RT_USING_AT is not set + +# +# VBUS(Virtual Software BUS) +# +# CONFIG_RT_USING_VBUS is not set + +# +# Utilities +# +# CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_VAR_EXPORT is not set +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_LWP is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set +CONFIG_SOC_FAMILY_STM32=y +CONFIG_SOC_SERIES_STM32F4=y + +# +# Hardware Drivers Config +# +CONFIG_SOC_STM32F407ZG=y +CONFIG_BSP_USING_GPIO=y +CONFIG_BSP_USING_UART=y +CONFIG_BSP_USING_UART1=y +# CONFIG_BSP_USING_UART2 is not set +# CONFIG_BSP_USING_UART3 is not set +# CONFIG_BSP_USING_UART4 is not set +# CONFIG_BSP_USING_I2C1 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_CH438 is not set +CONFIG_BSP_USING_USB=y +CONFIG_BSP_USING_STM32_USBH=y +CONFIG_USB_BUS_NAME="usb" +CONFIG_USB_DRIVER_NAME="usb_drv" +CONFIG_USB_DEVICE_NAME="usb_dev" +# CONFIG_BSP_USING_RNG is not set +# CONFIG_BSP_USING_UDID is not set + +# +# MicroPython +# +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# More Drivers +# +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_DRV_USING_OV2640 is not set + +# +# APP_Framework +# + +# +# Framework +# +CONFIG_TRANSFORM_LAYER_ATTRIUBUTE=y +CONFIG_ADD_XIZI_FETURES=y +# CONFIG_ADD_NUTTX_FETURES is not set +# CONFIG_ADD_RTTHREAD_FETURES is not set +# CONFIG_SUPPORT_SENSOR_FRAMEWORK is not set +# CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set +# CONFIG_SUPPORT_KNOWING_FRAMEWORK is not set +# CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set + +# +# Security +# +# CONFIG_CRYPTO is not set + +# +# Applications +# + +# +# config stack size and priority of main task +# +CONFIG_MAIN_KTASK_STACK_SIZE=1024 + +# +# ota app +# +# CONFIG_APPLICATION_OTA is not set + +# +# test app +# +# CONFIG_USER_TEST is not set + +# +# connection app +# +# CONFIG_APPLICATION_CONNECTION is not set + +# +# control app +# + +# +# knowing app +# +# CONFIG_APPLICATION_KNOWING is not set + +# +# sensor app +# +# CONFIG_APPLICATION_SENSOR is not set +# CONFIG_USING_EMBEDDED_DATABASE_APP is not set + +# +# lib +# +CONFIG_APP_SELECT_NEWLIB=y +# CONFIG_APP_SELECT_OTHER_LIB is not set +# CONFIG_LIB_USING_CJSON is not set +# CONFIG_LIB_USING_QUEUE is not set +# CONFIG_LIB_LV is not set +# CONFIG_USING_EMBEDDED_DATABASE is not set diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/.gitignore b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/.gitignore new file mode 100644 index 000000000..331082a3e --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/.gitignore @@ -0,0 +1,243 @@ +# this +*.map +*.dblite +*.bin +*.axf +*.old +*~ +*.o +*.bak +*.dep +*.i +*.d +*.uimg +GPATH +GRTAGS +GTAGS +JLinkLog.txt +JLinkSettings.ini +DebugConfig/ +RTE/ +settings/ +*.uvguix* +cconfig.h + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.con diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/Kconfig new file mode 100644 index 000000000..32ee87ce8 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/Kconfig @@ -0,0 +1,29 @@ +mainmenu "RT-Thread Configuration" + +config ROOT_DIR + string + default "../../../.." + +config BSP_DIR + string + default "." + +config RT_Thread_DIR + string + default "../.." + +config RTT_DIR + string + default "../../rt-thread" + +config APP_DIR + string + default "../../../../APP_Framework" + +source "$RTT_DIR/Kconfig" +source "$RTT_DIR/bsp/stm32/libraries/Kconfig" +source "board/Kconfig" +source "$RT_Thread_DIR/micropython/Kconfig" +source "$RT_Thread_DIR/app_match_rt-thread/Kconfig" +source "$ROOT_DIR/APP_Framework/Kconfig" + diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/README.md b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/README.md new file mode 100644 index 000000000..4f30d274a --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/README.md @@ -0,0 +1,91 @@ +# STM32F407最小系统板说明 + +采用ST公司的32位ARM-Cortex M4内核的STM32F407 + +## 以下为引脚硬件的连接表 + +## **W25q16(SPI1 )** + +| 引脚 | 作用 | 引脚序号 | W25q16 | +| ---- | --------- | -------- | --------| +| PA5 | SPI1_SCK | 41 | CLK | +| PA6 | SPI1_MISO | 42 | DO | +| PA7 | SPI1_MOSI | 43 | DI | +| PB0 | SpiFlash_nCS | 46 | nCS | + +## **CRF1278-L3(SPI2 )** + +| 引脚 | 作用 | 引脚序号 | CRF1278 | +| ---- | --------- | -------- | --------| +| PB13 | SPI2_SCK | 74 | SCK | +| PC2 | SPI2_MISO | 28 | MISO | +| PC3 | SPI2_MOSI | 29 | MOSI | +| PC6 | LORA_nCS | 96 | NSS | + +## **XPT2046(SPI3)** + +| 引脚 | 作用 | 引脚序号 | XPT2046 | +| ---- | --------- | -------- | --------| +| PB3 | SPI3_SCK | 133 | DCLK | +| PB4 | SPI3_MISO | 134 | DOUT | +| PB5 | SPI3_MOSI | 135 | DIN | +| PG13 | T_nCS | 128 | CS | + +## **sensor(I2C1)** + +| PB6 | I2C_SCL | +| ---- | ---------- | +| PB7 | I2C_SDA | + + +## **TTL_debug(uart1)** +| 引脚 | 作用 | 引脚序号 | TTL_debug | +| ---- | ----------|------------ |--------- | +| PA9 | USART1_TX | 101 |USART1_RX | +| PA10 | USART1_RX | 102 |USART1_TX | + +## **NB/4G(uart2)** + +| 引脚 | 作用 | 引脚序号 | NB/4G | +| ---- | ----------|------------ |--------- | +| PA2 | USART2_TX | 36 |USART2_RX | +| PA3 | USART2_RX | 37 |USART2_TX | + +## **Ethernet/WIFI(uart3)** + +| 引脚 | 作用 | 引脚序号 | Ethernet/WIFI | +| ---- | ----------|------------ |------------- | +| PB10 | USART3_TX | 69 |UART0_RXD | +| PB11 | USART3_RX | 70 |UART0_TXD | + + +## **BT-HC08(uart4)** + +| 引脚 | 作用 | 引脚序号 | BT-HC08 | +| -----------| ---------|------------ |--------- | +| PA0_WAKEUP | UART4_TX | 34 | RXD | +| PA1 | UART4_RX | 35 | TXD | + +## **SD** + +| 引脚 | 作用 | 引脚序号 | TF-01A | +| ---- | --------- | -------- | ---------| +| PC10 | SDIO_D2 | 114 | DATA2 | +| PC11 | SDIO_D3 | 115 | DATA3 | +| PD2 | SDIO_CMD | 116 | CMD | +| PC12 | SDIO_CK | 113 | CLK | +| PC8 | SDIO_D0 | 98 | DATA0 | +| PC9 | SDIO_D1 | 99 | DATA1 | + +## **USB-HOST** + +| 引脚 | 作用 | 引脚序号 | USB-S | +| -----------| --------- |------------ |------------| +| PA12 | USB_OTG_DP | 104 | USB_OTG_DP | +| PA11 | USB_OTG_DM | 103 | USB_OTG_DM | + +## **CAN** +| 引脚 | 作用 | 引脚序号 | USB-S | +| -----------| --------- |------------ |---------| +| PB8 | CAN1_RX | 139 | CAN1_TX | +| PB9 | CAN1_TX | 140 | CAN1_RX | diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/SConscript b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/SConscript new file mode 100644 index 000000000..20f7689c5 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/SConscript @@ -0,0 +1,15 @@ +# for module compiling +import os +Import('RTT_ROOT') +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/SConstruct b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/SConstruct new file mode 100644 index 000000000..533cf2e28 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/SConstruct @@ -0,0 +1,92 @@ +import os +import sys +import rtconfig +import SCons + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../rt-thread') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +try: + from building import * +except: + print('Cannot found RT-Thread root directory, please check RTT_ROOT') + print(RTT_ROOT) + exit(-1) + +TARGET = 'rt-thread.' + rtconfig.TARGET_EXT + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +AddOption('--compiledb', + dest = 'compiledb', + action = 'store_true', + default = False, + help = 'generate compile_commands.json') + +if GetOption('compiledb'): + if int(SCons.__version__.split('.')[0]) >= 4: + env['COMPILATIONDB_USE_ABSPATH'] = True + env.Tool('compilation_db') + env.CompilationDatabase('compile_commands.json') + else: + print('Warning: --compiledb only support on SCons 4.0+') + +if rtconfig.PLATFORM == 'iar': + env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) + env.Replace(ARFLAGS = ['']) + env.Replace(LINKCOM = env["LINKCOM"] + ' --map rt-thread.map') + +Export('RTT_ROOT') +Export('rtconfig') + +SDK_ROOT = os.path.abspath('./') + +#if os.path.exists(SDK_ROOT + '/libraries'): +# libraries_path_prefix = SDK_ROOT + '/libraries' +#else: +# libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries' + +libraries_path_prefix = RTT_ROOT + '/bsp/stm32/libraries' + +SDK_LIB = libraries_path_prefix +Export('SDK_LIB') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +stm32_library = 'STM32F4xx_HAL' +rtconfig.BSP_LIBRARY_TYPE = stm32_library + +# include libraries +objs.extend(SConscript(os.path.join(libraries_path_prefix, stm32_library, 'SConscript'))) + +# include drivers +objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript'))) + +# include more drivers +objs.extend(SConscript(os.getcwd() + '/../../app_match_rt-thread/SConscript')) + +# include APP_Framework/Framework +objs.extend(SConscript(os.getcwd() + '/../../../../APP_Framework/Framework/SConscript')) + +# include APP_Framework/Applications +objs.extend(SConscript(os.getcwd() + '/../../../../APP_Framework/Applications/SConscript')) + +# include APP_Framework/lib +objs.extend(SConscript(os.getcwd() + '/../../../../APP_Framework/lib/SConscript')) + +# include Ubiquitous/RT-Thread/micropython +objs.extend(SConscript(os.getcwd() + '/../../micropython/SConscript')) + +# make a building +DoBuilding(TARGET, objs) diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/applications/SConscript b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/applications/SConscript new file mode 100644 index 000000000..efae61d10 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/applications/SConscript @@ -0,0 +1,12 @@ +import rtconfig +from building import * + +cwd = GetCurrentDir() +CPPPATH = [cwd] +src = Split(""" +main.c +""") + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/applications/main.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/applications/main.c new file mode 100644 index 000000000..865256fee --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/applications/main.c @@ -0,0 +1,51 @@ +/* + * @Author: chunyexixiaoyu + * @Date: 2021-09-24 16:33:15 + * @LastEditTime: 2021-09-24 15:48:30 + * @LastEditors: Please set LastEditors + * @Description: In User Settings Edit + * @FilePath: \xiuos\Ubiquitous\RT_Thread\bsp\stm32f407-atk-coreboard\applications\main.c + */ + +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +#include +#include +#include +#include +#ifdef RT_USING_POSIX +#include +#include +#include +#include +#include +#include +#ifdef RT_USING_POSIX_TERMIOS +#include +#endif +#endif + +#define LED0_PIN GET_PIN(G, 15) +extern int FrameworkInit(); +int main(void) +{ + int count = 1; + rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT); + rt_thread_mdelay(100); + FrameworkInit(); + printf("XIUOS stm32f4 build %s %s\n",__DATE__,__TIME__); + while (count++) + { + rt_pin_write(LED0_PIN, PIN_HIGH); + rt_thread_mdelay(500); + rt_pin_write(LED0_PIN, PIN_LOW); + rt_thread_mdelay(500); + } +} diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/applications/uart_test.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/applications/uart_test.c new file mode 100644 index 000000000..aeb9e8859 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/applications/uart_test.c @@ -0,0 +1,43 @@ +/* + * @Author: yongliang + * @Date: 2022-03-31 16:00:00 + * @Description: uart_test code + * @FilePath: \xiuos\Ubiquitous\RT_Thread\aiit_board\stm32f407_mini_board\applications\uart_test.c + */ + +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +#include +#include +#include +#include + +int main (void) +{ + /*1.设置系统中断优先组*/ + + /*2.串口初始化*/ + while(1) + { + if(USART_RX_STA&0X8000) + { + len =USART_RX_STA&0X3fff; + printf("发送的消息为:\r\n"); + for(t=0;t +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h new file mode 100644 index 000000000..c31746fa0 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h @@ -0,0 +1,442 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32f4xx_hal_conf.h. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED + + /* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +#define HAL_CAN_MODULE_ENABLED +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +#define HAL_SRAM_MODULE_ENABLED +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_I2C_MODULE_ENABLED +/* #define HAL_I2S_MODULE_ENABLED */ +#define HAL_IWDG_MODULE_ENABLED +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_RNG_MODULE_ENABLED */ +#define HAL_RTC_MODULE_ENABLED +/* #define HAL_SAI_MODULE_ENABLED */ +#define HAL_SD_MODULE_ENABLED +/* #define HAL_MMC_MODULE_ENABLED */ +#define HAL_SPI_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +/* #define HAL_QSPI_MODULE_ENABLED */ +/* #define HAL_QSPI_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848_PHY_ADDRESS Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x000000FFU) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU) + +#define PHY_READ_TO ((uint32_t)0x0000FFFFU) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ +#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Inc/stm32f4xx_it.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Inc/stm32f4xx_it.h new file mode 100644 index 000000000..dd3a82473 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Inc/stm32f4xx_it.h @@ -0,0 +1,84 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f4xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * + * COPYRIGHT(c) 2018 STMicroelectronics + * + * 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 of STMicroelectronics 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 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. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_IT_H +#define __STM32F4xx_IT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_IT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/main.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/main.c new file mode 100644 index 000000000..bb1dd2e72 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/main.c @@ -0,0 +1,920 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2018 STMicroelectronics + * + * 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 of STMicroelectronics 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 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. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +CAN_HandleTypeDef hcan1; + +I2C_HandleTypeDef hi2c1; + +IWDG_HandleTypeDef hiwdg; + +RTC_HandleTypeDef hrtc; + +SD_HandleTypeDef hsd; + +SPI_HandleTypeDef hspi1; +SPI_HandleTypeDef hspi2; +SPI_HandleTypeDef hspi3; + +TIM_HandleTypeDef htim2; +TIM_HandleTypeDef htim11; +TIM_HandleTypeDef htim13; +TIM_HandleTypeDef htim14; + +UART_HandleTypeDef huart4; +UART_HandleTypeDef huart1; +UART_HandleTypeDef huart2; +UART_HandleTypeDef huart3; + +SRAM_HandleTypeDef hsram1; + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +static void MX_GPIO_Init(void); +static void MX_USART1_UART_Init(void); +static void MX_USART3_UART_Init(void); +static void MX_RTC_Init(void); +static void MX_IWDG_Init(void); +static void MX_TIM14_Init(void); +static void MX_TIM13_Init(void); +static void MX_TIM11_Init(void); +static void MX_SDIO_SD_Init(void); +static void MX_TIM2_Init(void); +static void MX_SPI2_Init(void); +static void MX_FSMC_Init(void); +static void MX_UART4_Init(void); +static void MX_USART2_UART_Init(void); +static void MX_CAN1_Init(void); +static void MX_I2C1_Init(void); +static void MX_SPI1_Init(void); +static void MX_SPI3_Init(void); +/* USER CODE BEGIN PFP */ +/* Private function prototypes -----------------------------------------------*/ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_USART1_UART_Init(); + MX_USART3_UART_Init(); + MX_RTC_Init(); + MX_IWDG_Init(); + MX_TIM14_Init(); + MX_TIM13_Init(); + MX_TIM11_Init(); + MX_SDIO_SD_Init(); + MX_TIM2_Init(); + MX_SPI2_Init(); + MX_FSMC_Init(); + MX_UART4_Init(); + MX_USART2_UART_Init(); + MX_CAN1_Init(); + MX_I2C1_Init(); + MX_SPI1_Init(); + MX_SPI3_Init(); + /* USER CODE BEGIN 2 */ + + /* USER CODE END 2 */ + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) + { + + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + + } + /* USER CODE END 3 */ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + + /** Configure the main internal regulator output voltage + */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE + |RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 4; + RCC_OscInitStruct.PLL.PLLN = 168; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) + { + Error_Handler(); + } + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } +} + +/** + * @brief CAN1 Initialization Function + * @param None + * @retval None + */ +static void MX_CAN1_Init(void) +{ + + /* USER CODE BEGIN CAN1_Init 0 */ + + /* USER CODE END CAN1_Init 0 */ + + /* USER CODE BEGIN CAN1_Init 1 */ + + /* USER CODE END CAN1_Init 1 */ + hcan1.Instance = CAN1; + hcan1.Init.Prescaler = 16; + hcan1.Init.Mode = CAN_MODE_NORMAL; + hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; + hcan1.Init.TimeSeg1 = CAN_BS1_1TQ; + hcan1.Init.TimeSeg2 = CAN_BS2_1TQ; + hcan1.Init.TimeTriggeredMode = DISABLE; + hcan1.Init.AutoBusOff = DISABLE; + hcan1.Init.AutoWakeUp = DISABLE; + hcan1.Init.AutoRetransmission = DISABLE; + hcan1.Init.ReceiveFifoLocked = DISABLE; + hcan1.Init.TransmitFifoPriority = DISABLE; + if (HAL_CAN_Init(&hcan1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN CAN1_Init 2 */ + + /* USER CODE END CAN1_Init 2 */ + +} + +/** + * @brief I2C1 Initialization Function + * @param None + * @retval None + */ +static void MX_I2C1_Init(void) +{ + + /* USER CODE BEGIN I2C1_Init 0 */ + + /* USER CODE END I2C1_Init 0 */ + + /* USER CODE BEGIN I2C1_Init 1 */ + + /* USER CODE END I2C1_Init 1 */ + hi2c1.Instance = I2C1; + hi2c1.Init.ClockSpeed = 100000; + hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; + hi2c1.Init.OwnAddress1 = 0; + hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + hi2c1.Init.OwnAddress2 = 0; + hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + if (HAL_I2C_Init(&hi2c1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN I2C1_Init 2 */ + + /* USER CODE END I2C1_Init 2 */ + +} + +/** + * @brief IWDG Initialization Function + * @param None + * @retval None + */ +static void MX_IWDG_Init(void) +{ + + /* USER CODE BEGIN IWDG_Init 0 */ + + /* USER CODE END IWDG_Init 0 */ + + /* USER CODE BEGIN IWDG_Init 1 */ + + /* USER CODE END IWDG_Init 1 */ + hiwdg.Instance = IWDG; + hiwdg.Init.Prescaler = IWDG_PRESCALER_4; + hiwdg.Init.Reload = 4095; + if (HAL_IWDG_Init(&hiwdg) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN IWDG_Init 2 */ + + /* USER CODE END IWDG_Init 2 */ + +} + +/** + * @brief RTC Initialization Function + * @param None + * @retval None + */ +static void MX_RTC_Init(void) +{ + + /* USER CODE BEGIN RTC_Init 0 */ + + /* USER CODE END RTC_Init 0 */ + + /* USER CODE BEGIN RTC_Init 1 */ + + /* USER CODE END RTC_Init 1 */ + /** Initialize RTC Only + */ + hrtc.Instance = RTC; + hrtc.Init.HourFormat = RTC_HOURFORMAT_24; + hrtc.Init.AsynchPrediv = 127; + hrtc.Init.SynchPrediv = 255; + hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; + hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + if (HAL_RTC_Init(&hrtc) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN RTC_Init 2 */ + + /* USER CODE END RTC_Init 2 */ + +} + +/** + * @brief SDIO Initialization Function + * @param None + * @retval None + */ +static void MX_SDIO_SD_Init(void) +{ + + /* USER CODE BEGIN SDIO_Init 0 */ + + /* USER CODE END SDIO_Init 0 */ + + /* USER CODE BEGIN SDIO_Init 1 */ + + /* USER CODE END SDIO_Init 1 */ + hsd.Instance = SDIO; + hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; + hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; + hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; + hsd.Init.BusWide = SDIO_BUS_WIDE_1B; + hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; + hsd.Init.ClockDiv = 0; + if (HAL_SD_Init(&hsd) != HAL_OK) + { + Error_Handler(); + } + if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SDIO_Init 2 */ + + /* USER CODE END SDIO_Init 2 */ + +} + +/** + * @brief SPI1 Initialization Function + * @param None + * @retval None + */ +static void MX_SPI1_Init(void) +{ + + /* USER CODE BEGIN SPI1_Init 0 */ + + /* USER CODE END SPI1_Init 0 */ + + /* USER CODE BEGIN SPI1_Init 1 */ + + /* USER CODE END SPI1_Init 1 */ + /* SPI1 parameter configuration*/ + hspi1.Instance = SPI1; + hspi1.Init.Mode = SPI_MODE_MASTER; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_SOFT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLE; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi1.Init.CRCPolynomial = 10; + if (HAL_SPI_Init(&hspi1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SPI1_Init 2 */ + + /* USER CODE END SPI1_Init 2 */ + +} + +/** + * @brief SPI2 Initialization Function + * @param None + * @retval None + */ +static void MX_SPI2_Init(void) +{ + + /* USER CODE BEGIN SPI2_Init 0 */ + + /* USER CODE END SPI2_Init 0 */ + + /* USER CODE BEGIN SPI2_Init 1 */ + + /* USER CODE END SPI2_Init 1 */ + /* SPI2 parameter configuration*/ + hspi2.Instance = SPI2; + hspi2.Init.Mode = SPI_MODE_MASTER; + hspi2.Init.Direction = SPI_DIRECTION_2LINES; + hspi2.Init.DataSize = SPI_DATASIZE_8BIT; + hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi2.Init.NSS = SPI_NSS_SOFT; + hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi2.Init.TIMode = SPI_TIMODE_DISABLE; + hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi2.Init.CRCPolynomial = 10; + if (HAL_SPI_Init(&hspi2) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SPI2_Init 2 */ + + /* USER CODE END SPI2_Init 2 */ + +} + +/** + * @brief SPI3 Initialization Function + * @param None + * @retval None + */ +static void MX_SPI3_Init(void) +{ + + /* USER CODE BEGIN SPI3_Init 0 */ + + /* USER CODE END SPI3_Init 0 */ + + /* USER CODE BEGIN SPI3_Init 1 */ + + /* USER CODE END SPI3_Init 1 */ + /* SPI3 parameter configuration*/ + hspi3.Instance = SPI3; + hspi3.Init.Mode = SPI_MODE_MASTER; + hspi3.Init.Direction = SPI_DIRECTION_2LINES; + hspi3.Init.DataSize = SPI_DATASIZE_8BIT; + hspi3.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi3.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi3.Init.NSS = SPI_NSS_SOFT; + hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi3.Init.TIMode = SPI_TIMODE_DISABLE; + hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi3.Init.CRCPolynomial = 10; + if (HAL_SPI_Init(&hspi3) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SPI3_Init 2 */ + + /* USER CODE END SPI3_Init 2 */ + +} + +/** + * @brief TIM2 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM2_Init(void) +{ + + /* USER CODE BEGIN TIM2_Init 0 */ + + /* USER CODE END TIM2_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ + htim2.Instance = TIM2; + htim2.Init.Prescaler = 0; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + htim2.Init.Period = 0; + htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim2) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM2_Init 2 */ + + /* USER CODE END TIM2_Init 2 */ + +} + +/** + * @brief TIM11 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM11_Init(void) +{ + + /* USER CODE BEGIN TIM11_Init 0 */ + + /* USER CODE END TIM11_Init 0 */ + + /* USER CODE BEGIN TIM11_Init 1 */ + + /* USER CODE END TIM11_Init 1 */ + htim11.Instance = TIM11; + htim11.Init.Prescaler = 0; + htim11.Init.CounterMode = TIM_COUNTERMODE_UP; + htim11.Init.Period = 0; + htim11.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim11.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim11) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM11_Init 2 */ + + /* USER CODE END TIM11_Init 2 */ + +} + +/** + * @brief TIM13 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM13_Init(void) +{ + + /* USER CODE BEGIN TIM13_Init 0 */ + + /* USER CODE END TIM13_Init 0 */ + + /* USER CODE BEGIN TIM13_Init 1 */ + + /* USER CODE END TIM13_Init 1 */ + htim13.Instance = TIM13; + htim13.Init.Prescaler = 0; + htim13.Init.CounterMode = TIM_COUNTERMODE_UP; + htim13.Init.Period = 0; + htim13.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim13.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim13) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM13_Init 2 */ + + /* USER CODE END TIM13_Init 2 */ + +} + +/** + * @brief TIM14 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM14_Init(void) +{ + + /* USER CODE BEGIN TIM14_Init 0 */ + + /* USER CODE END TIM14_Init 0 */ + + /* USER CODE BEGIN TIM14_Init 1 */ + + /* USER CODE END TIM14_Init 1 */ + htim14.Instance = TIM14; + htim14.Init.Prescaler = 0; + htim14.Init.CounterMode = TIM_COUNTERMODE_UP; + htim14.Init.Period = 0; + htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim14) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM14_Init 2 */ + + /* USER CODE END TIM14_Init 2 */ + +} + +/** + * @brief UART4 Initialization Function + * @param None + * @retval None + */ +static void MX_UART4_Init(void) +{ + + /* USER CODE BEGIN UART4_Init 0 */ + + /* USER CODE END UART4_Init 0 */ + + /* USER CODE BEGIN UART4_Init 1 */ + + /* USER CODE END UART4_Init 1 */ + huart4.Instance = UART4; + huart4.Init.BaudRate = 115200; + huart4.Init.WordLength = UART_WORDLENGTH_8B; + huart4.Init.StopBits = UART_STOPBITS_1; + huart4.Init.Parity = UART_PARITY_NONE; + huart4.Init.Mode = UART_MODE_TX_RX; + huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart4.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart4) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN UART4_Init 2 */ + + /* USER CODE END UART4_Init 2 */ + +} + +/** + * @brief USART1 Initialization Function + * @param None + * @retval None + */ +static void MX_USART1_UART_Init(void) +{ + + /* USER CODE BEGIN USART1_Init 0 */ + + /* USER CODE END USART1_Init 0 */ + + /* USER CODE BEGIN USART1_Init 1 */ + + /* USER CODE END USART1_Init 1 */ + huart1.Instance = USART1; + huart1.Init.BaudRate = 115200; + huart1.Init.WordLength = UART_WORDLENGTH_8B; + huart1.Init.StopBits = UART_STOPBITS_1; + huart1.Init.Parity = UART_PARITY_NONE; + huart1.Init.Mode = UART_MODE_TX_RX; + huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart1.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USART1_Init 2 */ + + /* USER CODE END USART1_Init 2 */ + +} + +/** + * @brief USART2 Initialization Function + * @param None + * @retval None + */ +static void MX_USART2_UART_Init(void) +{ + + /* USER CODE BEGIN USART2_Init 0 */ + + /* USER CODE END USART2_Init 0 */ + + /* USER CODE BEGIN USART2_Init 1 */ + + /* USER CODE END USART2_Init 1 */ + huart2.Instance = USART2; + huart2.Init.BaudRate = 115200; + huart2.Init.WordLength = UART_WORDLENGTH_8B; + huart2.Init.StopBits = UART_STOPBITS_1; + huart2.Init.Parity = UART_PARITY_NONE; + huart2.Init.Mode = UART_MODE_TX_RX; + huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart2.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart2) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USART2_Init 2 */ + + /* USER CODE END USART2_Init 2 */ + +} + +/** + * @brief USART3 Initialization Function + * @param None + * @retval None + */ +static void MX_USART3_UART_Init(void) +{ + + /* USER CODE BEGIN USART3_Init 0 */ + + /* USER CODE END USART3_Init 0 */ + + /* USER CODE BEGIN USART3_Init 1 */ + + /* USER CODE END USART3_Init 1 */ + huart3.Instance = USART3; + huart3.Init.BaudRate = 115200; + huart3.Init.WordLength = UART_WORDLENGTH_8B; + huart3.Init.StopBits = UART_STOPBITS_1; + huart3.Init.Parity = UART_PARITY_NONE; + huart3.Init.Mode = UART_MODE_TX_RX; + huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart3.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart3) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USART3_Init 2 */ + + /* USER CODE END USART3_Init 2 */ + +} + +/** + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +static void MX_GPIO_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOG, GPIO_PIN_11|GPIO_PIN_14, GPIO_PIN_RESET); + + /*Configure GPIO pins : PG11 PG14 */ + GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_14; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + /*Configure GPIO pin : PG13 */ + GPIO_InitStruct.Pin = GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + +} + +/* FSMC initialization function */ +static void MX_FSMC_Init(void) +{ + + /* USER CODE BEGIN FSMC_Init 0 */ + + /* USER CODE END FSMC_Init 0 */ + + FSMC_NORSRAM_TimingTypeDef Timing = {0}; + + /* USER CODE BEGIN FSMC_Init 1 */ + + /* USER CODE END FSMC_Init 1 */ + + /** Perform the SRAM1 memory initialization sequence + */ + hsram1.Instance = FSMC_NORSRAM_DEVICE; + hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE; + /* hsram1.Init */ + hsram1.Init.NSBank = FSMC_NORSRAM_BANK3; + hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE; + hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM; + hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16; + hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE; + hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW; + hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE; + hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS; + hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE; + hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE; + hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE; + hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE; + hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE; + hsram1.Init.PageSize = FSMC_PAGE_SIZE_NONE; + /* Timing */ + Timing.AddressSetupTime = 15; + Timing.AddressHoldTime = 15; + Timing.DataSetupTime = 255; + Timing.BusTurnAroundDuration = 15; + Timing.CLKDivision = 16; + Timing.DataLatency = 17; + Timing.AccessMode = FSMC_ACCESS_MODE_A; + /* ExtTiming */ + + if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK) + { + Error_Handler( ); + } + + /* USER CODE BEGIN FSMC_Init 2 */ + + /* USER CODE END FSMC_Init 2 */ +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + while(1) + { + } + /* USER CODE END Error_Handler_Debug */ +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c new file mode 100644 index 000000000..e2a1e797a --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c @@ -0,0 +1,1025 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : stm32f4xx_hal_msp.c + * Description : This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2018 STMicroelectronics + * + * 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 of STMicroelectronics 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 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. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/** +* @brief CAN MSP Initialization +* This function configures the hardware resources used in this example +* @param hcan: CAN handle pointer +* @retval None +*/ +void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hcan->Instance==CAN1) + { + /* USER CODE BEGIN CAN1_MspInit 0 */ + + /* USER CODE END CAN1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_CAN1_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**CAN1 GPIO Configuration + PB8 ------> CAN1_RX + PB9 ------> CAN1_TX + */ + GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF9_CAN1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN CAN1_MspInit 1 */ + + /* USER CODE END CAN1_MspInit 1 */ + } + +} + +/** +* @brief CAN MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hcan: CAN handle pointer +* @retval None +*/ +void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan) +{ + if(hcan->Instance==CAN1) + { + /* USER CODE BEGIN CAN1_MspDeInit 0 */ + + /* USER CODE END CAN1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_CAN1_CLK_DISABLE(); + + /**CAN1 GPIO Configuration + PB8 ------> CAN1_RX + PB9 ------> CAN1_TX + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9); + + /* USER CODE BEGIN CAN1_MspDeInit 1 */ + + /* USER CODE END CAN1_MspDeInit 1 */ + } + +} + +/** +* @brief I2C MSP Initialization +* This function configures the hardware resources used in this example +* @param hi2c: I2C handle pointer +* @retval None +*/ +void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hi2c->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspInit 0 */ + + /* USER CODE END I2C1_MspInit 0 */ + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**I2C1 GPIO Configuration + PB6 ------> I2C1_SCL + PB7 ------> I2C1_SDA + */ + GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_I2C1_CLK_ENABLE(); + /* USER CODE BEGIN I2C1_MspInit 1 */ + + /* USER CODE END I2C1_MspInit 1 */ + } + +} + +/** +* @brief I2C MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hi2c: I2C handle pointer +* @retval None +*/ +void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c) +{ + if(hi2c->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspDeInit 0 */ + + /* USER CODE END I2C1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_I2C1_CLK_DISABLE(); + + /**I2C1 GPIO Configuration + PB6 ------> I2C1_SCL + PB7 ------> I2C1_SDA + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6); + + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7); + + /* USER CODE BEGIN I2C1_MspDeInit 1 */ + + /* USER CODE END I2C1_MspDeInit 1 */ + } + +} + +/** +* @brief RTC MSP Initialization +* This function configures the hardware resources used in this example +* @param hrtc: RTC handle pointer +* @retval None +*/ +void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) +{ + if(hrtc->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspInit 0 */ + + /* USER CODE END RTC_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_RTC_ENABLE(); + /* USER CODE BEGIN RTC_MspInit 1 */ + + /* USER CODE END RTC_MspInit 1 */ + } + +} + +/** +* @brief RTC MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hrtc: RTC handle pointer +* @retval None +*/ +void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc) +{ + if(hrtc->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspDeInit 0 */ + + /* USER CODE END RTC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_RTC_DISABLE(); + /* USER CODE BEGIN RTC_MspDeInit 1 */ + + /* USER CODE END RTC_MspDeInit 1 */ + } + +} + +/** +* @brief SD MSP Initialization +* This function configures the hardware resources used in this example +* @param hsd: SD handle pointer +* @retval None +*/ +void HAL_SD_MspInit(SD_HandleTypeDef* hsd) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hsd->Instance==SDIO) + { + /* USER CODE BEGIN SDIO_MspInit 0 */ + + /* USER CODE END SDIO_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SDIO_CLK_ENABLE(); + + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + /**SDIO GPIO Configuration + PC8 ------> SDIO_D0 + PC9 ------> SDIO_D1 + PC10 ------> SDIO_D2 + PC11 ------> SDIO_D3 + PC12 ------> SDIO_CK + PD2 ------> SDIO_CMD + */ + GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 + |GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_2; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /* USER CODE BEGIN SDIO_MspInit 1 */ + + /* USER CODE END SDIO_MspInit 1 */ + } + +} + +/** +* @brief SD MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hsd: SD handle pointer +* @retval None +*/ +void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd) +{ + if(hsd->Instance==SDIO) + { + /* USER CODE BEGIN SDIO_MspDeInit 0 */ + + /* USER CODE END SDIO_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SDIO_CLK_DISABLE(); + + /**SDIO GPIO Configuration + PC8 ------> SDIO_D0 + PC9 ------> SDIO_D1 + PC10 ------> SDIO_D2 + PC11 ------> SDIO_D3 + PC12 ------> SDIO_CK + PD2 ------> SDIO_CMD + */ + HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 + |GPIO_PIN_12); + + HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2); + + /* USER CODE BEGIN SDIO_MspDeInit 1 */ + + /* USER CODE END SDIO_MspDeInit 1 */ + } + +} + +/** +* @brief SPI MSP Initialization +* This function configures the hardware resources used in this example +* @param hspi: SPI handle pointer +* @retval None +*/ +void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hspi->Instance==SPI1) + { + /* USER CODE BEGIN SPI1_MspInit 0 */ + + /* USER CODE END SPI1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**SPI1 GPIO Configuration + PA5 ------> SPI1_SCK + PA6 ------> SPI1_MISO + PA7 ------> SPI1_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI1_MspInit 1 */ + + /* USER CODE END SPI1_MspInit 1 */ + } + else if(hspi->Instance==SPI2) + { + /* USER CODE BEGIN SPI2_MspInit 0 */ + + /* USER CODE END SPI2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI2_CLK_ENABLE(); + + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**SPI2 GPIO Configuration + PC2 ------> SPI2_MISO + PC3 ------> SPI2_MOSI + PB13 ------> SPI2_SCK + */ + GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI2_MspInit 1 */ + + /* USER CODE END SPI2_MspInit 1 */ + } + else if(hspi->Instance==SPI3) + { + /* USER CODE BEGIN SPI3_MspInit 0 */ + + /* USER CODE END SPI3_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI3_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**SPI3 GPIO Configuration + PB3 ------> SPI3_SCK + PB4 ------> SPI3_MISO + PB5 ------> SPI3_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI3_MspInit 1 */ + + /* USER CODE END SPI3_MspInit 1 */ + } + +} + +/** +* @brief SPI MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hspi: SPI handle pointer +* @retval None +*/ +void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) +{ + if(hspi->Instance==SPI1) + { + /* USER CODE BEGIN SPI1_MspDeInit 0 */ + + /* USER CODE END SPI1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI1_CLK_DISABLE(); + + /**SPI1 GPIO Configuration + PA5 ------> SPI1_SCK + PA6 ------> SPI1_MISO + PA7 ------> SPI1_MOSI + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); + + /* USER CODE BEGIN SPI1_MspDeInit 1 */ + + /* USER CODE END SPI1_MspDeInit 1 */ + } + else if(hspi->Instance==SPI2) + { + /* USER CODE BEGIN SPI2_MspDeInit 0 */ + + /* USER CODE END SPI2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI2_CLK_DISABLE(); + + /**SPI2 GPIO Configuration + PC2 ------> SPI2_MISO + PC3 ------> SPI2_MOSI + PB13 ------> SPI2_SCK + */ + HAL_GPIO_DeInit(GPIOC, GPIO_PIN_2|GPIO_PIN_3); + + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13); + + /* USER CODE BEGIN SPI2_MspDeInit 1 */ + + /* USER CODE END SPI2_MspDeInit 1 */ + } + else if(hspi->Instance==SPI3) + { + /* USER CODE BEGIN SPI3_MspDeInit 0 */ + + /* USER CODE END SPI3_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI3_CLK_DISABLE(); + + /**SPI3 GPIO Configuration + PB3 ------> SPI3_SCK + PB4 ------> SPI3_MISO + PB5 ------> SPI3_MOSI + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5); + + /* USER CODE BEGIN SPI3_MspDeInit 1 */ + + /* USER CODE END SPI3_MspDeInit 1 */ + } + +} + +/** +* @brief TIM_Base MSP Initialization +* This function configures the hardware resources used in this example +* @param htim_base: TIM_Base handle pointer +* @retval None +*/ +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) +{ + if(htim_base->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspInit 0 */ + + /* USER CODE END TIM2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM2_CLK_ENABLE(); + /* USER CODE BEGIN TIM2_MspInit 1 */ + + /* USER CODE END TIM2_MspInit 1 */ + } + else if(htim_base->Instance==TIM11) + { + /* USER CODE BEGIN TIM11_MspInit 0 */ + + /* USER CODE END TIM11_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM11_CLK_ENABLE(); + /* USER CODE BEGIN TIM11_MspInit 1 */ + + /* USER CODE END TIM11_MspInit 1 */ + } + else if(htim_base->Instance==TIM13) + { + /* USER CODE BEGIN TIM13_MspInit 0 */ + + /* USER CODE END TIM13_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM13_CLK_ENABLE(); + /* USER CODE BEGIN TIM13_MspInit 1 */ + + /* USER CODE END TIM13_MspInit 1 */ + } + else if(htim_base->Instance==TIM14) + { + /* USER CODE BEGIN TIM14_MspInit 0 */ + + /* USER CODE END TIM14_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM14_CLK_ENABLE(); + /* USER CODE BEGIN TIM14_MspInit 1 */ + + /* USER CODE END TIM14_MspInit 1 */ + } + +} + +/** +* @brief TIM_Base MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param htim_base: TIM_Base handle pointer +* @retval None +*/ +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) +{ + if(htim_base->Instance==TIM2) + { + /* USER CODE BEGIN TIM2_MspDeInit 0 */ + + /* USER CODE END TIM2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM2_CLK_DISABLE(); + /* USER CODE BEGIN TIM2_MspDeInit 1 */ + + /* USER CODE END TIM2_MspDeInit 1 */ + } + else if(htim_base->Instance==TIM11) + { + /* USER CODE BEGIN TIM11_MspDeInit 0 */ + + /* USER CODE END TIM11_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM11_CLK_DISABLE(); + /* USER CODE BEGIN TIM11_MspDeInit 1 */ + + /* USER CODE END TIM11_MspDeInit 1 */ + } + else if(htim_base->Instance==TIM13) + { + /* USER CODE BEGIN TIM13_MspDeInit 0 */ + + /* USER CODE END TIM13_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM13_CLK_DISABLE(); + /* USER CODE BEGIN TIM13_MspDeInit 1 */ + + /* USER CODE END TIM13_MspDeInit 1 */ + } + else if(htim_base->Instance==TIM14) + { + /* USER CODE BEGIN TIM14_MspDeInit 0 */ + + /* USER CODE END TIM14_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM14_CLK_DISABLE(); + /* USER CODE BEGIN TIM14_MspDeInit 1 */ + + /* USER CODE END TIM14_MspDeInit 1 */ + } + +} + +/** +* @brief UART MSP Initialization +* This function configures the hardware resources used in this example +* @param huart: UART handle pointer +* @retval None +*/ +void HAL_UART_MspInit(UART_HandleTypeDef* huart) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(huart->Instance==UART4) + { + /* USER CODE BEGIN UART4_MspInit 0 */ + + /* USER CODE END UART4_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_UART4_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**UART4 GPIO Configuration + PA0-WKUP ------> UART4_TX + PA1 ------> UART4_RX + */ + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF8_UART4; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN UART4_MspInit 1 */ + + /* USER CODE END UART4_MspInit 1 */ + } + else if(huart->Instance==USART1) + { + /* USER CODE BEGIN USART1_MspInit 0 */ + + /* USER CODE END USART1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_USART1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USART1 GPIO Configuration + PA9 ------> USART1_TX + PA10 ------> USART1_RX + */ + GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN USART1_MspInit 1 */ + + /* USER CODE END USART1_MspInit 1 */ + } + else if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspInit 0 */ + + /* USER CODE END USART2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_USART2_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN USART2_MspInit 1 */ + + /* USER CODE END USART2_MspInit 1 */ + } + else if(huart->Instance==USART3) + { + /* USER CODE BEGIN USART3_MspInit 0 */ + + /* USER CODE END USART3_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_USART3_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**USART3 GPIO Configuration + PB10 ------> USART3_TX + PB11 ------> USART3_RX + */ + GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN USART3_MspInit 1 */ + + /* USER CODE END USART3_MspInit 1 */ + } + +} + +/** +* @brief UART MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param huart: UART handle pointer +* @retval None +*/ +void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) +{ + if(huart->Instance==UART4) + { + /* USER CODE BEGIN UART4_MspDeInit 0 */ + + /* USER CODE END UART4_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_UART4_CLK_DISABLE(); + + /**UART4 GPIO Configuration + PA0-WKUP ------> UART4_TX + PA1 ------> UART4_RX + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0|GPIO_PIN_1); + + /* USER CODE BEGIN UART4_MspDeInit 1 */ + + /* USER CODE END UART4_MspDeInit 1 */ + } + else if(huart->Instance==USART1) + { + /* USER CODE BEGIN USART1_MspDeInit 0 */ + + /* USER CODE END USART1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART1_CLK_DISABLE(); + + /**USART1 GPIO Configuration + PA9 ------> USART1_TX + PA10 ------> USART1_RX + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); + + /* USER CODE BEGIN USART1_MspDeInit 1 */ + + /* USER CODE END USART1_MspDeInit 1 */ + } + else if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspDeInit 0 */ + + /* USER CODE END USART2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART2_CLK_DISABLE(); + + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3); + + /* USER CODE BEGIN USART2_MspDeInit 1 */ + + /* USER CODE END USART2_MspDeInit 1 */ + } + else if(huart->Instance==USART3) + { + /* USER CODE BEGIN USART3_MspDeInit 0 */ + + /* USER CODE END USART3_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART3_CLK_DISABLE(); + + /**USART3 GPIO Configuration + PB10 ------> USART3_TX + PB11 ------> USART3_RX + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11); + + /* USER CODE BEGIN USART3_MspDeInit 1 */ + + /* USER CODE END USART3_MspDeInit 1 */ + } + +} + +static uint32_t FSMC_Initialized = 0; + +static void HAL_FSMC_MspInit(void){ + /* USER CODE BEGIN FSMC_MspInit 0 */ + + /* USER CODE END FSMC_MspInit 0 */ + GPIO_InitTypeDef GPIO_InitStruct ={0}; + if (FSMC_Initialized) { + return; + } + FSMC_Initialized = 1; + + /* Peripheral clock enable */ + __HAL_RCC_FSMC_CLK_ENABLE(); + + /** FSMC GPIO Configuration + PF0 ------> FSMC_A0 + PF1 ------> FSMC_A1 + PF2 ------> FSMC_A2 + PF3 ------> FSMC_A3 + PF4 ------> FSMC_A4 + PF5 ------> FSMC_A5 + PF12 ------> FSMC_A6 + PF13 ------> FSMC_A7 + PF14 ------> FSMC_A8 + PF15 ------> FSMC_A9 + PG0 ------> FSMC_A10 + PG1 ------> FSMC_A11 + PE7 ------> FSMC_D4 + PE8 ------> FSMC_D5 + PE9 ------> FSMC_D6 + PE10 ------> FSMC_D7 + PE11 ------> FSMC_D8 + PE12 ------> FSMC_D9 + PE13 ------> FSMC_D10 + PE14 ------> FSMC_D11 + PE15 ------> FSMC_D12 + PD8 ------> FSMC_D13 + PD9 ------> FSMC_D14 + PD10 ------> FSMC_D15 + PD11 ------> FSMC_A16 + PD12 ------> FSMC_A17 + PD13 ------> FSMC_A18 + PD14 ------> FSMC_D0 + PD15 ------> FSMC_D1 + PG2 ------> FSMC_A12 + PG3 ------> FSMC_A13 + PG4 ------> FSMC_A14 + PG5 ------> FSMC_A15 + PD0 ------> FSMC_D2 + PD1 ------> FSMC_D3 + PD4 ------> FSMC_NOE + PD5 ------> FSMC_NWE + PG10 ------> FSMC_NE3 + PG12 ------> FSMC_NE4 + PE0 ------> FSMC_NBL0 + PE1 ------> FSMC_NBL1 + */ + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 + |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_12|GPIO_PIN_13 + |GPIO_PIN_14|GPIO_PIN_15; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 + |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10|GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 + |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 + |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 + |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15 + |GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /* USER CODE BEGIN FSMC_MspInit 1 */ + + /* USER CODE END FSMC_MspInit 1 */ +} + +void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram){ + /* USER CODE BEGIN SRAM_MspInit 0 */ + + /* USER CODE END SRAM_MspInit 0 */ + HAL_FSMC_MspInit(); + /* USER CODE BEGIN SRAM_MspInit 1 */ + + /* USER CODE END SRAM_MspInit 1 */ +} + +static uint32_t FSMC_DeInitialized = 0; + +static void HAL_FSMC_MspDeInit(void){ + /* USER CODE BEGIN FSMC_MspDeInit 0 */ + + /* USER CODE END FSMC_MspDeInit 0 */ + if (FSMC_DeInitialized) { + return; + } + FSMC_DeInitialized = 1; + /* Peripheral clock enable */ + __HAL_RCC_FSMC_CLK_DISABLE(); + + /** FSMC GPIO Configuration + PF0 ------> FSMC_A0 + PF1 ------> FSMC_A1 + PF2 ------> FSMC_A2 + PF3 ------> FSMC_A3 + PF4 ------> FSMC_A4 + PF5 ------> FSMC_A5 + PF12 ------> FSMC_A6 + PF13 ------> FSMC_A7 + PF14 ------> FSMC_A8 + PF15 ------> FSMC_A9 + PG0 ------> FSMC_A10 + PG1 ------> FSMC_A11 + PE7 ------> FSMC_D4 + PE8 ------> FSMC_D5 + PE9 ------> FSMC_D6 + PE10 ------> FSMC_D7 + PE11 ------> FSMC_D8 + PE12 ------> FSMC_D9 + PE13 ------> FSMC_D10 + PE14 ------> FSMC_D11 + PE15 ------> FSMC_D12 + PD8 ------> FSMC_D13 + PD9 ------> FSMC_D14 + PD10 ------> FSMC_D15 + PD11 ------> FSMC_A16 + PD12 ------> FSMC_A17 + PD13 ------> FSMC_A18 + PD14 ------> FSMC_D0 + PD15 ------> FSMC_D1 + PG2 ------> FSMC_A12 + PG3 ------> FSMC_A13 + PG4 ------> FSMC_A14 + PG5 ------> FSMC_A15 + PD0 ------> FSMC_D2 + PD1 ------> FSMC_D3 + PD4 ------> FSMC_NOE + PD5 ------> FSMC_NWE + PG10 ------> FSMC_NE3 + PG12 ------> FSMC_NE4 + PE0 ------> FSMC_NBL0 + PE1 ------> FSMC_NBL1 + */ + HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 + |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_12|GPIO_PIN_13 + |GPIO_PIN_14|GPIO_PIN_15); + + HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 + |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10|GPIO_PIN_12); + + HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 + |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 + |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1); + + HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 + |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15 + |GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5); + + /* USER CODE BEGIN FSMC_MspDeInit 1 */ + + /* USER CODE END FSMC_MspDeInit 1 */ +} + +void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram){ + /* USER CODE BEGIN SRAM_MspDeInit 0 */ + + /* USER CODE END SRAM_MspDeInit 0 */ + HAL_FSMC_MspDeInit(); + /* USER CODE BEGIN SRAM_MspDeInit 1 */ + + /* USER CODE END SRAM_MspDeInit 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/stm32f4xx_it.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/stm32f4xx_it.c new file mode 100644 index 000000000..404f784a0 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/stm32f4xx_it.c @@ -0,0 +1,218 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f4xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * + * COPYRIGHT(c) 2018 STMicroelectronics + * + * 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 of STMicroelectronics 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 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. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32f4xx_it.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ + +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Pre-fetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVCall_IRQn 0 */ + + /* USER CODE END SVCall_IRQn 0 */ + /* USER CODE BEGIN SVCall_IRQn 1 */ + + /* USER CODE END SVCall_IRQn 1 */ +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32F4xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32f4xx.s). */ +/******************************************************************************/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/system_stm32f4xx.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/system_stm32f4xx.c new file mode 100644 index 000000000..3303f969d --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/CubeMX_Config/Src/system_stm32f4xx.c @@ -0,0 +1,761 @@ +/** + ****************************************************************************** + * @file system_stm32f4xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2017 STMicroelectronics

+ * + * 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 of STMicroelectronics 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 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. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx_system + * @{ + */ + +/** @addtogroup STM32F4xx_System_Private_Includes + * @{ + */ + + +#include "stm32f4xx.h" + +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\ + || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) +/* #define DATA_IN_ExtSRAM */ +#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\ + STM32F412Zx || STM32F412Vx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +/* #define DATA_IN_ExtSDRAM */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\ + STM32F479xx */ + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Variables + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +uint32_t SystemCoreClock = 16000000; +const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; +const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes + * @{ + */ + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the FPU setting, vector table location and External memory + * configuration. + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000; + + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x24003010; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + SystemInit_ExtMemCtl(); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value + * depends on the application requirements), user has to ensure that HSE_VALUE + * is same as the real frequency of the crystal used. Otherwise, this function + * may have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N + SYSCLK = PLL_VCO / PLL_P + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + SystemCoreClock = pllvco/pllp; + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK frequency --------------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK frequency */ + SystemCoreClock >>= tmp; +} + +#if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM) +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external memories (SRAM/SDRAM) + * This SRAM/SDRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + __IO uint32_t tmp = 0x00; + + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register __IO uint32_t index; + + /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */ + RCC->AHB1ENR |= 0x000001F8; + + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00CCC0CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAA0A8A; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xFFFF0FCF; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00CC0CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA828A; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC3CF; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0xCCCCCCCC; + GPIOF->AFR[1] = 0xCCCCCCCC; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA800AAA; + /* Configure PFx pins speed to 50 MHz */ + GPIOF->OSPEEDR = 0xAA800AAA; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0xCCCCCCCC; + GPIOG->AFR[1] = 0xCCCCCCCC; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xAAAAAAAA; + /* Configure PGx pins speed to 50 MHz */ + GPIOG->OSPEEDR = 0xAAAAAAAA; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0x00C0CC00; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAA08A0; + /* Configure PHx pins speed to 50 MHz */ + GPIOH->OSPEEDR = 0xAAAA08A0; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* No pull-up, pull-down for PHx pins */ + GPIOH->PUPDR = 0x00000000; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0x0028AAAA; + /* Configure PIx pins speed to 50 MHz */ + GPIOI->OSPEEDR = 0x0028AAAA; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* No pull-up, pull-down for PIx pins */ + GPIOI->PUPDR = 0x00000000; + +/*-- FMC Configuration -------------------------------------------------------*/ + /* Enable the FMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + + FMC_Bank5_6->SDCR[0] = 0x000019E4; + FMC_Bank5_6->SDTR[0] = 0x01115351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6->SDCMR = 0x00000011; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6->SDCMR = 0x00000012; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Auto refresh command */ + FMC_Bank5_6->SDCMR = 0x00000073; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* MRD register program */ + FMC_Bank5_6->SDCMR = 0x00046014; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Set refresh count */ + tmpreg = FMC_Bank5_6->SDRTR; + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); + + /* Disable write protection */ + tmpreg = FMC_Bank5_6->SDCR[0]; + FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001011; + FMC_Bank1->BTCR[3] = 0x00000201; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +#if defined(STM32F469xx) || defined(STM32F479xx) + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001091; + FMC_Bank1->BTCR[3] = 0x00110212; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F469xx || STM32F479xx */ + + (void)(tmp); +} +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */ +#elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external memories (SRAM/SDRAM) + * This SRAM/SDRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + __IO uint32_t tmp = 0x00; +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) +#if defined (DATA_IN_ExtSDRAM) + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register __IO uint32_t index; + +#if defined(STM32F446xx) + /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface + clock */ + RCC->AHB1ENR |= 0x0000007D; +#else + /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface + clock */ + RCC->AHB1ENR |= 0x000001F8; +#endif /* STM32F446xx */ + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); + +#if defined(STM32F446xx) + /* Connect PAx pins to FMC Alternate function */ + GPIOA->AFR[0] |= 0xC0000000; + GPIOA->AFR[1] |= 0x00000000; + /* Configure PDx pins in Alternate function mode */ + GPIOA->MODER |= 0x00008000; + /* Configure PDx pins speed to 50 MHz */ + GPIOA->OSPEEDR |= 0x00008000; + /* Configure PDx pins Output type to push-pull */ + GPIOA->OTYPER |= 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOA->PUPDR |= 0x00000000; + + /* Connect PCx pins to FMC Alternate function */ + GPIOC->AFR[0] |= 0x00CC0000; + GPIOC->AFR[1] |= 0x00000000; + /* Configure PDx pins in Alternate function mode */ + GPIOC->MODER |= 0x00000A00; + /* Configure PDx pins speed to 50 MHz */ + GPIOC->OSPEEDR |= 0x00000A00; + /* Configure PDx pins Output type to push-pull */ + GPIOC->OTYPER |= 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOC->PUPDR |= 0x00000000; +#endif /* STM32F446xx */ + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x000000CC; + GPIOD->AFR[1] = 0xCC000CCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xA02A000A; + /* Configure PDx pins speed to 50 MHz */ + GPIOD->OSPEEDR = 0xA02A000A; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00000CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA800A; + /* Configure PEx pins speed to 50 MHz */ + GPIOE->OSPEEDR = 0xAAAA800A; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0xCCCCCCCC; + GPIOF->AFR[1] = 0xCCCCCCCC; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA800AAA; + /* Configure PFx pins speed to 50 MHz */ + GPIOF->OSPEEDR = 0xAA800AAA; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0xCCCCCCCC; + GPIOG->AFR[1] = 0xCCCCCCCC; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xAAAAAAAA; + /* Configure PGx pins speed to 50 MHz */ + GPIOG->OSPEEDR = 0xAAAAAAAA; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0x00C0CC00; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAA08A0; + /* Configure PHx pins speed to 50 MHz */ + GPIOH->OSPEEDR = 0xAAAA08A0; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* No pull-up, pull-down for PHx pins */ + GPIOH->PUPDR = 0x00000000; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0x0028AAAA; + /* Configure PIx pins speed to 50 MHz */ + GPIOI->OSPEEDR = 0x0028AAAA; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* No pull-up, pull-down for PIx pins */ + GPIOI->PUPDR = 0x00000000; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */ + +/*-- FMC Configuration -------------------------------------------------------*/ + /* Enable the FMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + + /* Configure and enable SDRAM bank1 */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCR[0] = 0x00001954; +#else + FMC_Bank5_6->SDCR[0] = 0x000019E4; +#endif /* STM32F446xx */ + FMC_Bank5_6->SDTR[0] = 0x01115351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6->SDCMR = 0x00000011; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6->SDCMR = 0x00000012; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Auto refresh command */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCMR = 0x000000F3; +#else + FMC_Bank5_6->SDCMR = 0x00000073; +#endif /* STM32F446xx */ + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* MRD register program */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCMR = 0x00044014; +#else + FMC_Bank5_6->SDCMR = 0x00046014; +#endif /* STM32F446xx */ + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Set refresh count */ + tmpreg = FMC_Bank5_6->SDRTR; +#if defined(STM32F446xx) + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1)); +#else + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); +#endif /* STM32F446xx */ + + /* Disable write protection */ + tmpreg = FMC_Bank5_6->SDCR[0]; + FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); +#endif /* DATA_IN_ExtSDRAM */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\ + || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\ + || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) + +#if defined(DATA_IN_ExtSRAM) +/*-- GPIOs Configuration -----------------------------------------------------*/ + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHB1ENR |= 0x00000078; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN); + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00CCC0CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAA0A8A; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xFFFF0FCF; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00CC0CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA828A; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC3CF; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0x00CCCCCC; + GPIOF->AFR[1] = 0xCCCC0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA000AAA; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xFF000FFF; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0x00CCCCCC; + GPIOG->AFR[1] = 0x000000C0; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0x00085AAA; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0x000CAFFF; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +/*-- FMC/FSMC Configuration --------------------------------------------------*/ + /* Enable the FMC/FSMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001011; + FMC_Bank1->BTCR[3] = 0x00000201; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +#if defined(STM32F469xx) || defined(STM32F479xx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001091; + FMC_Bank1->BTCR[3] = 0x00110212; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F469xx || STM32F479xx */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\ + || defined(STM32F412Zx) || defined(STM32F412Vx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN); + /* Configure and enable Bank1_SRAM2 */ + FSMC_Bank1->BTCR[2] = 0x00001011; + FSMC_Bank1->BTCR[3] = 0x00000201; + FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF; +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */ + +#endif /* DATA_IN_ExtSRAM */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\ + STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */ + (void)(tmp); +} +#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/Kconfig new file mode 100644 index 000000000..86ccf39af --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/Kconfig @@ -0,0 +1,64 @@ +menu"Hardware Drivers Config" + + menuconfig SOC_STM32F407ZG + bool + select SOC_SERIES_STM32F4 + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + + config BSP_USING_GPIO + bool "Enable GPIO" + select RT_USING_PIN + default y + + + menuconfig BSP_USING_UART + bool "Using UART device" + default y + select RT_USING_SERIAL + if BSP_USING_UART + source "$BSP_DIR/board/ports/uart/Kconfig" + endif + + + menuconfig BSP_USING_I2C1 + bool "Using I2C device" + default n + select RT_USING_I2C + select RT_USING_I2C_BITOPS + select RT_USING_PIN + if BSP_USING_I2C1 + source "$BSP_DIR/board/ports/I2c/Kconfig" + endif + + menuconfig BSP_USING_SPI + bool "Using SPI BUS" + default n + select RT_USING_SPI + if BSP_USING_SPI + source "$BSP_DIR/board/ports/spi/Kconfig" + endif + + + menuconfig BSP_USING_CH438 + bool "Using CH438 device" + default y + if BSP_USING_CH438 + source "$BSP_DIR/board/ports/ch438/Kconfig" + endif + + menuconfig BSP_USING_USB + bool "Using USB device" + default n + select BSP_USING_STM32_USBH + select RESOURCES_USB + select RESOURCES_USB_HOST + select USBH_MSTORAGE + select RESOURCES_USB_DEVICE + if BSP_USING_USB + source "$BSP_DIR/board/ports/usb/Kconfig" + endif + + source "$RTT_DIR/bsp/stm32/libraries/HAL_Drivers/Kconfig" +endmenu diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/SConscript b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/SConscript new file mode 100644 index 000000000..4812888d5 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/SConscript @@ -0,0 +1,31 @@ +import os +import rtconfig +from building import * + +Import('SDK_LIB') + +cwd = GetCurrentDir() + +# add general drivers +src = Split(''' +board.c +CubeMX_Config/Src/stm32f4xx_hal_msp.c +''') + +path = [cwd] +path += [cwd + '/CubeMX_Config/Inc'] +path += [cwd + '/ports'] + +startup_path_prefix = SDK_LIB + +if rtconfig.CROSS_TOOL == 'gcc': + src += [startup_path_prefix + '/STM32F4xx_HAL/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc/startup_stm32f407xx.s'] +elif rtconfig.CROSS_TOOL == 'keil': + src += [startup_path_prefix + '/STM32F4xx_HAL/CMSIS/Device/ST/STM32F4xx/Source/Templates/arm/startup_stm32f407xx.s'] +elif rtconfig.CROSS_TOOL == 'iar': + src += [startup_path_prefix + '/STM32F4xx_HAL/CMSIS/Device/ST/STM32F4xx/Source/Templates/iar/startup_stm32f407xx.s'] + +CPPDEFINES = ['STM32F407xx'] +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) + +Return('group') \ No newline at end of file diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/board.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/board.c new file mode 100644 index 000000000..c2c90a5e8 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/board.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-06 SummerGift first version + */ + +#include "board.h" + +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + + /**Configure the main internal regulator output voltage + */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + /**Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE + |RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 4; + RCC_OscInitStruct.PLL.PLLN = 168; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + /**Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) + { + Error_Handler(); + } + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } +} diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/board.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/board.h new file mode 100644 index 000000000..70a4c0ed1 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/board.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-5 SummerGift first version + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include +#include +#include "drv_common.h" +#include "drv_gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define STM32_SRAM_SIZE (128) +#define STM32_SRAM_END (0x20000000 + STM32_SRAM_SIZE * 1024) + +#define STM32_FLASH_START_ADRESS ((uint32_t)0x08000000) +#define STM32_FLASH_SIZE (1024 * 1024) +#define STM32_FLASH_END_ADDRESS ((uint32_t)(STM32_FLASH_START_ADRESS + STM32_FLASH_SIZE)) + +#if defined(__CC_ARM) || defined(__CLANG_ARM) +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define HEAP_BEGIN ((void *)&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ +#pragma section="CSTACK" +#define HEAP_BEGIN (__segment_end("CSTACK")) +#else +extern int __bss_end; +#define HEAP_BEGIN ((void *)&__bss_end) +#endif + +#define HEAP_END STM32_SRAM_END + +void SystemClock_Config(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/drv_dcmi.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/drv_dcmi.c new file mode 100644 index 000000000..f0f4c1d7b --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/drv_dcmi.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-07-27 thread-liu the first version + */ + +#include "board.h" +#ifdef BSP_USING_DCMI +#include +#ifdef RT_USING_POSIX +#include +#include +#ifdef RT_USING_POSIX_TERMIOS +#include +#endif +#endif + +#define DRV_DEBUG +#define LOG_TAG "drv.dcmi" +#include +static void (*dcmi_irq_callback)(void) = NULL; + +static struct stm32_dcmi rt_dcmi = {0}; +DMA_HandleTypeDef hdma_dcmi; +static void rt_hw_dcmi_dma_init(void) +{ + __HAL_RCC_DMA2_CLK_ENABLE(); + hdma_dcmi.Instance = DMA2_Stream1; + hdma_dcmi.Init.Channel = DMA_CHANNEL_1; + hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE; + hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; + hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; + hdma_dcmi.Init.Mode = DMA_NORMAL; + hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH; + hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE; + hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + hdma_dcmi.Init.MemBurst = DMA_MBURST_SINGLE; + hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE; + HAL_DMA_Init(&hdma_dcmi); + __HAL_LINKDMA(&rt_dcmi.DCMI_Handle, DMA_Handle, hdma_dcmi); + __HAL_DMA_ENABLE_IT(&hdma_dcmi,DMA_IT_TC); + HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0x00, 0x00); + HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);; +} +/* +DMA multi_buffer DMA Transfer. +*/ +void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint32_t len) +{ + HAL_DMAEx_MultiBufferStart(&hdma_dcmi, (rt_uint32_t)&DCMI->DR, dst_addr1, dst_addr2, len); + + __HAL_DMA_ENABLE_IT(&hdma_dcmi, DMA_IT_TC); +} + +static rt_err_t rt_hw_dcmi_init(DCMI_HandleTypeDef *device) +{ + RT_ASSERT(device != RT_NULL); + + device->Instance = DCMI; + device->Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; + device->Init.PCKPolarity = DCMI_PCKPOLARITY_RISING; + device->Init.VSPolarity = DCMI_VSPOLARITY_LOW; + device->Init.HSPolarity = DCMI_HSPOLARITY_LOW; + device->Init.CaptureRate = DCMI_CR_ALL_FRAME; + device->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B; + device->Init.JPEGMode = DCMI_JPEG_ENABLE; + #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) + device->Init.ByteSelectMode = DCMI_BSM_ALL; + device->Init.ByteSelectStart = DCMI_OEBS_ODD; + device->Init.LineSelectMode = DCMI_LSM_ALL; + device->Init.LineSelectStart = DCMI_OELS_ODD; + #endif + if(HAL_DCMI_Init(device) != HAL_OK) + { + LOG_E("dcmi init error!"); + return RT_ERROR; + } + else + { + LOG_I("dcmi HAL_DCMI_Init success"); + } + DCMI->IER = 0x0; + __HAL_DCMI_ENABLE_IT(device, DCMI_IT_FRAME); + __HAL_DCMI_ENABLE(device); + return RT_EOK; +} + +void DCMI_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + HAL_DCMI_IRQHandler(&rt_dcmi.DCMI_Handle); + /* leave interrupt */ + rt_interrupt_leave(); +} +/* +the camera starts transfering photos +*/ +void rt_dcmi_start(uint32_t pData, uint32_t Length) +{ + HAL_DCMI_Start_DMA(&rt_dcmi.DCMI_Handle,DCMI_MODE_SNAPSHOT,pData, Length); +} + +/* +the camera stops transfering photos +*/ +void rt_dcmi_stop(void) +{ + HAL_DCMI_Stop(&rt_dcmi.DCMI_Handle);// +} + + +/* Capture a frame of the image */ +void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi) +{ + rt_interrupt_enter(); + __HAL_DCMI_ENABLE_IT(&rt_dcmi.DCMI_Handle, DCMI_IT_FRAME); + rt_dcmi_stop(); + if(NULL != dcmi_irq_callback) + { + (*dcmi_irq_callback)(); + } + rt_interrupt_leave(); +} + +void DMA2_Stream1_IRQHandler(void) +{ + extern void camera_dma_data_process(void); + /* enter interrupt */ + rt_interrupt_enter(); + + if (__HAL_DMA_GET_FLAG(&hdma_dcmi, DMA_FLAG_TCIF1_5) != RESET) + { + __HAL_DMA_CLEAR_FLAG(&hdma_dcmi, DMA_FLAG_TCIF1_5); + } + + /* leave interrupt */ + rt_interrupt_leave(); +} + +static rt_err_t rt_dcmi_init(rt_device_t dev) +{ + RT_ASSERT(dev != RT_NULL); + rt_err_t result = RT_EOK; + result = rt_hw_dcmi_init(&rt_dcmi.DCMI_Handle); + if (result != RT_EOK) + { + return result; + } + + rt_hw_dcmi_dma_init(); + + return result; +} + +static rt_err_t rt_dcmi_open(rt_device_t dev, rt_uint16_t oflag) +{ + RT_ASSERT(dev != RT_NULL); + + return RT_EOK; +} + +static rt_err_t rt_dcmi_close(rt_device_t dev) +{ + RT_ASSERT(dev != RT_NULL); + + return RT_EOK; +} + +static rt_err_t rt_dcmi_control(rt_device_t dev, int cmd, void *args) +{ + RT_ASSERT(dev != RT_NULL); + + return RT_EOK; +} + +static rt_size_t rt_dcmi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + RT_ASSERT(dev != RT_NULL); + + return RT_EOK; +} + +static rt_size_t rt_dcmi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + RT_ASSERT(dev != RT_NULL); + + return RT_EOK; +} + +rt_err_t rt_set_irq_dcmi_callback_hander(void (*p)(void)) +{ + if(NULL == p) + { + LOG_E("set irq dcmi callback hander is NULL"); + return RT_ERROR; + } + dcmi_irq_callback = p; + return RT_EOK; + +} +int dcmi_init(void) +{ + int ret = 0; + rt_device_t dcmi_dev = RT_NULL; + rt_dcmi.dev.parent.type = RT_Device_Class_Miscellaneous; + rt_dcmi.dev.parent.init = rt_dcmi_init; + rt_dcmi.dev.parent.open = rt_dcmi_open; + rt_dcmi.dev.parent.close = rt_dcmi_close; + rt_dcmi.dev.parent.read = rt_dcmi_read; + rt_dcmi.dev.parent.write = rt_dcmi_write; + rt_dcmi.dev.parent.control = rt_dcmi_control; + rt_dcmi.dev.parent.user_data = RT_NULL; + ret = rt_device_register(&rt_dcmi.dev.parent, "dcmi", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); + if(ret != RT_EOK) + { + LOG_E("dcmi registered fail!!\n\r"); + return -RT_ERROR; + } + LOG_I("dcmi registered successfully!"); + dcmi_dev = rt_device_find("dcmi"); + if (dcmi_dev == RT_NULL) + { + LOG_E("can't find dcmi device!"); + return RT_ERROR; + } + ret = rt_device_open(dcmi_dev, RT_DEVICE_FLAG_RDWR); + if(ret != RT_EOK) + { + LOG_E("can't open dcmi device!"); + return RT_ERROR; + } + LOG_I("dcmi open successfully"); + return RT_EOK; +} +INIT_BOARD_EXPORT(dcmi_init); +#endif diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/drv_dcmi.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/drv_dcmi.h new file mode 100644 index 000000000..abd01c183 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/drv_dcmi.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-07-27 thread-liu the first version + */ + +#ifndef __DRV_DCMI_H__ +#define __DRV_DCMI_H__ +#include "board.h" +#ifdef __cplusplus +extern "C" { +#endif +struct rt_dcmi_device +{ + struct rt_device parent; +}; +struct stm32_dcmi +{ + DCMI_HandleTypeDef DCMI_Handle; + struct rt_dcmi_device dev; +}; + +extern DMA_HandleTypeDef hdma_dcmi; +extern void DCMI_IRQHandler(void); +extern void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint32_t len); +extern void rt_dcmi_start(uint32_t pData, uint32_t Length); +extern void rt_dcmi_stop(void); +extern rt_err_t rt_set_irq_dcmi_callback_hander(void (*p)(void)); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/linker_scripts/link.lds b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/linker_scripts/link.lds new file mode 100644 index 000000000..79a7e76df --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/linker_scripts/link.lds @@ -0,0 +1,159 @@ +/* + * linker script for STM32F4xx with GNU ld + * bernard.xiong 2009-10-14 + * flybreak 2018-11-19 Add support for RAM2 + */ + +/* Program Entry, set to mark it as "used" and avoid gc */ +MEMORY +{ + CODE (rx) : ORIGIN = 0x08000000, LENGTH = 1024k /* 1024KB flash */ + RAM1 (rw) : ORIGIN = 0x20000000, LENGTH = 128k /* 128K sram */ + RAM2 (rw) : ORIGIN = 0x10000000, LENGTH = 64k /* 64K sram */ +} +ENTRY(Reset_Handler) +_system_stack_size = 0x200; + +SECTIONS +{ + .text : + { + . = ALIGN(4); + _stext = .; + KEEP(*(.isr_vector)) /* Startup code */ + + . = ALIGN(4); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + + /* section information for initial. */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + + . = ALIGN(4); + + PROVIDE(__ctors_start__ = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE(__ctors_end__ = .); + + . = ALIGN(4); + + _etext = .; + } > CODE = 0 + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + /* This is used by the startup in order to initialize the .data secion */ + _sidata = .; + } > CODE + __exidx_end = .; + + /* .data section which is used for initialized data */ + + .data : AT (_sidata) + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _sdata = . ; + + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _edata = . ; + } >RAM1 + + .stack : + { + . = ALIGN(4); + _sstack = .; + . = . + _system_stack_size; + . = ALIGN(4); + _estack = .; + } >RAM1 + + __bss_start = .; + .bss : + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; + + *(.bss) + *(.bss.*) + *(COMMON) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _ebss = . ; + + *(.bss.init) + } > RAM1 + __bss_end = .; + + _end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/I2c/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/I2c/Kconfig new file mode 100644 index 000000000..168ee276b --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/I2c/Kconfig @@ -0,0 +1,13 @@ +config BSP_USING_I2C1 + bool "Enable I2C1 BUS (software simulation)" + default y + if BSP_USING_I2C1 + config BSP_I2C1_SCL_PIN + int "I2C scl pin number" + range 0 143 + default 24 + config BSP_I2C1_SDA_PIN + int "I2C sda pin number" + range 0 143 + default 25 + endif diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/can/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/can/Kconfig new file mode 100644 index 000000000..34fb7d247 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/can/Kconfig @@ -0,0 +1,11 @@ +config CAN_BUS_NAME_1 + string "can bus name" + default "can1" + +config CAN_DRIVER_NAME + string "can driver name" + default "can1_drv" + +config CAN_1_DEVICE_NAME_1 + string "can bus 1 device 1 name" + default "can1_dev1" \ No newline at end of file diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/ch438/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/ch438/Kconfig new file mode 100644 index 000000000..389b67525 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/ch438/Kconfig @@ -0,0 +1,39 @@ +config CH438_BUS_NAME + string + default "extuart" + +config CH438_DRIVER_NAME + string + default "extuart_drv" + +config CH438_DEVICE_NAME_0 + string + default "extuart_dev0" + +config CH438_DEVICE_NAME_1 + string + default "extuart_dev1" + +config CH438_DEVICE_NAME_2 + string + default "extuart_dev2" + +config CH438_DEVICE_NAME_3 + string + default "extuart_dev3" + +config CH438_DEVICE_NAME_4 + string + default "extuart_dev4" + +config CH438_DEVICE_NAME_5 + string + default "extuart_dev5" + +config CH438_DEVICE_NAME_6 + string + default "extuart_dev6" + +config CH438_DEVICE_NAME_7 + string + default "extuart_dev7" diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/gpio/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/gpio/Kconfig new file mode 100644 index 000000000..1f789b987 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/gpio/Kconfig @@ -0,0 +1,4 @@ +config BSP_USING_GPIO + bool "Enable GPIO" + default y + diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/spi/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/spi/Kconfig new file mode 100644 index 000000000..33e9ba97f --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/spi/Kconfig @@ -0,0 +1,46 @@ +config BSP_USING_SPI1 + bool "Enable SPI1 BUS" + default n + +config BSP_SPI1_TX_USING_DMA + bool "Enable SPI1 TX DMA" + depends on BSP_USING_SPI1 + default n + +config BSP_SPI1_RX_USING_DMA + bool "Enable SPI1 RX DMA" + depends on BSP_USING_SPI1 + select BSP_SPI1_TX_USING_DMA + default n + +config BSP_USING_SPI2 + bool "Enable SPI2 BUS" + default n + +config BSP_SPI2_TX_USING_DMA + bool "Enable SPI2 TX DMA" + depends on BSP_USING_SPI2 + default n + +config BSP_SPI2_RX_USING_DMA + bool "Enable SPI2 RX DMA" + depends on BSP_USING_SPI2 + select BSP_SPI2_TX_USING_DMA + default n + + +config BSP_USING_SPI3 + bool "Enable SPI3 BUS" + default n + +config BSP_SPI3_TX_USING_DMA + bool "Enable SPI3 TX DMA" + depends on BSP_USING_SPI3 + default n + +config BSP_SPI3_RX_USING_DMA + bool "Enable SPI3 RX DMA" + depends on BSP_USING_SPI3 + select BSP_SPI3_TX_USING_DMA + default n + diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/uart/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/uart/Kconfig new file mode 100644 index 000000000..856d0d1f5 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/uart/Kconfig @@ -0,0 +1,21 @@ +config BSP_USING_UART1 + bool "Enable UART1" + default y + +config BSP_USING_UART2 + bool "Enable UART2" + default n + +config BSP_USING_UART3 + bool "Enable UART3" + default n + +config BSP_USING_UART4 + bool "Enable UART4" + default n + + + + + + diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/usb/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/usb/Kconfig new file mode 100644 index 000000000..4fcd37871 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/board/ports/usb/Kconfig @@ -0,0 +1,15 @@ +config BSP_USING_STM32_USBH + bool "Using usb host" + default y + if BSP_USING_STM32_USBH + config USB_BUS_NAME + string "usb bus name" + default "usb" + config USB_DRIVER_NAME + string "usb bus driver name" + default "usb_drv" + config USB_DEVICE_NAME + string "usb bus device name" + default "usb_dev" + endif + diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/rtconfig.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/rtconfig.h new file mode 100644 index 000000000..da4679060 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/rtconfig.h @@ -0,0 +1,226 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Configuration */ + +#define ROOT_DIR "../../../.." +#define BSP_DIR "." +#define RT_Thread_DIR "../.." +#define RTT_DIR "../../rt-thread" + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 256 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 512 + +/* kservice optimization */ + +#define RT_DEBUG +#define RT_DEBUG_COLOR + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_MEMHEAP +#define RT_USING_MEMHEAP_AUTO_BINDING +#define RT_USING_MEMHEAP_AS_HEAP +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x40004 +#define ARCH_ARM +#define RT_USING_CPU_FFS +#define ARCH_ARM_CORTEX_M +#define ARCH_ARM_CORTEX_M4 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 + +/* C++ features */ + + +/* Command shell */ + +#define RT_USING_FINSH +#define RT_USING_MSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_WORKDIR +#define DFS_FILESYSTEMS_MAX 4 +#define DFS_FILESYSTEM_TYPES_MAX 4 +#define DFS_FD_MAX 16 +#define RT_USING_DFS_ELMFAT + +/* elm-chan's FatFs, Generic FAT Filesystem Module */ + +#define RT_DFS_ELM_CODE_PAGE 437 +#define RT_DFS_ELM_WORD_ACCESS +#define RT_DFS_ELM_USE_LFN_3 +#define RT_DFS_ELM_USE_LFN 3 +#define RT_DFS_ELM_LFN_UNICODE_0 +#define RT_DFS_ELM_LFN_UNICODE 0 +#define RT_DFS_ELM_MAX_LFN 255 +#define RT_DFS_ELM_DRIVES 2 +#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 +#define RT_DFS_ELM_REENTRANT +#define RT_DFS_ELM_MUTEX_TIMEOUT 3000 +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_ROMFS + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_CAN +#define RT_USING_I2C +#define RT_USING_I2C_BITOPS +#define RT_USING_PIN +#define RT_USING_RTC +#define RT_USING_SPI +#define RT_USING_SPI_MSD +#define RT_USING_SFUD +#define RT_SFUD_USING_SFDP +#define RT_SFUD_USING_FLASH_INFO_TABLE +#define RT_SFUD_SPI_MAX_HZ 50000000 + +/* Using USB */ + + +/* POSIX layer and C standard library */ + +#define RT_USING_LIBC +#define RT_USING_PTHREADS +#define PTHREAD_NUM_MAX 8 +#define RT_USING_POSIX +#define RT_LIBC_USING_TIME +#define RT_LIBC_DEFAULT_TIMEZONE 8 + +/* Network */ + +/* Socket abstraction layer */ + + +/* Network interface device */ + + +/* light weight TCP/IP stack */ + + +/* AT commands */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + + +/* RT-Thread Utestcases */ + +#define SOC_FAMILY_STM32 +#define SOC_SERIES_STM32F4 + +/* Hardware Drivers Config */ + +#define SOC_STM32F407ZG +#define BSP_USING_GPIO +#define BSP_USING_UART +#define BSP_USING_UART1 +#define BSP_USING_USB +#define BSP_USING_STM32_USBH +#define USB_BUS_NAME "usb" +#define USB_DRIVER_NAME "usb_drv" +#define USB_DEVICE_NAME "usb_dev" + +/* MicroPython */ + + +/* More Drivers */ + + +/* APP_Framework */ + +/* Framework */ + +#define TRANSFORM_LAYER_ATTRIUBUTE +#define ADD_XIZI_FETURES + +/* Security */ + + +/* Applications */ + +/* config stack size and priority of main task */ + +#define MAIN_KTASK_STACK_SIZE 1024 + +/* ota app */ + + +/* test app */ + + +/* connection app */ + + +/* control app */ + +/* knowing app */ + + +/* sensor app */ + + +/* lib */ + +#define APP_SELECT_NEWLIB + +#endif diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/rtconfig.py b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/rtconfig.py new file mode 100644 index 000000000..1e094c54c --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-arm32-board/rtconfig.py @@ -0,0 +1,151 @@ +import os +SRC_APP_DIR = '../../../../APP_Framework' +# toolchains options +ARCH='arm' +CPU='cortex-m4' +CROSS_TOOL='gcc' + +# bsp lib config +BSP_LIBRARY_TYPE = None + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'/opt/gcc-arm-none-eabi-7-2018-q2-update/bin' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = r'C:/Keil_v5' +elif CROSS_TOOL == 'iar': + PLATFORM = 'iar' + EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.0' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + CXX = PREFIX + 'g++' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections' + CFLAGS = DEVICE + ' -Dgcc' + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb ' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rt-thread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.lds' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2 -g' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + CXXFLAGS += ' -std=gnu++11' + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' + +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + CXX = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --cpu Cortex-M4.fp ' + CFLAGS = '-c ' + DEVICE + ' --apcs=interwork --c99' + AFLAGS = DEVICE + ' --apcs=interwork ' + LFLAGS = DEVICE + ' --scatter "board\linker_scripts\link.sct" --info sizes --info totals --info unused --info veneers --list rt-thread.map --strict' + CFLAGS += ' -I' + EXEC_PATH + '/ARM/ARMCC/include' + LFLAGS += ' --libpath=' + EXEC_PATH + '/ARM/ARMCC/lib' + + CFLAGS += ' -D__MICROLIB ' + AFLAGS += ' --pd "__MICROLIB SETA 1" ' + LFLAGS += ' --library_type=microlib ' + EXEC_PATH += '/ARM/ARMCC/bin/' + + if BUILD == 'debug': + CFLAGS += ' -g -O0' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + CFLAGS += ' -std=c99' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + +elif PLATFORM == 'iar': + # toolchains + CC = 'iccarm' + CXX = 'iccarm' + AS = 'iasmarm' + AR = 'iarchive' + LINK = 'ilinkarm' + TARGET_EXT = 'out' + + DEVICE = '-Dewarm' + + CFLAGS = DEVICE + CFLAGS += ' --diag_suppress Pa050' + CFLAGS += ' --no_cse' + CFLAGS += ' --no_unroll' + CFLAGS += ' --no_inline' + CFLAGS += ' --no_code_motion' + CFLAGS += ' --no_tbaa' + CFLAGS += ' --no_clustering' + CFLAGS += ' --no_scheduling' + CFLAGS += ' --endian=little' + CFLAGS += ' --cpu=Cortex-M4' + CFLAGS += ' -e' + CFLAGS += ' --fpu=VFPv4_sp' + CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"' + CFLAGS += ' --silent' + + AFLAGS = DEVICE + AFLAGS += ' -s+' + AFLAGS += ' -w+' + AFLAGS += ' -r' + AFLAGS += ' --cpu Cortex-M4' + AFLAGS += ' --fpu VFPv4_sp' + AFLAGS += ' -S' + + if BUILD == 'debug': + CFLAGS += ' --debug' + CFLAGS += ' -On' + else: + CFLAGS += ' -Oh' + + LFLAGS = ' --config "board/linker_scripts/link.icf"' + LFLAGS += ' --entry __iar_program_start' + + CXXFLAGS = CFLAGS + + EXEC_PATH = EXEC_PATH + '/arm/bin/' + POST_ACTION = 'ielftool --bin $TARGET rtthread.bin' + +def dist_handle(BSP_ROOT, dist_dir): + import sys + cwd_path = os.getcwd() + sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools')) + from sdk_dist import dist_do_building + dist_do_building(BSP_ROOT, dist_dir) diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/.config b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/.config index c5029c9fa..0f63cb237 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/.config +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/.config @@ -11,7 +11,6 @@ CONFIG_RTT_DIR="../../rt-thread" # RT-Thread Kernel # CONFIG_RT_NAME_MAX=8 -# CONFIG_RT_USING_BIG_ENDIAN is not set # CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_SMP is not set CONFIG_RT_ALIGN_SIZE=4 @@ -22,6 +21,7 @@ CONFIG_RT_THREAD_PRIORITY_MAX=32 CONFIG_RT_TICK_PER_SECOND=1000 CONFIG_RT_USING_OVERFLOW_CHECK=y CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y CONFIG_RT_USING_IDLE_HOOK=y CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 CONFIG_IDLE_THREAD_STACK_SIZE=256 @@ -32,7 +32,8 @@ CONFIG_IDLE_THREAD_STACK_SIZE=256 # # CONFIG_RT_KSERVICE_USING_STDLIB is not set # CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set -# CONFIG_RT_USING_ASM_MEMCPY is not set +# CONFIG_RT_USING_TINY_FFS is not set +# CONFIG_RT_KPRINTF_USING_LONGLONG is not set CONFIG_RT_DEBUG=y CONFIG_RT_DEBUG_COLOR=y # CONFIG_RT_DEBUG_INIT_CONFIG is not set @@ -60,14 +61,19 @@ CONFIG_RT_USING_MESSAGEQUEUE=y # Memory Management # CONFIG_RT_USING_MEMPOOL=y -CONFIG_RT_USING_MEMHEAP=y -CONFIG_RT_USING_MEMHEAP_AUTO_BINDING=y -# CONFIG_RT_USING_NOHEAP is not set # CONFIG_RT_USING_SMALL_MEM is not set # CONFIG_RT_USING_SLAB is not set +CONFIG_RT_USING_MEMHEAP=y +CONFIG_RT_MEMHEAP_FAST_MODE=y +# CONFIG_RT_MEMHEAP_BSET_MODE is not set +# CONFIG_RT_USING_SMALL_MEM_AS_HEAP is not set CONFIG_RT_USING_MEMHEAP_AS_HEAP=y +CONFIG_RT_USING_MEMHEAP_AUTO_BINDING=y +# CONFIG_RT_USING_SLAB_AS_HEAP is not set # CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set # CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set CONFIG_RT_USING_HEAP=y # @@ -79,8 +85,7 @@ CONFIG_RT_USING_DEVICE=y CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=256 CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" -# CONFIG_RT_PRINTF_LONGLONG is not set -CONFIG_RT_VER_NUM=0x40004 +CONFIG_RT_VER_NUM=0x40100 CONFIG_ARCH_ARM=y CONFIG_RT_USING_CPU_FFS=y CONFIG_ARCH_ARM_CORTEX_M=y @@ -94,18 +99,9 @@ CONFIG_RT_USING_COMPONENTS_INIT=y CONFIG_RT_USING_USER_MAIN=y CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 CONFIG_RT_MAIN_THREAD_PRIORITY=10 - -# -# C++ features -# -CONFIG_RT_USING_CPLUSPLUS=y -# CONFIG_RT_USING_CPLUSPLUS11 is not set - -# -# Command shell -# -CONFIG_RT_USING_FINSH=y +# CONFIG_RT_USING_LEGACY is not set CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y CONFIG_FINSH_USING_MSH=y CONFIG_FINSH_THREAD_NAME="tshell" CONFIG_FINSH_THREAD_PRIORITY=20 @@ -119,11 +115,8 @@ CONFIG_FINSH_USING_DESCRIPTION=y # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set # CONFIG_FINSH_USING_AUTH is not set CONFIG_FINSH_ARG_MAX=10 - -# -# Device virtual file system -# CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y CONFIG_DFS_USING_WORKDIR=y CONFIG_DFS_FILESYSTEMS_MAX=4 CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 @@ -153,14 +146,15 @@ CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096 CONFIG_RT_DFS_ELM_REENTRANT=y CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000 CONFIG_RT_USING_DFS_DEVFS=y -CONFIG_RT_USING_DFS_ROMFS=y -# CONFIG_RT_USING_DFS_RAMFS is not set +# CONFIG_RT_USING_DFS_ROMFS is not set +CONFIG_RT_USING_DFS_RAMFS=y +# CONFIG_RT_USING_FAL is not set +# CONFIG_RT_USING_LWP is not set # # Device Drivers # CONFIG_RT_USING_DEVICE_IPC=y -CONFIG_RT_PIPE_BUFSZ=512 # CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set CONFIG_RT_USING_SERIAL=y CONFIG_RT_USING_SERIAL_V1=y @@ -179,9 +173,28 @@ CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set # CONFIG_RT_USING_PM is not set -# CONFIG_RT_USING_RTC is not set -# CONFIG_RT_USING_SDIO is not set -# CONFIG_RT_USING_SPI is not set +CONFIG_RT_USING_RTC=y +# CONFIG_RT_USING_ALARM is not set +# CONFIG_RT_USING_SOFT_RTC is not set +CONFIG_RT_USING_SDIO=y +CONFIG_RT_SDIO_STACK_SIZE=512 +CONFIG_RT_SDIO_THREAD_PRIORITY=15 +CONFIG_RT_MMCSD_STACK_SIZE=1024 +CONFIG_RT_MMCSD_THREAD_PREORITY=22 +CONFIG_RT_MMCSD_MAX_PARTITION=16 +# CONFIG_RT_SDIO_DEBUG is not set +CONFIG_RT_USING_SPI=y +# CONFIG_RT_USING_SPI_BITOPS is not set +CONFIG_RT_USING_QSPI=y +# CONFIG_RT_USING_SPI_MSD is not set +CONFIG_RT_USING_SFUD=y +CONFIG_RT_SFUD_USING_SFDP=y +CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y +CONFIG_RT_SFUD_USING_QSPI=y +CONFIG_RT_SFUD_SPI_MAX_HZ=50000000 +# CONFIG_RT_DEBUG_SFUD is not set +# CONFIG_RT_USING_ENC28J60 is not set +# CONFIG_RT_USING_SPI_WIFI is not set # CONFIG_RT_USING_WDT is not set # CONFIG_RT_USING_AUDIO is not set # CONFIG_RT_USING_SENSOR is not set @@ -194,53 +207,64 @@ CONFIG_RT_USING_PIN=y # # Using USB # +CONFIG_RT_USING_USB=y # CONFIG_RT_USING_USB_HOST is not set -# CONFIG_RT_USING_USB_DEVICE is not set +CONFIG_RT_USING_USB_DEVICE=y +CONFIG_RT_USBD_THREAD_STACK_SZ=4096 +CONFIG_USB_VENDOR_ID=0x0FFE +CONFIG_USB_PRODUCT_ID=0x0001 +# CONFIG_RT_USB_DEVICE_COMPOSITE is not set +# CONFIG__RT_USB_DEVICE_NONE is not set +CONFIG__RT_USB_DEVICE_CDC=y +# CONFIG__RT_USB_DEVICE_MSTORAGE is not set +# CONFIG__RT_USB_DEVICE_HID is not set +# CONFIG__RT_USB_DEVICE_WINUSB is not set +# CONFIG__RT_USB_DEVICE_AUDIO is not set +CONFIG_RT_USB_DEVICE_CDC=y +CONFIG_RT_VCOM_TASK_STK_SIZE=512 +CONFIG_RT_CDC_RX_BUFSIZE=128 +# CONFIG_RT_VCOM_TX_USE_DMA is not set +CONFIG_RT_VCOM_SERNO="32021919830108" +CONFIG_RT_VCOM_SER_LEN=14 +CONFIG_RT_VCOM_TX_TIMEOUT=1000 # -# POSIX layer and C standard library +# C/C++ and POSIX layer # -CONFIG_RT_USING_LIBC=y +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# POSIX (Portable Operating System Interface) layer +# +# CONFIG_RT_USING_POSIX_FS is not set +CONFIG_RT_USING_POSIX_DELAY=y +CONFIG_RT_USING_POSIX_CLOCK=y +# CONFIG_RT_USING_POSIX_TIMER is not set CONFIG_RT_USING_PTHREADS=y CONFIG_PTHREAD_NUM_MAX=8 -CONFIG_RT_USING_POSIX=y -# CONFIG_RT_USING_POSIX_MMAP is not set -# CONFIG_RT_USING_POSIX_TERMIOS is not set -# CONFIG_RT_USING_POSIX_GETLINE is not set -# CONFIG_RT_USING_POSIX_AIO is not set -CONFIG_RT_LIBC_USING_TIME=y # CONFIG_RT_USING_MODULE is not set -CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# Interprocess Communication (IPC) +# +# CONFIG_RT_USING_POSIX_PIPE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set + +# +# Socket is in the 'Network' category +# +CONFIG_RT_USING_CPLUSPLUS=y +# CONFIG_RT_USING_CPLUSPLUS11 is not set # # Network # - -# -# Socket abstraction layer -# # CONFIG_RT_USING_SAL is not set - -# -# Network interface device -# # CONFIG_RT_USING_NETDEV is not set - -# -# light weight TCP/IP stack -# # CONFIG_RT_USING_LWIP is not set - -# -# AT commands -# # CONFIG_RT_USING_AT is not set -# -# VBUS(Virtual Software BUS) -# -# CONFIG_RT_USING_VBUS is not set - # # Utilities # @@ -249,7 +273,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_RT_USING_UTEST is not set # CONFIG_RT_USING_VAR_EXPORT is not set # CONFIG_RT_USING_RT_LINK is not set -# CONFIG_RT_USING_LWP is not set +# CONFIG_RT_USING_VBUS is not set # # RT-Thread Utestcases @@ -272,11 +296,20 @@ CONFIG_BSP_USING_UART1=y # CONFIG_BSP_UART1_RX_USING_DMA is not set # CONFIG_BSP_USING_UART2 is not set # CONFIG_BSP_USING_LPUART1 is not set -CONFIG_BSP_USING_SDRAM=y +CONFIG_BSP_USING_QSPI=y +CONFIG_BSP_USING_ONCHIP_RTC=y # CONFIG_BSP_USING_CRC is not set # CONFIG_BSP_USING_RNG is not set # CONFIG_BSP_USING_UDID is not set +# +# Onboard Peripheral Drivers +# +CONFIG_BSP_USING_SDRAM=y +# CONFIG_BSP_USING_QSPI_FLASH is not set +CONFIG_BSP_USING_SDMMC=y +CONFIG_BSP_USING_USBD=y + # # More Drivers # diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/README.md b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/README.md index 121f7eef3..82647c59c 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/README.md +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/README.md @@ -82,4 +82,33 @@ | PC5 | FMC_SDCKE0 | | PG8 | FMC_SDCLK | | PG15 | FMC_SDNCAS | -| PF11 | FMC_SDNRAS | \ No newline at end of file +| PF11 | FMC_SDNRAS | + +### QSPI FLASH W25Q256JV + +| 引脚 | 作用 | +| ---- | --------------- | +| PF6 | QUADSPI_BK1_IO3 | +| PF7 | QUADSPI_BK1_IO2 | +| PF8 | QUADSPI_BK1_IO0 | +| PF9 | QUADSPI_BK1_IO1 | +| PF10 | QUADSPI_CLK | +| PG6 | QUADSPI_BK1_NCS | + +### SDIO USD-1040310811 + +| 引脚 | 作用 | +| ---- | ---------- | +| PC8 | SDMMC1_D0 | +| PC9 | SDMMC1_D1 | +| PC10 | SDMMC1_D2 | +| PC11 | SDMMC1_D3 | +| PC12 | SDMMC1_CK | +| PD2 | SDMMC1_CMD | + +### USBCDC + +| 引脚 | 作用 | +| ---- | ------------- | +| PA11 | USB_OTG_FS_DM | +| PA12 | USB_OTG_FS_DP | \ No newline at end of file diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/applications/main.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/applications/main.c index 7a43f472d..dd727ca37 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/applications/main.c +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/applications/main.c @@ -31,9 +31,11 @@ extern int FrameworkInit(); int main(void) { rt_pin_mode(LEDR_PIN, PIN_MODE_OUTPUT); - rt_thread_mdelay(100); FrameworkInit(); printf("XIUOS stm32h7 build %s %s\n",__DATE__,__TIME__); + #ifdef BSP_USING_USBD + //rt_console_set_device("vcom"); + #endif while (1) { rt_pin_write(LEDR_PIN, PIN_HIGH); diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/.mxproject b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/.mxproject index bf4101d42..78b5f4088 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/.mxproject +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/.mxproject @@ -1,8 +1,8 @@ [PreviousLibFiles] -LibFiles=Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_fmc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_mdma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_def.h;Drivers\STM32H7xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_sdram.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart_ex.h;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_fmc.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sdram.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_fmc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_mdma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_def.h;Drivers\STM32H7xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_sdram.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart_ex.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h743xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h7xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\system_stm32h7xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h; +LibFiles=Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_fmc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_mdma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_def.h;Drivers\STM32H7xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_sdram.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_qspi.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_sdmmc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_sd.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_delayblock.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_sd_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pcd.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pcd_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_usb.h;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_fmc.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sdram.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_qspi.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_sdmmc.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_delayblock.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sd.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sd_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_usb.c;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_fmc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_mdma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_def.h;Drivers\STM32H7xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_sdram.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_qspi.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_sdmmc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_sd.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_delayblock.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_sd_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pcd.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pcd_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_usb.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h743xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h7xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\system_stm32h7xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h; [PreviousUsedKeilFiles] -SourceFiles=..\Core\Src\main.c;..\Core\Src\stm32h7xx_it.c;..\Core\Src\stm32h7xx_hal_msp.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_fmc.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sdram.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;..\Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;..\Core\Src\system_stm32h7xx.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_fmc.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sdram.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;..\Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;..\Core\Src\system_stm32h7xx.c;;; +SourceFiles=..\Core\Src\main.c;..\Core\Src\stm32h7xx_it.c;..\Core\Src\stm32h7xx_hal_msp.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_fmc.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sdram.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_qspi.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_sdmmc.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_delayblock.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sd.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sd_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_usb.c;..\Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;..\Core\Src\system_stm32h7xx.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_fmc.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sdram.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_qspi.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_sdmmc.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_delayblock.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sd.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sd_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd_ex.c;..\Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_usb.c;..\Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;..\Core\Src\system_stm32h7xx.c;;; HeaderPath=..\Drivers\STM32H7xx_HAL_Driver\Inc;..\Drivers\STM32H7xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32H7xx\Include;..\Drivers\CMSIS\Include;..\Core\Inc; CDefines=USE_HAL_DRIVER;STM32H743xx;USE_HAL_DRIVER;USE_HAL_DRIVER; diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/main.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/main.h index c2e05f070..2a5f7379f 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/main.h +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/main.h @@ -49,6 +49,8 @@ extern "C" { /* USER CODE END EM */ +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + /* Exported functions prototypes ---------------------------------------------*/ void Error_Handler(void); @@ -59,10 +61,6 @@ void Error_Handler(void); /* Private defines -----------------------------------------------------------*/ #define LED_RED_Pin GPIO_PIN_0 #define LED_RED_GPIO_Port GPIOC -#define LED_GREEN_Pin GPIO_PIN_1 -#define LED_GREEN_GPIO_Port GPIOC -#define LED_BLUE_Pin GPIO_PIN_2 -#define LED_BLUE_GPIO_Port GPIOC /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/stm32h7xx_hal_conf.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/stm32h7xx_hal_conf.h index 4e2bd0598..6605d2cac 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/stm32h7xx_hal_conf.h +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/stm32h7xx_hal_conf.h @@ -43,7 +43,7 @@ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ -/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DCMI_MODULE_ENABLED /* #define HAL_DMA2D_MODULE_ENABLED */ /* #define HAL_ETH_MODULE_ENABLED */ /* #define HAL_NAND_MODULE_ENABLED */ @@ -64,23 +64,23 @@ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_LPTIM_MODULE_ENABLED */ /* #define HAL_LTDC_MODULE_ENABLED */ -/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_QSPI_MODULE_ENABLED /* #define HAL_RAMECC_MODULE_ENABLED */ /* #define HAL_RNG_MODULE_ENABLED */ -/* #define HAL_RTC_MODULE_ENABLED */ +#define HAL_RTC_MODULE_ENABLED /* #define HAL_SAI_MODULE_ENABLED */ -/* #define HAL_SD_MODULE_ENABLED */ +#define HAL_SD_MODULE_ENABLED /* #define HAL_MMC_MODULE_ENABLED */ /* #define HAL_SPDIFRX_MODULE_ENABLED */ /* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_SWPMI_MODULE_ENABLED */ -/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_TIM_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ -/* #define HAL_PCD_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED /* #define HAL_HCD_MODULE_ENABLED */ /* #define HAL_DFSDM_MODULE_ENABLED */ /* #define HAL_DSI_MODULE_ENABLED */ @@ -168,7 +168,7 @@ #define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority */ #define USE_RTOS 0 #define USE_SD_TRANSCEIVER 0U /*!< use uSD Transceiver */ -#define USE_SPI_CRC 0U /*!< use CRC in SPI */ +#define USE_SPI_CRC 0U /*!< use CRC in SPI */ #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ #define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/stm32h7xx_it.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/stm32h7xx_it.h index edc9db7de..63ec9f9ee 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/stm32h7xx_it.h +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Inc/stm32h7xx_it.h @@ -55,6 +55,11 @@ void SVC_Handler(void); void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); +void DMA1_Stream3_IRQHandler(void); +void SDMMC1_IRQHandler(void); +void DCMI_IRQHandler(void); +void OTG_FS_EP1_OUT_IRQHandler(void); +void OTG_FS_EP1_IN_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Src/main.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Src/main.c index 8dfc5fff5..0fadc19f3 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Src/main.c +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Src/main.c @@ -40,8 +40,21 @@ /* Private variables ---------------------------------------------------------*/ +DCMI_HandleTypeDef hdcmi; +DMA_HandleTypeDef hdma_dcmi; + +QSPI_HandleTypeDef hqspi; + +RTC_HandleTypeDef hrtc; + +SD_HandleTypeDef hsd1; + +TIM_HandleTypeDef htim1; + UART_HandleTypeDef huart1; +PCD_HandleTypeDef hpcd_USB_OTG_FS; + SDRAM_HandleTypeDef hsdram1; /* USER CODE BEGIN PV */ @@ -53,6 +66,13 @@ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); static void MX_FMC_Init(void); +static void MX_QUADSPI_Init(void); +static void MX_SDMMC1_SD_Init(void); +static void MX_DMA_Init(void); +static void MX_RTC_Init(void); +static void MX_DCMI_Init(void); +static void MX_USB_OTG_FS_PCD_Init(void); +static void MX_TIM1_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -72,6 +92,12 @@ int main(void) /* USER CODE END 1 */ + /* Enable I-Cache---------------------------------------------------------*/ + SCB_EnableICache(); + + /* Enable D-Cache---------------------------------------------------------*/ + SCB_EnableDCache(); + /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ @@ -92,6 +118,13 @@ int main(void) MX_GPIO_Init(); MX_USART1_UART_Init(); MX_FMC_Init(); + MX_QUADSPI_Init(); + MX_SDMMC1_SD_Init(); + MX_DMA_Init(); + MX_RTC_Init(); + MX_DCMI_Init(); + MX_USB_OTG_FS_PCD_Init(); + MX_TIM1_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ @@ -119,24 +152,25 @@ void SystemClock_Config(void) /** Supply configuration update enable */ HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); - /** Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} - /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_LSI + |RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 3; RCC_OscInitStruct.PLL.PLLN = 200; RCC_OscInitStruct.PLL.PLLP = 2; - RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; @@ -145,7 +179,6 @@ void SystemClock_Config(void) { Error_Handler(); } - /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK @@ -165,6 +198,242 @@ void SystemClock_Config(void) } } +/** + * @brief DCMI Initialization Function + * @param None + * @retval None + */ +static void MX_DCMI_Init(void) +{ + + /* USER CODE BEGIN DCMI_Init 0 */ + + /* USER CODE END DCMI_Init 0 */ + + /* USER CODE BEGIN DCMI_Init 1 */ + + /* USER CODE END DCMI_Init 1 */ + hdcmi.Instance = DCMI; + hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; + hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_FALLING; + hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_LOW; + hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW; + hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME; + hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B; + hdcmi.Init.JPEGMode = DCMI_JPEG_ENABLE; + hdcmi.Init.ByteSelectMode = DCMI_BSM_ALL; + hdcmi.Init.ByteSelectStart = DCMI_OEBS_ODD; + hdcmi.Init.LineSelectMode = DCMI_LSM_ALL; + hdcmi.Init.LineSelectStart = DCMI_OELS_ODD; + if (HAL_DCMI_Init(&hdcmi) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN DCMI_Init 2 */ + + /* USER CODE END DCMI_Init 2 */ + +} + +/** + * @brief QUADSPI Initialization Function + * @param None + * @retval None + */ +static void MX_QUADSPI_Init(void) +{ + + /* USER CODE BEGIN QUADSPI_Init 0 */ + + /* USER CODE END QUADSPI_Init 0 */ + + /* USER CODE BEGIN QUADSPI_Init 1 */ + + /* USER CODE END QUADSPI_Init 1 */ + /* QUADSPI parameter configuration*/ + hqspi.Instance = QUADSPI; + hqspi.Init.ClockPrescaler = 1; + hqspi.Init.FifoThreshold = 3; + hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; + hqspi.Init.FlashSize = 24; + hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE; + hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0; + hqspi.Init.FlashID = QSPI_FLASH_ID_1; + hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE; + if (HAL_QSPI_Init(&hqspi) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN QUADSPI_Init 2 */ + + /* USER CODE END QUADSPI_Init 2 */ + +} + +/** + * @brief RTC Initialization Function + * @param None + * @retval None + */ +static void MX_RTC_Init(void) +{ + + /* USER CODE BEGIN RTC_Init 0 */ + + /* USER CODE END RTC_Init 0 */ + + RTC_TimeTypeDef sTime = {0}; + RTC_DateTypeDef sDate = {0}; + + /* USER CODE BEGIN RTC_Init 1 */ + + /* USER CODE END RTC_Init 1 */ + /** Initialize RTC Only + */ + hrtc.Instance = RTC; + hrtc.Init.HourFormat = RTC_HOURFORMAT_24; + hrtc.Init.AsynchPrediv = 127; + hrtc.Init.SynchPrediv = 255; + hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; + hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE; + if (HAL_RTC_Init(&hrtc) != HAL_OK) + { + Error_Handler(); + } + + /* USER CODE BEGIN Check_RTC_BKUP */ + + /* USER CODE END Check_RTC_BKUP */ + + /** Initialize RTC and set the Time and Date + */ + sTime.Hours = 0x0; + sTime.Minutes = 0x0; + sTime.Seconds = 0x0; + sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; + sTime.StoreOperation = RTC_STOREOPERATION_RESET; + if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) + { + Error_Handler(); + } + sDate.WeekDay = RTC_WEEKDAY_MONDAY; + sDate.Month = RTC_MONTH_JANUARY; + sDate.Date = 0x1; + sDate.Year = 0x0; + + if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN RTC_Init 2 */ + + /* USER CODE END RTC_Init 2 */ + +} + +/** + * @brief SDMMC1 Initialization Function + * @param None + * @retval None + */ +static void MX_SDMMC1_SD_Init(void) +{ + + /* USER CODE BEGIN SDMMC1_Init 0 */ + + /* USER CODE END SDMMC1_Init 0 */ + + /* USER CODE BEGIN SDMMC1_Init 1 */ + + /* USER CODE END SDMMC1_Init 1 */ + hsd1.Instance = SDMMC1; + hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; + hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; + hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B; + hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; + hsd1.Init.ClockDiv = 4; + if (HAL_SD_Init(&hsd1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SDMMC1_Init 2 */ + + /* USER CODE END SDMMC1_Init 2 */ + +} + +/** + * @brief TIM1 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM1_Init(void) +{ + + /* USER CODE BEGIN TIM1_Init 0 */ + + /* USER CODE END TIM1_Init 0 */ + + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; + + /* USER CODE BEGIN TIM1_Init 1 */ + + /* USER CODE END TIM1_Init 1 */ + htim1.Instance = TIM1; + htim1.Init.Prescaler = 0; + htim1.Init.CounterMode = TIM_COUNTERMODE_UP; + htim1.Init.Period = 7; + htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim1.Init.RepetitionCounter = 0; + htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = 3; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; + sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; + if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; + sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; + sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; + sBreakDeadTimeConfig.DeadTime = 0; + sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; + sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; + sBreakDeadTimeConfig.BreakFilter = 0; + sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE; + sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH; + sBreakDeadTimeConfig.Break2Filter = 0; + sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; + if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM1_Init 2 */ + + /* USER CODE END TIM1_Init 2 */ + HAL_TIM_MspPostInit(&htim1); + +} + /** * @brief USART1 Initialization Function * @param None @@ -213,6 +482,58 @@ static void MX_USART1_UART_Init(void) } +/** + * @brief USB_OTG_FS Initialization Function + * @param None + * @retval None + */ +static void MX_USB_OTG_FS_PCD_Init(void) +{ + + /* USER CODE BEGIN USB_OTG_FS_Init 0 */ + + /* USER CODE END USB_OTG_FS_Init 0 */ + + /* USER CODE BEGIN USB_OTG_FS_Init 1 */ + + /* USER CODE END USB_OTG_FS_Init 1 */ + hpcd_USB_OTG_FS.Instance = USB_OTG_FS; + hpcd_USB_OTG_FS.Init.dev_endpoints = 9; + hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL; + hpcd_USB_OTG_FS.Init.dma_enable = DISABLE; + hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED; + hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE; + hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE; + hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE; + hpcd_USB_OTG_FS.Init.battery_charging_enable = DISABLE; + hpcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE; + hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE; + if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USB_OTG_FS_Init 2 */ + + /* USER CODE END USB_OTG_FS_Init 2 */ + +} + +/** + * Enable DMA controller clock + */ +static void MX_DMA_Init(void) +{ + + /* DMA controller clock enable */ + __HAL_RCC_DMA1_CLK_ENABLE(); + + /* DMA interrupt init */ + /* DMA1_Stream3_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn); + +} + /* FMC initialization function */ static void MX_FMC_Init(void) { @@ -271,24 +592,24 @@ static void MX_GPIO_Init(void) /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOI_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(GPIOC, LED_RED_Pin|LED_GREEN_Pin|LED_BLUE_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET); - /*Configure GPIO pins : LED_RED_Pin LED_GREEN_Pin LED_BLUE_Pin */ - GPIO_InitStruct.Pin = LED_RED_Pin|LED_GREEN_Pin|LED_BLUE_Pin; + /*Configure GPIO pin : LED_RED_Pin */ + GPIO_InitStruct.Pin = LED_RED_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + HAL_GPIO_Init(LED_RED_GPIO_Port, &GPIO_InitStruct); } @@ -327,3 +648,4 @@ void assert_failed(uint8_t *file, uint32_t line) /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ + diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Src/stm32h7xx_hal_msp.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Src/stm32h7xx_hal_msp.c index c214b85e2..bc295e6c7 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Src/stm32h7xx_hal_msp.c +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/Core/Src/stm32h7xx_hal_msp.c @@ -25,6 +25,7 @@ #include "drv_common.h" #endif /* USER CODE END Includes */ +extern DMA_HandleTypeDef hdma_dcmi; /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN TD */ @@ -59,7 +60,9 @@ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ -/** + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + /** * Initializes the Global MSP. */ void HAL_MspInit(void) @@ -77,6 +80,484 @@ void HAL_MspInit(void) /* USER CODE END MspInit 1 */ } +/** +* @brief DCMI MSP Initialization +* This function configures the hardware resources used in this example +* @param hdcmi: DCMI handle pointer +* @retval None +*/ +void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hdcmi->Instance==DCMI) + { + /* USER CODE BEGIN DCMI_MspInit 0 */ + + /* USER CODE END DCMI_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_DCMI_CLK_ENABLE(); + + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**DCMI GPIO Configuration + PE4 ------> DCMI_D4 + PE5 ------> DCMI_D6 + PE6 ------> DCMI_D7 + PB7 ------> DCMI_VSYNC + PB6 ------> DCMI_D5 + PG11 ------> DCMI_D3 + PG10 ------> DCMI_D2 + PC7 ------> DCMI_D1 + PC6 ------> DCMI_D0 + PA4 ------> DCMI_HSYNC + PA6 ------> DCMI_PIXCLK + */ + GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF13_DCMI; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_6; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF13_DCMI; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF13_DCMI; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_6; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF13_DCMI; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_6; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF13_DCMI; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* DCMI DMA Init */ + /* DCMI Init */ + hdma_dcmi.Instance = DMA1_Stream3; + hdma_dcmi.Init.Request = DMA_REQUEST_DCMI; + hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE; + hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; + hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; + hdma_dcmi.Init.Mode = DMA_CIRCULAR; + hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH; + hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE; + hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + hdma_dcmi.Init.MemBurst = DMA_MBURST_SINGLE; + hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE; + if (HAL_DMA_Init(&hdma_dcmi) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(hdcmi,DMA_Handle,hdma_dcmi); + + /* DCMI interrupt Init */ + HAL_NVIC_SetPriority(DCMI_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DCMI_IRQn); + /* USER CODE BEGIN DCMI_MspInit 1 */ + + /* USER CODE END DCMI_MspInit 1 */ + } + +} + +/** +* @brief DCMI MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hdcmi: DCMI handle pointer +* @retval None +*/ +void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef* hdcmi) +{ + if(hdcmi->Instance==DCMI) + { + /* USER CODE BEGIN DCMI_MspDeInit 0 */ + + /* USER CODE END DCMI_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_DCMI_CLK_DISABLE(); + + /**DCMI GPIO Configuration + PE4 ------> DCMI_D4 + PE5 ------> DCMI_D6 + PE6 ------> DCMI_D7 + PB7 ------> DCMI_VSYNC + PB6 ------> DCMI_D5 + PG11 ------> DCMI_D3 + PG10 ------> DCMI_D2 + PC7 ------> DCMI_D1 + PC6 ------> DCMI_D0 + PA4 ------> DCMI_HSYNC + PA6 ------> DCMI_PIXCLK + */ + HAL_GPIO_DeInit(GPIOE, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6); + + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7|GPIO_PIN_6); + + HAL_GPIO_DeInit(GPIOG, GPIO_PIN_11|GPIO_PIN_10); + + HAL_GPIO_DeInit(GPIOC, GPIO_PIN_7|GPIO_PIN_6); + + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4|GPIO_PIN_6); + + /* DCMI DMA DeInit */ + HAL_DMA_DeInit(hdcmi->DMA_Handle); + + /* DCMI interrupt DeInit */ + HAL_NVIC_DisableIRQ(DCMI_IRQn); + /* USER CODE BEGIN DCMI_MspDeInit 1 */ + + /* USER CODE END DCMI_MspDeInit 1 */ + } + +} + +/** +* @brief QSPI MSP Initialization +* This function configures the hardware resources used in this example +* @param hqspi: QSPI handle pointer +* @retval None +*/ +void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + if(hqspi->Instance==QUADSPI) + { + /* USER CODE BEGIN QUADSPI_MspInit 0 */ + + /* USER CODE END QUADSPI_MspInit 0 */ + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_QSPI; + PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_D1HCLK; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /* Peripheral clock enable */ + __HAL_RCC_QSPI_CLK_ENABLE(); + + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + /**QUADSPI GPIO Configuration + PG6 ------> QUADSPI_BK1_NCS + PF7 ------> QUADSPI_BK1_IO2 + PF6 ------> QUADSPI_BK1_IO3 + PF10 ------> QUADSPI_CLK + PF9 ------> QUADSPI_BK1_IO1 + PF8 ------> QUADSPI_BK1_IO0 + */ + GPIO_InitStruct.Pin = GPIO_PIN_6; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI; + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_8; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + /* USER CODE BEGIN QUADSPI_MspInit 1 */ + + /* USER CODE END QUADSPI_MspInit 1 */ + } + +} + +/** +* @brief QSPI MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hqspi: QSPI handle pointer +* @retval None +*/ +void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef* hqspi) +{ + if(hqspi->Instance==QUADSPI) + { + /* USER CODE BEGIN QUADSPI_MspDeInit 0 */ + + /* USER CODE END QUADSPI_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_QSPI_CLK_DISABLE(); + + /**QUADSPI GPIO Configuration + PG6 ------> QUADSPI_BK1_NCS + PF7 ------> QUADSPI_BK1_IO2 + PF6 ------> QUADSPI_BK1_IO3 + PF10 ------> QUADSPI_CLK + PF9 ------> QUADSPI_BK1_IO1 + PF8 ------> QUADSPI_BK1_IO0 + */ + HAL_GPIO_DeInit(GPIOG, GPIO_PIN_6); + + HAL_GPIO_DeInit(GPIOF, GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_10|GPIO_PIN_9 + |GPIO_PIN_8); + + /* USER CODE BEGIN QUADSPI_MspDeInit 1 */ + + /* USER CODE END QUADSPI_MspDeInit 1 */ + } + +} + +/** +* @brief RTC MSP Initialization +* This function configures the hardware resources used in this example +* @param hrtc: RTC handle pointer +* @retval None +*/ +void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) +{ + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + if(hrtc->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspInit 0 */ + + /* USER CODE END RTC_MspInit 0 */ + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /* Peripheral clock enable */ + __HAL_RCC_RTC_ENABLE(); + /* USER CODE BEGIN RTC_MspInit 1 */ + + /* USER CODE END RTC_MspInit 1 */ + } + +} + +/** +* @brief RTC MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hrtc: RTC handle pointer +* @retval None +*/ +void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc) +{ + if(hrtc->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspDeInit 0 */ + + /* USER CODE END RTC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_RTC_DISABLE(); + /* USER CODE BEGIN RTC_MspDeInit 1 */ + + /* USER CODE END RTC_MspDeInit 1 */ + } + +} + +/** +* @brief SD MSP Initialization +* This function configures the hardware resources used in this example +* @param hsd: SD handle pointer +* @retval None +*/ +void HAL_SD_MspInit(SD_HandleTypeDef* hsd) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + if(hsd->Instance==SDMMC1) + { + /* USER CODE BEGIN SDMMC1_MspInit 0 */ + + /* USER CODE END SDMMC1_MspInit 0 */ + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SDMMC; + PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /* Peripheral clock enable */ + __HAL_RCC_SDMMC1_CLK_ENABLE(); + + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + /**SDMMC1 GPIO Configuration + PC12 ------> SDMMC1_CK + PC11 ------> SDMMC1_D3 + PC10 ------> SDMMC1_D2 + PD2 ------> SDMMC1_CMD + PC9 ------> SDMMC1_D1 + PC8 ------> SDMMC1_D0 + */ + GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_10|GPIO_PIN_9 + |GPIO_PIN_8; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_2; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /* SDMMC1 interrupt Init */ + HAL_NVIC_SetPriority(SDMMC1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(SDMMC1_IRQn); + /* USER CODE BEGIN SDMMC1_MspInit 1 */ + + /* USER CODE END SDMMC1_MspInit 1 */ + } + +} + +/** +* @brief SD MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hsd: SD handle pointer +* @retval None +*/ +void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd) +{ + if(hsd->Instance==SDMMC1) + { + /* USER CODE BEGIN SDMMC1_MspDeInit 0 */ + + /* USER CODE END SDMMC1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SDMMC1_CLK_DISABLE(); + + /**SDMMC1 GPIO Configuration + PC12 ------> SDMMC1_CK + PC11 ------> SDMMC1_D3 + PC10 ------> SDMMC1_D2 + PD2 ------> SDMMC1_CMD + PC9 ------> SDMMC1_D1 + PC8 ------> SDMMC1_D0 + */ + HAL_GPIO_DeInit(GPIOC, GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_10|GPIO_PIN_9 + |GPIO_PIN_8); + + HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2); + + /* SDMMC1 interrupt DeInit */ + HAL_NVIC_DisableIRQ(SDMMC1_IRQn); + /* USER CODE BEGIN SDMMC1_MspDeInit 1 */ + + /* USER CODE END SDMMC1_MspDeInit 1 */ + } + +} + +/** +* @brief TIM_PWM MSP Initialization +* This function configures the hardware resources used in this example +* @param htim_pwm: TIM_PWM handle pointer +* @retval None +*/ +void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* htim_pwm) +{ + if(htim_pwm->Instance==TIM1) + { + /* USER CODE BEGIN TIM1_MspInit 0 */ + + /* USER CODE END TIM1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM1_CLK_ENABLE(); + /* USER CODE BEGIN TIM1_MspInit 1 */ + + /* USER CODE END TIM1_MspInit 1 */ + } + +} + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(htim->Instance==TIM1) + { + /* USER CODE BEGIN TIM1_MspPostInit 0 */ + + /* USER CODE END TIM1_MspPostInit 0 */ + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**TIM1 GPIO Configuration + PA8 ------> TIM1_CH1 + */ + GPIO_InitStruct.Pin = GPIO_PIN_8; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN TIM1_MspPostInit 1 */ + + /* USER CODE END TIM1_MspPostInit 1 */ + } + +} +/** +* @brief TIM_PWM MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param htim_pwm: TIM_PWM handle pointer +* @retval None +*/ +void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* htim_pwm) +{ + if(htim_pwm->Instance==TIM1) + { + /* USER CODE BEGIN TIM1_MspDeInit 0 */ + + /* USER CODE END TIM1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM1_CLK_DISABLE(); + /* USER CODE BEGIN TIM1_MspDeInit 1 */ + + /* USER CODE END TIM1_MspDeInit 1 */ + } + +} + /** * @brief UART MSP Initialization * This function configures the hardware resources used in this example @@ -92,7 +573,6 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart) /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ - /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1; @@ -153,6 +633,91 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) } +/** +* @brief PCD MSP Initialization +* This function configures the hardware resources used in this example +* @param hpcd: PCD handle pointer +* @retval None +*/ +void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + if(hpcd->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspInit 0 */ + + /* USER CODE END USB_OTG_FS_MspInit 0 */ + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } + /** Enable USB Voltage detector + */ + HAL_PWREx_EnableUSBVoltageDetector(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USB_OTG_FS GPIO Configuration + PA12 ------> USB_OTG_FS_DP + PA11 ------> USB_OTG_FS_DM + */ + GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + /* USB_OTG_FS interrupt Init */ + HAL_NVIC_SetPriority(OTG_FS_EP1_OUT_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(OTG_FS_EP1_OUT_IRQn); + HAL_NVIC_SetPriority(OTG_FS_EP1_IN_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(OTG_FS_EP1_IN_IRQn); + /* USER CODE BEGIN USB_OTG_FS_MspInit 1 */ + + /* USER CODE END USB_OTG_FS_MspInit 1 */ + } + +} + +/** +* @brief PCD MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hpcd: PCD handle pointer +* @retval None +*/ +void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd) +{ + if(hpcd->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USB_OTG_FS_CLK_DISABLE(); + + /**USB_OTG_FS GPIO Configuration + PA12 ------> USB_OTG_FS_DP + PA11 ------> USB_OTG_FS_DM + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12|GPIO_PIN_11); + + /* USB_OTG_FS interrupt DeInit */ + HAL_NVIC_DisableIRQ(OTG_FS_EP1_OUT_IRQn); + HAL_NVIC_DisableIRQ(OTG_FS_EP1_IN_IRQn); + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 1 */ + } + +} + static uint32_t FMC_Initialized = 0; static void HAL_FMC_MspInit(void){ @@ -430,3 +995,4 @@ void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef* hsdram){ /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ + diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/CubeMX_Config.ioc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/CubeMX_Config.ioc index eade1aaf9..81714499b 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/CubeMX_Config.ioc +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/CubeMX_Config/CubeMX_Config.ioc @@ -1,4 +1,32 @@ #MicroXplorer Configuration settings - do not modify +CORTEX_M7.CPU_DCache=Enabled +CORTEX_M7.CPU_ICache=Enabled +CORTEX_M7.IPParameters=CPU_ICache,CPU_DCache +DCMI.IPParameters=JPEGMode +DCMI.JPEGMode=DCMI_JPEG_ENABLE +Dma.DCMI.0.Direction=DMA_PERIPH_TO_MEMORY +Dma.DCMI.0.EventEnable=DISABLE +Dma.DCMI.0.FIFOMode=DMA_FIFOMODE_ENABLE +Dma.DCMI.0.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL +Dma.DCMI.0.Instance=DMA1_Stream3 +Dma.DCMI.0.MemBurst=DMA_MBURST_SINGLE +Dma.DCMI.0.MemDataAlignment=DMA_MDATAALIGN_WORD +Dma.DCMI.0.MemInc=DMA_MINC_ENABLE +Dma.DCMI.0.Mode=DMA_CIRCULAR +Dma.DCMI.0.PeriphBurst=DMA_PBURST_SINGLE +Dma.DCMI.0.PeriphDataAlignment=DMA_PDATAALIGN_WORD +Dma.DCMI.0.PeriphInc=DMA_PINC_DISABLE +Dma.DCMI.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING +Dma.DCMI.0.Priority=DMA_PRIORITY_HIGH +Dma.DCMI.0.RequestNumber=1 +Dma.DCMI.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber +Dma.DCMI.0.SignalID=NONE +Dma.DCMI.0.SyncEnable=DISABLE +Dma.DCMI.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT +Dma.DCMI.0.SyncRequestNumber=1 +Dma.DCMI.0.SyncSignalID=NONE +Dma.Request0=DCMI +Dma.RequestsNb=1 FMC.BankMapConfig=FMC_SWAPBMAP_DISABLE FMC.CASLatency1=FMC_SDRAM_CAS_LATENCY_2 FMC.ColumnBitsNumber1=FMC_SDRAM_COLUMN_BITS_NUM_9 @@ -18,117 +46,189 @@ KeepUserPlacement=false Mcu.CPN=STM32H743IIK6 Mcu.Family=STM32H7 Mcu.IP0=CORTEX_M7 -Mcu.IP1=FMC -Mcu.IP2=NVIC -Mcu.IP3=RCC -Mcu.IP4=SYS -Mcu.IP5=USART1 -Mcu.IPNb=6 +Mcu.IP1=DCMI +Mcu.IP10=TIM1 +Mcu.IP11=USART1 +Mcu.IP12=USB_OTG_FS +Mcu.IP2=DMA +Mcu.IP3=FMC +Mcu.IP4=NVIC +Mcu.IP5=QUADSPI +Mcu.IP6=RCC +Mcu.IP7=RTC +Mcu.IP8=SDMMC1 +Mcu.IP9=SYS +Mcu.IPNb=13 Mcu.Name=STM32H743IIKx Mcu.Package=UFBGA176 Mcu.Pin0=PE1 Mcu.Pin1=PE0 -Mcu.Pin10=PI9 -Mcu.Pin11=PI4 -Mcu.Pin12=PH15 -Mcu.Pin13=PI1 -Mcu.Pin14=PF0 -Mcu.Pin15=PI10 -Mcu.Pin16=PH13 -Mcu.Pin17=PH14 -Mcu.Pin18=PI0 -Mcu.Pin19=PH0-OSC_IN (PH0) -Mcu.Pin2=PG15 -Mcu.Pin20=PH1-OSC_OUT (PH1) -Mcu.Pin21=PF2 -Mcu.Pin22=PF1 -Mcu.Pin23=PG8 -Mcu.Pin24=PF3 -Mcu.Pin25=PF4 -Mcu.Pin26=PF5 -Mcu.Pin27=PH12 -Mcu.Pin28=PG5 -Mcu.Pin29=PG4 -Mcu.Pin3=PD0 -Mcu.Pin30=PH11 -Mcu.Pin31=PH10 -Mcu.Pin32=PD15 -Mcu.Pin33=PC0 -Mcu.Pin34=PC1 -Mcu.Pin35=PC2_C -Mcu.Pin36=PG1 -Mcu.Pin37=PH8 -Mcu.Pin38=PH9 -Mcu.Pin39=PD14 -Mcu.Pin4=PI7 -Mcu.Pin40=PC4 -Mcu.Pin41=PF13 -Mcu.Pin42=PG0 -Mcu.Pin43=PE13 -Mcu.Pin44=PD10 -Mcu.Pin45=PC5 -Mcu.Pin46=PF12 -Mcu.Pin47=PF15 -Mcu.Pin48=PE8 -Mcu.Pin49=PE9 -Mcu.Pin5=PI6 -Mcu.Pin50=PE11 -Mcu.Pin51=PE14 -Mcu.Pin52=PD9 -Mcu.Pin53=PD8 -Mcu.Pin54=PA7 -Mcu.Pin55=PF11 -Mcu.Pin56=PF14 -Mcu.Pin57=PE7 -Mcu.Pin58=PE10 -Mcu.Pin59=PE12 -Mcu.Pin6=PI5 -Mcu.Pin60=PE15 -Mcu.Pin61=PB14 -Mcu.Pin62=PB15 -Mcu.Pin63=VP_SYS_VS_Systick -Mcu.Pin7=PD1 -Mcu.Pin8=PI3 -Mcu.Pin9=PI2 -Mcu.PinsNb=64 +Mcu.Pin10=PG10 +Mcu.Pin11=PD0 +Mcu.Pin12=PC11 +Mcu.Pin13=PC10 +Mcu.Pin14=PA12 +Mcu.Pin15=PI7 +Mcu.Pin16=PI6 +Mcu.Pin17=PI5 +Mcu.Pin18=PD1 +Mcu.Pin19=PI3 +Mcu.Pin2=PC12 +Mcu.Pin20=PI2 +Mcu.Pin21=PA11 +Mcu.Pin22=PI9 +Mcu.Pin23=PI4 +Mcu.Pin24=PD2 +Mcu.Pin25=PH15 +Mcu.Pin26=PI1 +Mcu.Pin27=PF0 +Mcu.Pin28=PI10 +Mcu.Pin29=PH13 +Mcu.Pin3=PE4 +Mcu.Pin30=PH14 +Mcu.Pin31=PI0 +Mcu.Pin32=PC9 +Mcu.Pin33=PA8 +Mcu.Pin34=PH0-OSC_IN (PH0) +Mcu.Pin35=PC8 +Mcu.Pin36=PC7 +Mcu.Pin37=PH1-OSC_OUT (PH1) +Mcu.Pin38=PF2 +Mcu.Pin39=PF1 +Mcu.Pin4=PE5 +Mcu.Pin40=PG8 +Mcu.Pin41=PC6 +Mcu.Pin42=PF3 +Mcu.Pin43=PF4 +Mcu.Pin44=PG6 +Mcu.Pin45=PF7 +Mcu.Pin46=PF6 +Mcu.Pin47=PF5 +Mcu.Pin48=PH12 +Mcu.Pin49=PG5 +Mcu.Pin5=PE6 +Mcu.Pin50=PG4 +Mcu.Pin51=PF10 +Mcu.Pin52=PF9 +Mcu.Pin53=PF8 +Mcu.Pin54=PH11 +Mcu.Pin55=PH10 +Mcu.Pin56=PD15 +Mcu.Pin57=PC0 +Mcu.Pin58=PG1 +Mcu.Pin59=PH8 +Mcu.Pin6=PB7 +Mcu.Pin60=PH9 +Mcu.Pin61=PD14 +Mcu.Pin62=PA4 +Mcu.Pin63=PC4 +Mcu.Pin64=PF13 +Mcu.Pin65=PG0 +Mcu.Pin66=PE13 +Mcu.Pin67=PD10 +Mcu.Pin68=PA6 +Mcu.Pin69=PC5 +Mcu.Pin7=PB6 +Mcu.Pin70=PF12 +Mcu.Pin71=PF15 +Mcu.Pin72=PE8 +Mcu.Pin73=PE9 +Mcu.Pin74=PE11 +Mcu.Pin75=PE14 +Mcu.Pin76=PD9 +Mcu.Pin77=PD8 +Mcu.Pin78=PA7 +Mcu.Pin79=PF11 +Mcu.Pin8=PG15 +Mcu.Pin80=PF14 +Mcu.Pin81=PE7 +Mcu.Pin82=PE10 +Mcu.Pin83=PE12 +Mcu.Pin84=PE15 +Mcu.Pin85=PB14 +Mcu.Pin86=PB15 +Mcu.Pin87=VP_RTC_VS_RTC_Activate +Mcu.Pin88=VP_RTC_VS_RTC_Calendar +Mcu.Pin89=VP_SYS_VS_Systick +Mcu.Pin9=PG11 +Mcu.PinsNb=90 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32H743IIKx -MxCube.Version=6.5.0 -MxDb.Version=DB.6.0.50 +MxCube.Version=6.4.0 +MxDb.Version=DB.6.0.40 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true +NVIC.DCMI_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.DMA1_Stream3_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true NVIC.ForceEnableDMAVector=true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true +NVIC.OTG_FS_EP1_IN_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.OTG_FS_EP1_OUT_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SDMMC1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true +PA11.GPIOParameters=GPIO_Speed +PA11.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PA11.Mode=Device_Only +PA11.Signal=USB_OTG_FS_DM +PA12.GPIOParameters=GPIO_Speed +PA12.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PA12.Mode=Device_Only +PA12.Signal=USB_OTG_FS_DP +PA4.GPIOParameters=GPIO_Speed,GPIO_PuPd +PA4.GPIO_PuPd=GPIO_PULLUP +PA4.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PA4.Locked=true +PA4.Mode=Slave_8_bits_External_Synchro +PA4.Signal=DCMI_HSYNC +PA6.GPIOParameters=GPIO_Speed,GPIO_PuPd +PA6.GPIO_PuPd=GPIO_PULLUP +PA6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PA6.Locked=true +PA6.Mode=Slave_8_bits_External_Synchro +PA6.Signal=DCMI_PIXCLK PA7.GPIOParameters=GPIO_PuPd PA7.GPIO_PuPd=GPIO_PULLUP PA7.Locked=true PA7.Signal=FMC_SDNWE +PA8.GPIOParameters=GPIO_Speed,GPIO_PuPd +PA8.GPIO_PuPd=GPIO_PULLUP +PA8.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PA8.Signal=S_TIM1_CH1 PB14.Locked=true PB14.Mode=Asynchronous PB14.Signal=USART1_TX PB15.Locked=true PB15.Mode=Asynchronous PB15.Signal=USART1_RX +PB6.GPIOParameters=GPIO_Speed,GPIO_PuPd +PB6.GPIO_PuPd=GPIO_PULLUP +PB6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PB6.Locked=true +PB6.Mode=Slave_8_bits_External_Synchro +PB6.Signal=DCMI_D5 +PB7.GPIOParameters=GPIO_Speed,GPIO_PuPd +PB7.GPIO_PuPd=GPIO_PULLUP +PB7.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PB7.Locked=true +PB7.Mode=Slave_8_bits_External_Synchro +PB7.Signal=DCMI_VSYNC PC0.GPIOParameters=GPIO_Label PC0.GPIO_Label=LED_RED PC0.Locked=true PC0.Signal=GPIO_Output -PC1.GPIOParameters=GPIO_Label -PC1.GPIO_Label=LED_GREEN -PC1.Locked=true -PC1.Signal=GPIO_Output -PC2_C.GPIOParameters=GPIO_Label -PC2_C.GPIO_Label=LED_BLUE -PC2_C.Locked=true -PC2_C.Signal=GPIO_Output +PC10.Mode=SD_4_bits_Wide_bus +PC10.Signal=SDMMC1_D2 +PC11.Mode=SD_4_bits_Wide_bus +PC11.Signal=SDMMC1_D3 +PC12.Mode=SD_4_bits_Wide_bus +PC12.Signal=SDMMC1_CK PC4.GPIOParameters=GPIO_PuPd PC4.GPIO_PuPd=GPIO_PULLUP PC4.Locked=true @@ -139,6 +239,22 @@ PC5.GPIO_PuPd=GPIO_PULLUP PC5.Locked=true PC5.Mode=SdramChipSelect1_1 PC5.Signal=FMC_SDCKE0 +PC6.GPIOParameters=GPIO_Speed,GPIO_PuPd +PC6.GPIO_PuPd=GPIO_PULLUP +PC6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PC6.Locked=true +PC6.Mode=Slave_8_bits_External_Synchro +PC6.Signal=DCMI_D0 +PC7.GPIOParameters=GPIO_Speed,GPIO_PuPd +PC7.GPIO_PuPd=GPIO_PULLUP +PC7.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PC7.Locked=true +PC7.Mode=Slave_8_bits_External_Synchro +PC7.Signal=DCMI_D1 +PC8.Mode=SD_4_bits_Wide_bus +PC8.Signal=SDMMC1_D0 +PC9.Mode=SD_4_bits_Wide_bus +PC9.Signal=SDMMC1_D1 PD0.GPIOParameters=GPIO_PuPd PD0.GPIO_PuPd=GPIO_PULLUP PD0.Signal=FMC_D2_DA2 @@ -154,6 +270,8 @@ PD14.Signal=FMC_D0_DA0 PD15.GPIOParameters=GPIO_PuPd PD15.GPIO_PuPd=GPIO_PULLUP PD15.Signal=FMC_D1_DA1 +PD2.Mode=SD_4_bits_Wide_bus +PD2.Signal=SDMMC1_CMD PD8.GPIOParameters=GPIO_PuPd PD8.GPIO_PuPd=GPIO_PULLUP PD8.Signal=FMC_D13_DA13 @@ -184,6 +302,24 @@ PE14.Signal=FMC_D11_DA11 PE15.GPIOParameters=GPIO_PuPd PE15.GPIO_PuPd=GPIO_PULLUP PE15.Signal=FMC_D12_DA12 +PE4.GPIOParameters=GPIO_Speed,GPIO_PuPd +PE4.GPIO_PuPd=GPIO_PULLUP +PE4.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PE4.Locked=true +PE4.Mode=Slave_8_bits_External_Synchro +PE4.Signal=DCMI_D4 +PE5.GPIOParameters=GPIO_Speed,GPIO_PuPd +PE5.GPIO_PuPd=GPIO_PULLUP +PE5.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PE5.Locked=true +PE5.Mode=Slave_8_bits_External_Synchro +PE5.Signal=DCMI_D6 +PE6.GPIOParameters=GPIO_Speed,GPIO_PuPd +PE6.GPIO_PuPd=GPIO_PULLUP +PE6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PE6.Locked=true +PE6.Mode=Slave_8_bits_External_Synchro +PE6.Signal=DCMI_D7 PE7.GPIOParameters=GPIO_PuPd PE7.GPIO_PuPd=GPIO_PULLUP PE7.Signal=FMC_D4_DA4 @@ -199,6 +335,11 @@ PF0.Signal=FMC_A0 PF1.GPIOParameters=GPIO_PuPd PF1.GPIO_PuPd=GPIO_PULLUP PF1.Signal=FMC_A1 +PF10.GPIOParameters=GPIO_Speed +PF10.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PF10.Locked=true +PF10.Mode=Single Bank 1 +PF10.Signal=QUADSPI_CLK PF11.GPIOParameters=GPIO_PuPd PF11.GPIO_PuPd=GPIO_PULLUP PF11.Signal=FMC_SDNRAS @@ -226,12 +367,44 @@ PF4.Signal=FMC_A4 PF5.GPIOParameters=GPIO_PuPd PF5.GPIO_PuPd=GPIO_PULLUP PF5.Signal=FMC_A5 +PF6.GPIOParameters=GPIO_Speed +PF6.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PF6.Locked=true +PF6.Mode=Single Bank 1 +PF6.Signal=QUADSPI_BK1_IO3 +PF7.GPIOParameters=GPIO_Speed +PF7.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PF7.Locked=true +PF7.Mode=Single Bank 1 +PF7.Signal=QUADSPI_BK1_IO2 +PF8.GPIOParameters=GPIO_Speed +PF8.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PF8.Locked=true +PF8.Mode=Single Bank 1 +PF8.Signal=QUADSPI_BK1_IO0 +PF9.GPIOParameters=GPIO_Speed +PF9.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PF9.Locked=true +PF9.Mode=Single Bank 1 +PF9.Signal=QUADSPI_BK1_IO1 PG0.GPIOParameters=GPIO_PuPd PG0.GPIO_PuPd=GPIO_PULLUP PG0.Signal=FMC_A10 PG1.GPIOParameters=GPIO_PuPd PG1.GPIO_PuPd=GPIO_PULLUP PG1.Signal=FMC_A11 +PG10.GPIOParameters=GPIO_Speed,GPIO_PuPd +PG10.GPIO_PuPd=GPIO_PULLUP +PG10.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PG10.Locked=true +PG10.Mode=Slave_8_bits_External_Synchro +PG10.Signal=DCMI_D2 +PG11.GPIOParameters=GPIO_Speed,GPIO_PuPd +PG11.GPIO_PuPd=GPIO_PULLUP +PG11.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PG11.Locked=true +PG11.Mode=Slave_8_bits_External_Synchro +PG11.Signal=DCMI_D3 PG15.GPIOParameters=GPIO_PuPd PG15.GPIO_PuPd=GPIO_PULLUP PG15.Signal=FMC_SDNCAS @@ -241,6 +414,11 @@ PG4.Signal=FMC_A14_BA0 PG5.GPIOParameters=GPIO_PuPd PG5.GPIO_PuPd=GPIO_PULLUP PG5.Signal=FMC_A15_BA1 +PG6.GPIOParameters=GPIO_PuPd +PG6.GPIO_PuPd=GPIO_PULLUP +PG6.Locked=true +PG6.Mode=Single Bank 1 +PG6.Signal=QUADSPI_BK1_NCS PG8.GPIOParameters=GPIO_PuPd PG8.GPIO_PuPd=GPIO_PULLUP PG8.Signal=FMC_SDCLK @@ -313,7 +491,7 @@ ProjectManager.CustomerFirmwarePackage= ProjectManager.DefaultFWLocation=true ProjectManager.DeletePrevious=true ProjectManager.DeviceId=STM32H743IIKx -ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.10.0 +ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.9.0 ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x200 @@ -331,7 +509,13 @@ ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=MDK-ARM V5.32 ProjectManager.ToolChainLocation= ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_FMC_Init-FMC-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_FMC_Init-FMC-false-HAL-true,5-MX_QUADSPI_Init-QUADSPI-false-HAL-true,6-MX_SDMMC1_SD_Init-SDMMC1-false-HAL-true,7-MX_DMA_Init-DMA-false-HAL-true,8-MX_RTC_Init-RTC-false-HAL-true,9-MX_DCMI_Init-DCMI-false-HAL-true,10-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true +QUADSPI.ChipSelectHighTime=QSPI_CS_HIGH_TIME_2_CYCLE +QUADSPI.ClockPrescaler=1 +QUADSPI.FifoThreshold=3 +QUADSPI.FlashSize=24 +QUADSPI.IPParameters=ClockPrescaler,FifoThreshold,SampleShifting,FlashSize,ChipSelectHighTime +QUADSPI.SampleShifting=QSPI_SAMPLE_SHIFTING_HALFCYCLE RCC.ADCFreq_Value=24187500 RCC.AHB12Freq_Value=200000000 RCC.AHB4Freq_Value=200000000 @@ -349,20 +533,21 @@ RCC.D1PPRE=RCC_APB3_DIV2 RCC.D2PPRE1=RCC_APB1_DIV2 RCC.D2PPRE2=RCC_APB2_DIV2 RCC.D3PPRE=RCC_APB4_DIV2 -RCC.DFSDMACLkFreq_Value=400000000 +RCC.DFSDMACLkFreq_Value=200000000 RCC.DFSDMFreq_Value=100000000 RCC.DIVM1=3 RCC.DIVN1=200 RCC.DIVP1Freq_Value=400000000 RCC.DIVP2Freq_Value=24187500 RCC.DIVP3Freq_Value=24187500 -RCC.DIVQ1Freq_Value=400000000 +RCC.DIVQ1=4 +RCC.DIVQ1Freq_Value=200000000 RCC.DIVQ2Freq_Value=24187500 RCC.DIVQ3Freq_Value=24187500 RCC.DIVR1Freq_Value=400000000 RCC.DIVR2Freq_Value=24187500 RCC.DIVR3Freq_Value=24187500 -RCC.FDCANFreq_Value=400000000 +RCC.FDCANFreq_Value=200000000 RCC.FMCFreq_Value=200000000 RCC.FamilyName=M RCC.HCLK3ClockFreq_Value=200000000 @@ -372,7 +557,7 @@ RCC.HRTIMFreq_Value=200000000 RCC.HSE_VALUE=12000000 RCC.I2C123Freq_Value=100000000 RCC.I2C4Freq_Value=100000000 -RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVN1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,HSE_VALUE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value +RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVN1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,HSE_VALUE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBCLockSelection,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value RCC.LPTIM1Freq_Value=100000000 RCC.LPTIM2Freq_Value=100000000 RCC.LPTIM345Freq_Value=100000000 @@ -387,13 +572,13 @@ RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE RCC.QSPIFreq_Value=200000000 RCC.RNGFreq_Value=48000000 RCC.RTCFreq_Value=32000 -RCC.SAI1Freq_Value=400000000 -RCC.SAI23Freq_Value=400000000 -RCC.SAI4AFreq_Value=400000000 -RCC.SAI4BFreq_Value=400000000 -RCC.SDMMCFreq_Value=400000000 -RCC.SPDIFRXFreq_Value=400000000 -RCC.SPI123Freq_Value=400000000 +RCC.SAI1Freq_Value=200000000 +RCC.SAI23Freq_Value=200000000 +RCC.SAI4AFreq_Value=200000000 +RCC.SAI4BFreq_Value=200000000 +RCC.SDMMCFreq_Value=200000000 +RCC.SPDIFRXFreq_Value=200000000 +RCC.SPI123Freq_Value=200000000 RCC.SPI45Freq_Value=100000000 RCC.SPI6Freq_Value=100000000 RCC.SWPMI1Freq_Value=100000000 @@ -404,13 +589,16 @@ RCC.Tim2OutputFreq_Value=200000000 RCC.TraceFreq_Value=64000000 RCC.USART16Freq_Value=100000000 RCC.USART234578Freq_Value=100000000 -RCC.USBFreq_Value=400000000 +RCC.USBCLockSelection=RCC_USBCLKSOURCE_HSI48 +RCC.USBFreq_Value=48000000 RCC.VCO1OutputFreq_Value=800000000 RCC.VCO2OutputFreq_Value=48375000 RCC.VCO3OutputFreq_Value=48375000 RCC.VCOInput1Freq_Value=4000000 RCC.VCOInput2Freq_Value=375000 RCC.VCOInput3Freq_Value=375000 +SDMMC1.ClockDiv=4 +SDMMC1.IPParameters=ClockDiv SH.FMC_A0.0=FMC_A0,12b-sda1 SH.FMC_A0.ConfNb=1 SH.FMC_A1.0=FMC_A1,12b-sda1 @@ -519,8 +707,21 @@ SH.FMC_SDNRAS.0=FMC_SDNRAS,12b-sda1 SH.FMC_SDNRAS.ConfNb=1 SH.FMC_SDNWE.0=FMC_SDNWE,12b-sda1 SH.FMC_SDNWE.ConfNb=1 +SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1 +SH.S_TIM1_CH1.ConfNb=1 +TIM1.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 +TIM1.IPParameters=Channel-PWM Generation1 CH1,Period,AutoReloadPreload,Pulse-PWM Generation1 CH1 +TIM1.Period=7 +TIM1.Pulse-PWM\ Generation1\ CH1=3 USART1.IPParameters=VirtualMode-Asynchronous USART1.VirtualMode-Asynchronous=VM_ASYNC +USB_OTG_FS.IPParameters=VirtualMode +USB_OTG_FS.VirtualMode=Device_Only +VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled +VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate +VP_RTC_VS_RTC_Calendar.Mode=RTC_Calendar +VP_RTC_VS_RTC_Calendar.Signal=RTC_VS_RTC_Calendar VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick board=custom diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/Kconfig index cff9e5337..604094a85 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/Kconfig +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/Kconfig @@ -18,7 +18,7 @@ menu "On-chip Peripheral Drivers" bool "Enable UART" default y select RT_USING_SERIAL - + if BSP_USING_UART config BSP_USING_UART1 bool "Enable UART1" @@ -37,8 +37,8 @@ menu "On-chip Peripheral Drivers" bool "Enable UART2 RX DMA" depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA default n - - config BSP_USING_LPUART1 + + config BSP_USING_LPUART1 bool "Enable LPUART1" default n @@ -47,13 +47,47 @@ menu "On-chip Peripheral Drivers" depends on BSP_USING_LPUART1 && RT_SERIAL_USING_DMA default n endif - - config BSP_USING_SDRAM - bool "Enable SDRAM" - default n + + config BSP_USING_QSPI + bool "Enable QSPI BUS" + select RT_USING_QSPI + select RT_USING_SPI + default n + + config BSP_USING_ONCHIP_RTC + bool "Enable RTC" + select RT_USING_RTC + default n source "$RTT_DIR/bsp/stm32/libraries/HAL_Drivers/Kconfig" -endmenu + endmenu + + menu "Onboard Peripheral Drivers" + + config BSP_USING_SDRAM + bool "Enable SDRAM" + default n + + config BSP_USING_QSPI_FLASH + bool "Enable QSPI FLASH (W25Q256 qspi)" + select BSP_USING_QSPI + select RT_USING_SFUD + select RT_SFUD_USING_QSPI + default n + + config BSP_USING_SDMMC + bool "Enable SDMMC (SD card)" + select RT_USING_SDIO + select RT_USING_DFS + select RT_USING_DFS_ELMFAT + default n + + config BSP_USING_USBD + bool "Enable OTGFS as USB device" + select RT_USING_USB_DEVICE + default n + + endmenu endmenu diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/SConscript b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/SConscript index 17b3828b1..2f288f5d2 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/SConscript +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/SConscript @@ -14,6 +14,15 @@ CubeMX_Config/Core/Src/stm32h7xx_hal_msp.c if GetDepend(['BSP_USING_SDRAM']): src += Glob('ports/sdram_test.c') +if GetDepend(['BSP_USING_QSPI_FLASH']): + src += ['ports/drv_qspi_flash.c'] +if GetDepend(['BSP_USING_SDMMC']): + src += ['ports/drv_sdio.c'] +if GetDepend(['RT_USING_DFS_ROMFS']): + src += ['ports/romfs.c'] + src += ['ports/mnt_romfs.c'] +if GetDepend(['RT_USING_DFS_RAMFS']): + src += ['ports/mnt_ramfs.c'] path = [cwd] path += [cwd + '/CubeMX_Config/Core/Inc'] diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/board.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/board.c index 195c97cbc..de7268272 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/board.c +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/board.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -28,14 +28,15 @@ void SystemClock_Config(void) /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 3; RCC_OscInitStruct.PLL.PLLN = 200; RCC_OscInitStruct.PLL.PLLP = 2; - RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/board.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/board.h index f89013b1e..ab9fda779 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/board.h +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/board.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2021-12-14 supperthomas first version - * 2022-03-14 wwt add sram2 + * 2022-03-16 Miaowulue add sram2 */ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/drv_qspi_flash.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/drv_qspi_flash.c new file mode 100644 index 000000000..0e86224e5 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/drv_qspi_flash.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-27 zylx first version + * 2022-03-16 Miaowulue add dfs mount + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BSP_USING_QSPI_FLASH + +#include "spi_flash.h" +#include "spi_flash_sfud.h" + +char w25qxx_read_status_register2(struct rt_qspi_device *device) +{ + /* 0x35 read status register2 */ + char instruction = 0x35, status; + + rt_qspi_send_then_recv(device, &instruction, 1, &status, 1); + + return status; +} + +void w25qxx_write_enable(struct rt_qspi_device *device) +{ + /* 0x06 write enable */ + char instruction = 0x06; + + rt_qspi_send(device, &instruction, 1); +} + +void w25qxx_enter_qspi_mode(struct rt_qspi_device *device) +{ + char status = 0; + /* 0x38 enter qspi mode */ + char instruction = 0x38; + char write_status2_buf[2] = {0}; + + /* 0x31 write status register2 */ + write_status2_buf[0] = 0x31; + + status = w25qxx_read_status_register2(device); + if (!(status & 0x02)) + { + status |= 1 << 1; + w25qxx_write_enable(device); + write_status2_buf[1] = status; + rt_qspi_send(device, &write_status2_buf, 2); + rt_qspi_send(device, &instruction, 1); + rt_kprintf("flash already enter qspi mode\n"); + rt_thread_mdelay(10); + } +} + +static int rt_hw_qspi_flash_with_sfud_init(void) +{ + stm32_qspi_bus_attach_device("qspi1", "qspi10", RT_NULL, 4, w25qxx_enter_qspi_mode, RT_NULL); + + /* init W25Q256 */ + if (RT_NULL == rt_sfud_flash_probe("W25Q256", "qspi10")) + { + return -RT_ERROR; + } + + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_qspi_flash_with_sfud_init); + +static int mnt_qspi_flash_init(void) +{ + #ifdef RT_USING_DFS_ROMFS + if (dfs_mount("W25Q256", "/FLASH", "elm", 0, 0) == RT_EOK) + #else + if (dfs_mount("W25Q256", "/", "elm", 0, 0) == RT_EOK) + #endif + { + rt_kprintf("Mount spi flash successfully!\n"); + return RT_EOK; + } + else + { + rt_kprintf("Mount spi flash fail!\n"); + return -RT_ERROR; + } +} +INIT_APP_EXPORT(mnt_qspi_flash_init); + +#endif/* BSP_USING_QSPI_FLASH */ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/drv_sdio.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/drv_sdio.c new file mode 100644 index 000000000..54c6e212d --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/drv_sdio.c @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-05-23 liuduanfei first version + * 2022-03-16 Miaowulue change prompt message + */ + +#include "board.h" +#include "drv_sdio.h" +#include + +#ifdef BSP_USING_SDMMC + +#define DBG_TAG "drv.sdio" +#ifdef DRV_DEBUG +#define DBG_LVL DBG_LOG +#else +#define DBG_LVL DBG_INFO +#endif /* DRV_DEBUG */ +#include + +static struct rt_mmcsd_host *host; +#define SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS (100000) + +struct sdio_pkg +{ + struct rt_mmcsd_cmd *cmd; + void *buff; + rt_uint32_t flag; +}; + +struct rthw_sdio +{ + struct rt_mmcsd_host *host; + struct stm32_sdio_des sdio_des; + struct rt_event event; + struct sdio_pkg *pkg; +}; + +ALIGN(SDIO_ALIGN_LEN) +static rt_uint8_t cache_buf[SDIO_BUFF_SIZE]; + +/** + * @brief This function get order from sdio. + * @param data + * @retval sdio order + */ +static int get_order(rt_uint32_t data) +{ + int order = 0; + + switch (data) + { + case 1: + order = 0; + break; + case 2: + order = 1; + break; + case 4: + order = 2; + break; + case 8: + order = 3; + break; + case 16: + order = 4; + break; + case 32: + order = 5; + break; + case 64: + order = 6; + break; + case 128: + order = 7; + break; + case 256: + order = 8; + break; + case 512: + order = 9; + break; + case 1024: + order = 10; + break; + case 2048: + order = 11; + break; + case 4096: + order = 12; + break; + case 8192: + order = 13; + break; + case 16384: + order = 14; + break; + default : + order = 0; + break; + } + return order; +} + +/** + * @brief This function wait sdio cmd completed. + * @param sdio rthw_sdio + * @retval None + */ +static void rthw_sdio_wait_completed(struct rthw_sdio *sdio) +{ + rt_uint32_t status; + struct rt_mmcsd_cmd *cmd = sdio->pkg->cmd; + struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio; + + if (rt_event_recv(&sdio->event, 0xffffffff, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + rt_tick_from_millisecond(5000), &status) != RT_EOK) + { + LOG_E("wait cmd completed timeout"); + cmd->err = -RT_ETIMEOUT; + return; + } + + cmd->resp[0] = hw_sdio->resp1; + if (resp_type(cmd) == RESP_R2) + { + cmd->resp[1] = hw_sdio->resp2; + cmd->resp[2] = hw_sdio->resp3; + cmd->resp[3] = hw_sdio->resp4; + } + + if (status & SDIO_ERRORS) + { + if ((status & SDMMC_STA_CCRCFAIL) && (resp_type(cmd) & (RESP_R3 | RESP_R4))) + { + cmd->err = RT_EOK; + } + else + { + cmd->err = -RT_ERROR; + } + } + + if (cmd->err == RT_EOK) + { + LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); + } + else + { + LOG_D("send command error = %d", cmd->err); + } +} + +/** + * @brief This function send command. + * @param sdio rthw_sdio + * @param pkg sdio package + * @retval None + */ +static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg) +{ + struct rt_mmcsd_cmd *cmd = pkg->cmd; + struct rt_mmcsd_data *data = cmd->data; + struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio; + rt_uint32_t reg_cmd; + + /* save pkg */ + sdio->pkg = pkg; + + LOG_D("CMD:%d ARG:0x%08x RES:%s%s%s%s%s%s%s%s%s rw:%c len:%d blksize:%d\n", + cmd->cmd_code, + cmd->arg, + resp_type(cmd) == RESP_NONE ? "NONE" : "", + resp_type(cmd) == RESP_R1 ? "R1" : "", + resp_type(cmd) == RESP_R1B ? "R1B" : "", + resp_type(cmd) == RESP_R2 ? "R2" : "", + resp_type(cmd) == RESP_R3 ? "R3" : "", + resp_type(cmd) == RESP_R4 ? "R4" : "", + resp_type(cmd) == RESP_R5 ? "R5" : "", + resp_type(cmd) == RESP_R6 ? "R6" : "", + resp_type(cmd) == RESP_R7 ? "R7" : "", + data ? (data->flags & DATA_DIR_WRITE ? 'w' : 'r') : '-', + data ? data->blks * data->blksize : 0, + data ? data->blksize : 0 + ); + + hw_sdio->mask |= SDIO_MASKR_ALL; + reg_cmd = cmd->cmd_code | SDMMC_CMD_CPSMEN; + + /* data pre configuration */ + if (data != RT_NULL) + { + SCB_CleanInvalidateDCache(); + + reg_cmd |= SDMMC_CMD_CMDTRANS; + hw_sdio->mask &= ~(SDMMC_MASK_CMDRENDIE | SDMMC_MASK_CMDSENTIE); + hw_sdio->dtimer = HW_SDIO_DATATIMEOUT; + hw_sdio->dlen = data->blks * data->blksize; + hw_sdio->dctrl = (get_order(data->blksize)<<4) | (data->flags & DATA_DIR_READ ? SDMMC_DCTRL_DTDIR : 0); + hw_sdio->idmabase0r = (rt_uint32_t)cache_buf; + hw_sdio->idmatrlr = SDMMC_IDMA_IDMAEN; + } + + if (resp_type(cmd) == RESP_R2) + reg_cmd |= SDMMC_CMD_WAITRESP; + else if(resp_type(cmd) != RESP_NONE) + reg_cmd |= SDMMC_CMD_WAITRESP_0; + + hw_sdio->arg = cmd->arg; + hw_sdio->cmd = reg_cmd; + /* wait completed */ + rthw_sdio_wait_completed(sdio); + + /* Waiting for data to be sent to completion */ + if (data != RT_NULL) + { + volatile rt_uint32_t count = SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS; + + while (count && (hw_sdio->sta & SDMMC_STA_DPSMACT)) + { + count--; + } + if ((count == 0) || (hw_sdio->sta & SDIO_ERRORS)) + { + cmd->err = -RT_ERROR; + } + } + + /* data post configuration */ + if (data != RT_NULL) + { + if (data->flags & DATA_DIR_READ) + { + rt_memcpy(data->buf, cache_buf, data->blks * data->blksize); + SCB_CleanInvalidateDCache(); + } + } +} + +/** + * @brief This function send sdio request. + * @param sdio rthw_sdio + * @param req request + * @retval None + */ +static void rthw_sdio_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req) +{ + struct sdio_pkg pkg; + struct rthw_sdio *sdio = host->private_data; + struct rt_mmcsd_data *data; + + if (req->cmd != RT_NULL) + { + rt_memset(&pkg, 0, sizeof(pkg)); + data = req->cmd->data; + pkg.cmd = req->cmd; + + if (data != RT_NULL) + { + rt_uint32_t size = data->blks * data->blksize; + + RT_ASSERT(size <= SDIO_BUFF_SIZE); + + if (data->flags & DATA_DIR_WRITE) + { + rt_memcpy(cache_buf, data->buf, size); + } + } + + rthw_sdio_send_command(sdio, &pkg); + } + + if (req->stop != RT_NULL) + { + rt_memset(&pkg, 0, sizeof(pkg)); + pkg.cmd = req->stop; + rthw_sdio_send_command(sdio, &pkg); + } + + mmcsd_req_complete(sdio->host); +} + + +/** + * @brief This function interrupt process function. + * @param host rt_mmcsd_host + * @retval None + */ +void rthw_sdio_irq_process(struct rt_mmcsd_host *host) +{ + struct rthw_sdio *sdio = host->private_data; + struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio; + rt_uint32_t intstatus = hw_sdio->sta; + + /* clear irq flag*/ + hw_sdio->icr = intstatus; + + rt_event_send(&sdio->event, intstatus); +} + +/** + * @brief This function config sdio. + * @param host rt_mmcsd_host + * @param io_cfg rt_mmcsd_io_cfg + * @retval None + */ +static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg) +{ + rt_uint32_t temp, clk_src; + rt_uint32_t clk = io_cfg->clock; + struct rthw_sdio *sdio = host->private_data; + struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio; + + LOG_D("clk:%dK width:%s%s%s power:%s%s%s", + clk/1000, + io_cfg->bus_width == MMCSD_BUS_WIDTH_8 ? "8" : "", + io_cfg->bus_width == MMCSD_BUS_WIDTH_4 ? "4" : "", + io_cfg->bus_width == MMCSD_BUS_WIDTH_1 ? "1" : "", + io_cfg->power_mode == MMCSD_POWER_OFF ? "OFF" : "", + io_cfg->power_mode == MMCSD_POWER_UP ? "UP" : "", + io_cfg->power_mode == MMCSD_POWER_ON ? "ON" : "" + ); + + clk_src = SDIO_CLOCK_FREQ; + + if (clk > 0) + { + if (clk > host->freq_max) + clk = host->freq_max; + temp = DIV_ROUND_UP(clk_src, 2 * clk); + if (temp > 0x3FF) + temp = 0x3FF; + } + + if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4) + temp |= SDMMC_CLKCR_WIDBUS_0; + else if (io_cfg->bus_width == MMCSD_BUS_WIDTH_8) + temp |= SDMMC_CLKCR_WIDBUS_1; + + hw_sdio->clkcr = temp; + + if (io_cfg->power_mode == MMCSD_POWER_ON) + hw_sdio->power |= SDMMC_POWER_PWRCTRL; +} + +static const struct rt_mmcsd_host_ops ops = +{ + rthw_sdio_request, + rthw_sdio_iocfg, + RT_NULL, + RT_NULL, +}; + +/** + * @brief This function create mmcsd host. + * @param sdio_des stm32_sdio_des + * @retval rt_mmcsd_host + */ +struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des) +{ + struct rt_mmcsd_host *host; + struct rthw_sdio *sdio = RT_NULL; + + if (sdio_des == RT_NULL) + { + return RT_NULL; + } + + sdio = rt_malloc(sizeof(struct rthw_sdio)); + if (sdio == RT_NULL) + { + LOG_E("malloc rthw_sdio fail"); + return RT_NULL; + } + rt_memset(sdio, 0, sizeof(struct rthw_sdio)); + + host = mmcsd_alloc_host(); + if (host == RT_NULL) + { + LOG_E("alloc host fail"); + goto err; + } + + rt_memcpy(&sdio->sdio_des, sdio_des, sizeof(struct stm32_sdio_des)); + + sdio->sdio_des.hw_sdio = (struct stm32_sdio *)SDIO_BASE_ADDRESS; + + rt_event_init(&sdio->event, "sdio", RT_IPC_FLAG_FIFO); + + /* set host default attributes */ + host->ops = &ops; + host->freq_min = 400 * 1000; + host->freq_max = SDIO_MAX_FREQ; + host->valid_ocr = VDD_32_33 | VDD_33_34;/* The voltage range supported is 3.2v-3.4v */ +#ifndef SDIO_USING_1_BIT + host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED; +#else + host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED; +#endif + + host->max_seg_size = SDIO_BUFF_SIZE; + host->max_dma_segs = 1; + host->max_blk_size = 512; + host->max_blk_count = 512; + + /* link up host and sdio */ + sdio->host = host; + host->private_data = sdio; + + /* ready to change */ + mmcsd_change(host); + + return host; + +err: + if (sdio) rt_free(sdio); + + return RT_NULL; +} + +void SDMMC1_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + /* Process All SDIO Interrupt Sources */ + rthw_sdio_irq_process(host); + /* leave interrupt */ + rt_interrupt_leave(); +} + +int rt_hw_sdio_init(void) +{ + struct stm32_sdio_des sdio_des; + SD_HandleTypeDef hsd; + hsd.Instance = SDMMC1; + HAL_SD_MspInit(&hsd); + + host = sdio_host_create(&sdio_des); + if (host == RT_NULL) + { + LOG_E("host create fail"); + return RT_NULL; + } + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_sdio_init); + +int mnt_init(void) +{ + rt_thread_delay(RT_TICK_PER_SECOND); + #ifdef RT_USING_DFS_ROMFS + if (dfs_mount("sd0", "/SD", "elm", 0, 0) == RT_EOK) + #else + if (dfs_mount("sd0", "/", "elm", 0, 0) == RT_EOK) + #endif + { + rt_kprintf("Mount sd card successfully!\n"); + } + else + { + rt_kprintf("Mount sd card fail!\n"); + } + + return 0; +} +INIT_APP_EXPORT(mnt_init); + +#endif /* BSP_USING_SDMMC */ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/drv_sdio.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/drv_sdio.h new file mode 100644 index 000000000..fb4f531e3 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/drv_sdio.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-05-23 liuduanfei first version + */ + +#ifndef __DRV_SDIO_H__ +#define __DRV_SDIO_H__ + +#include +#include "rtdevice.h" +#include +#include +#include +#include +#include + +#define SDIO_BUFF_SIZE 4096 +#define SDIO_ALIGN_LEN 32 + +#ifndef SDIO_BASE_ADDRESS +#define SDIO_BASE_ADDRESS (0x52007000) +#endif + +#ifndef SDIO_CLOCK_FREQ +#define SDIO_CLOCK_FREQ (200U * 1000 * 1000) +#endif + +#ifndef SDIO_BUFF_SIZE +#define SDIO_BUFF_SIZE (4096) +#endif + +#ifndef SDIO_ALIGN_LEN +#define SDIO_ALIGN_LEN (32) +#endif + +#ifndef SDIO_MAX_FREQ +#define SDIO_MAX_FREQ (25 * 1000 * 1000) +#endif + +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) + +#define SDIO_ERRORS \ + (SDMMC_STA_IDMATE | SDMMC_STA_ACKTIMEOUT | \ + SDMMC_STA_RXOVERR | SDMMC_STA_TXUNDERR | \ + SDMMC_STA_DTIMEOUT | SDMMC_STA_CTIMEOUT | \ + SDMMC_STA_DCRCFAIL | SDMMC_STA_CCRCFAIL) + +#define SDIO_MASKR_ALL \ + (SDMMC_MASK_CCRCFAILIE | SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_CTIMEOUTIE | \ + SDMMC_MASK_TXUNDERRIE | SDMMC_MASK_RXOVERRIE | SDMMC_MASK_CMDRENDIE | \ + SDMMC_MASK_CMDSENTIE | SDMMC_MASK_DATAENDIE | SDMMC_MASK_ACKTIMEOUTIE) + +#define HW_SDIO_DATATIMEOUT (0xFFFFFFFFU) + +struct stm32_sdio +{ + volatile rt_uint32_t power; /* offset 0x00 */ + volatile rt_uint32_t clkcr; /* offset 0x04 */ + volatile rt_uint32_t arg; /* offset 0x08 */ + volatile rt_uint32_t cmd; /* offset 0x0C */ + volatile rt_uint32_t respcmd; /* offset 0x10 */ + volatile rt_uint32_t resp1; /* offset 0x14 */ + volatile rt_uint32_t resp2; /* offset 0x18 */ + volatile rt_uint32_t resp3; /* offset 0x1C */ + volatile rt_uint32_t resp4; /* offset 0x20 */ + volatile rt_uint32_t dtimer; /* offset 0x24 */ + volatile rt_uint32_t dlen; /* offset 0x28 */ + volatile rt_uint32_t dctrl; /* offset 0x2C */ + volatile rt_uint32_t dcount; /* offset 0x30 */ + volatile rt_uint32_t sta; /* offset 0x34 */ + volatile rt_uint32_t icr; /* offset 0x38 */ + volatile rt_uint32_t mask; /* offset 0x3C */ + volatile rt_uint32_t acktimer; /* offset 0x40 */ + volatile rt_uint32_t reserved0[3]; /* offset 0x44 ~ 0x4C */ + volatile rt_uint32_t idmatrlr; /* offset 0x50 */ + volatile rt_uint32_t idmabsizer; /* offset 0x54 */ + volatile rt_uint32_t idmabase0r; /* offset 0x58 */ + volatile rt_uint32_t idmabase1r; /* offset 0x5C */ + volatile rt_uint32_t reserved1[8]; /* offset 0x60 ~ 7C */ + volatile rt_uint32_t fifo; /* offset 0x80 */ +}; + +typedef rt_uint32_t (*sdio_clk_get)(struct stm32_sdio *hw_sdio); + +struct stm32_sdio_des +{ + struct stm32_sdio *hw_sdio; + sdio_clk_get clk_get; +}; + +/* stm32 sdio dirver class */ +struct stm32_sdio_class +{ + struct stm32_sdio_des *des; + const struct stm32_sdio_config *cfg; + struct rt_mmcsd_host host; +}; + +extern void stm32_mmcsd_change(void); + +#endif /* __DRV_SDIO_H__ */ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/mnt_ramfs.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/mnt_ramfs.c new file mode 100644 index 000000000..3a0680bf8 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/mnt_ramfs.c @@ -0,0 +1,22 @@ +#include + +#if defined RT_USING_DFS && defined RT_USING_DFS_RAMFS +#include +#include "dfs_ramfs.h" + +int mnt_ramfs_init(void) +{ + if (dfs_mount(RT_NULL, "/", "ram", 0, dfs_ramfs_create(rt_malloc(1024),1024)) == 0) + { + rt_kprintf("RAM file system initializated!\n"); + } + else + { + rt_kprintf("RAM file system initializate failed!\n"); + } + + return 0; +} +INIT_ENV_EXPORT(mnt_ramfs_init); + +#endif \ No newline at end of file diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/mnt_romfs.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/mnt_romfs.c new file mode 100644 index 000000000..b0a4fc1f6 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/mnt_romfs.c @@ -0,0 +1,22 @@ +#include + +#if defined RT_USING_DFS && defined RT_USING_DFS_ROMFS +#include +#include "dfs_romfs.h" + +int mnt_romfs_init(void) +{ + if (dfs_mount(RT_NULL, "/", "rom", 0, &(romfs_root)) == 0) + { + rt_kprintf("ROM file system initializated!\n"); + } + else + { + rt_kprintf("ROM file system initializate failed!\n"); + } + + return 0; +} +INIT_ENV_EXPORT(mnt_romfs_init); + +#endif \ No newline at end of file diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/romfs.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/romfs.c new file mode 100644 index 000000000..892a591b0 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/romfs.c @@ -0,0 +1,23 @@ +/* Generated by mkromfs. Edit with caution. */ +#include +#include + +#ifdef RT_USING_DFS_ROMFS +static const rt_uint8_t _romfs_root_hello_txt[] = { +0x58,0x49,0x55,0x4f,0x53,0x20,0x73,0x74,0x6d,0x33,0x32,0x68,0x37,0x20,0x52,0x6f,0x6d,0x46,0x53,0x20,0x73,0x75,0x63,0x63,0x65,0x73,0x73,0x21 +}; + +static const struct romfs_dirent _romfs_root[] = { + #ifdef BSP_USING_QSPI_FLASH + {ROMFS_DIRENT_DIR, "FLASH", RT_NULL, 0}, + #endif + #ifdef BSP_USING_SDMMC + {ROMFS_DIRENT_DIR, "SD", RT_NULL, 0}, + #endif + {ROMFS_DIRENT_FILE, "hello.txt", (rt_uint8_t *)_romfs_root_hello_txt, sizeof(_romfs_root_hello_txt)/sizeof(_romfs_root_hello_txt[0])} +}; + +const struct romfs_dirent romfs_root = { + ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_romfs_root, sizeof(_romfs_root)/sizeof(_romfs_root[0]) +}; +#endif \ No newline at end of file diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/sdram_port.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/sdram_port.h index ea4afbc2f..80096b3a5 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/sdram_port.h +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/board/ports/sdram_port.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2021, RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/rtconfig.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/rtconfig.h index 532e4ae6a..8ebd6580e 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/rtconfig.h +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/rtconfig.h @@ -18,6 +18,7 @@ #define RT_TICK_PER_SECOND 1000 #define RT_USING_OVERFLOW_CHECK #define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR #define RT_USING_IDLE_HOOK #define RT_IDLE_HOOK_LIST_SIZE 4 #define IDLE_THREAD_STACK_SIZE 256 @@ -39,8 +40,9 @@ #define RT_USING_MEMPOOL #define RT_USING_MEMHEAP -#define RT_USING_MEMHEAP_AUTO_BINDING +#define RT_MEMHEAP_FAST_MODE #define RT_USING_MEMHEAP_AS_HEAP +#define RT_USING_MEMHEAP_AUTO_BINDING #define RT_USING_HEAP /* Kernel Device Object */ @@ -49,7 +51,7 @@ #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 256 #define RT_CONSOLE_DEVICE_NAME "uart1" -#define RT_VER_NUM 0x40004 +#define RT_VER_NUM 0x40100 #define ARCH_ARM #define RT_USING_CPU_FFS #define ARCH_ARM_CORTEX_M @@ -61,15 +63,8 @@ #define RT_USING_USER_MAIN #define RT_MAIN_THREAD_STACK_SIZE 2048 #define RT_MAIN_THREAD_PRIORITY 10 - -/* C++ features */ - -#define RT_USING_CPLUSPLUS - -/* Command shell */ - -#define RT_USING_FINSH #define RT_USING_MSH +#define RT_USING_FINSH #define FINSH_USING_MSH #define FINSH_THREAD_NAME "tshell" #define FINSH_THREAD_PRIORITY 20 @@ -81,10 +76,8 @@ #define MSH_USING_BUILT_IN_COMMANDS #define FINSH_USING_DESCRIPTION #define FINSH_ARG_MAX 10 - -/* Device virtual file system */ - #define RT_USING_DFS +#define DFS_USING_POSIX #define DFS_USING_WORKDIR #define DFS_FILESYSTEMS_MAX 4 #define DFS_FILESYSTEM_TYPES_MAX 4 @@ -105,46 +98,66 @@ #define RT_DFS_ELM_REENTRANT #define RT_DFS_ELM_MUTEX_TIMEOUT 3000 #define RT_USING_DFS_DEVFS -#define RT_USING_DFS_ROMFS +#define RT_USING_DFS_RAMFS /* Device Drivers */ #define RT_USING_DEVICE_IPC -#define RT_PIPE_BUFSZ 512 #define RT_USING_SERIAL #define RT_USING_SERIAL_V1 #define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_PIN +#define RT_USING_RTC +#define RT_USING_SDIO +#define RT_SDIO_STACK_SIZE 512 +#define RT_SDIO_THREAD_PRIORITY 15 +#define RT_MMCSD_STACK_SIZE 1024 +#define RT_MMCSD_THREAD_PREORITY 22 +#define RT_MMCSD_MAX_PARTITION 16 +#define RT_USING_SPI +#define RT_USING_QSPI +#define RT_USING_SFUD +#define RT_SFUD_USING_SFDP +#define RT_SFUD_USING_FLASH_INFO_TABLE +#define RT_SFUD_USING_QSPI +#define RT_SFUD_SPI_MAX_HZ 50000000 /* Using USB */ +#define RT_USING_USB +#define RT_USING_USB_DEVICE +#define RT_USBD_THREAD_STACK_SZ 4096 +#define USB_VENDOR_ID 0x0FFE +#define USB_PRODUCT_ID 0x0001 +#define _RT_USB_DEVICE_CDC +#define RT_USB_DEVICE_CDC +#define RT_VCOM_TASK_STK_SIZE 512 +#define RT_CDC_RX_BUFSIZE 128 +#define RT_VCOM_SERNO "32021919830108" +#define RT_VCOM_SER_LEN 14 +#define RT_VCOM_TX_TIMEOUT 1000 -/* POSIX layer and C standard library */ +/* C/C++ and POSIX layer */ -#define RT_USING_LIBC -#define RT_USING_PTHREADS -#define PTHREAD_NUM_MAX 8 -#define RT_USING_POSIX -#define RT_LIBC_USING_TIME #define RT_LIBC_DEFAULT_TIMEZONE 8 +/* POSIX (Portable Operating System Interface) layer */ + +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_PTHREADS +#define PTHREAD_NUM_MAX 8 + +/* Interprocess Communication (IPC) */ + + +/* Socket is in the 'Network' category */ + +#define RT_USING_CPLUSPLUS + /* Network */ -/* Socket abstraction layer */ - - -/* Network interface device */ - - -/* light weight TCP/IP stack */ - - -/* AT commands */ - - -/* VBUS(Virtual Software BUS) */ - /* Utilities */ @@ -163,7 +176,14 @@ #define BSP_USING_GPIO #define BSP_USING_UART #define BSP_USING_UART1 +#define BSP_USING_QSPI +#define BSP_USING_ONCHIP_RTC + +/* Onboard Peripheral Drivers */ + #define BSP_USING_SDRAM +#define BSP_USING_SDMMC +#define BSP_USING_USBD /* More Drivers */ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/rtconfig.py b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/rtconfig.py index 1e094c54c..f060650ff 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/rtconfig.py +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/stm32h743_openmv_h7plus/rtconfig.py @@ -2,7 +2,7 @@ import os SRC_APP_DIR = '../../../../APP_Framework' # toolchains options ARCH='arm' -CPU='cortex-m4' +CPU='cortex-m7' CROSS_TOOL='gcc' # bsp lib config diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/.config b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/.config index aaa537a37..d47741477 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/.config +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/.config @@ -125,7 +125,29 @@ CONFIG_DFS_FILESYSTEMS_MAX=4 CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 CONFIG_DFS_FD_MAX=16 # CONFIG_RT_USING_DFS_MNTTABLE is not set -# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_ELMFAT=y + +# +# elm-chan's FatFs, Generic FAT Filesystem Module +# +CONFIG_RT_DFS_ELM_CODE_PAGE=437 +CONFIG_RT_DFS_ELM_WORD_ACCESS=y +# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set +# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set +# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set +CONFIG_RT_DFS_ELM_USE_LFN_3=y +CONFIG_RT_DFS_ELM_USE_LFN=3 +CONFIG_RT_DFS_ELM_LFN_UNICODE_0=y +# CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set +# CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set +# CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set +CONFIG_RT_DFS_ELM_LFN_UNICODE=0 +CONFIG_RT_DFS_ELM_MAX_LFN=255 +CONFIG_RT_DFS_ELM_DRIVES=2 +CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512 +# CONFIG_RT_DFS_ELM_USE_ERASE is not set +CONFIG_RT_DFS_ELM_REENTRANT=y +CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000 CONFIG_RT_USING_DFS_DEVFS=y # CONFIG_RT_USING_DFS_ROMFS is not set # CONFIG_RT_USING_DFS_RAMFS is not set @@ -157,7 +179,13 @@ CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_MTD_NAND is not set # CONFIG_RT_USING_PM is not set # CONFIG_RT_USING_RTC is not set -# CONFIG_RT_USING_SDIO is not set +CONFIG_RT_USING_SDIO=y +CONFIG_RT_SDIO_STACK_SIZE=512 +CONFIG_RT_SDIO_THREAD_PRIORITY=15 +CONFIG_RT_MMCSD_STACK_SIZE=1024 +CONFIG_RT_MMCSD_THREAD_PREORITY=22 +CONFIG_RT_MMCSD_MAX_PARTITION=16 +CONFIG_RT_SDIO_DEBUG=y # CONFIG_RT_USING_SPI is not set # CONFIG_RT_USING_WDT is not set # CONFIG_RT_USING_AUDIO is not set @@ -324,11 +352,13 @@ CONFIG_BSP_USING_LPUART1=y # CONFIG_BSP_USING_I2C is not set # CONFIG_BSP_USING_CAN is not set # CONFIG_BSP_USING_RTC is not set +CONFIG_BSP_USING_SDIO=y # # Onboard Peripheral Drivers # CONFIG_BSP_USING_SDRAM=y +CONFIG_BSP_USING_SDCARD=y CONFIG_BSP_USING_ETH=y CONFIG_BSP_USING_PHY=y CONFIG_PHY_DEVICE_ADDRESS=0 diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/Kconfig index ce132f12a..5eee78ea2 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/Kconfig +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/Kconfig @@ -203,6 +203,10 @@ menu "On-chip Peripheral Drivers" bool "Enable RTC" select RT_USING_RTC default n + + config BSP_USING_SDIO + bool "Enable SDIO" + default n endmenu @@ -210,7 +214,14 @@ menu "Onboard Peripheral Drivers" config BSP_USING_SDRAM bool "Enable SDRAM" default n - + config BSP_USING_SDCARD + bool "Using SDCard" + select BSP_USING_SDIO + select RT_USING_SDIO + select RT_USING_DFS + select RT_USING_DFS_ELMFAT + default n + menuconfig BSP_USING_ETH bool "Enable Ethernet" select RT_USING_NETDEV diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/MCUX_Config/pin_mux.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/MCUX_Config/pin_mux.c index 22ec13700..38c3e231b 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/MCUX_Config/pin_mux.c +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/MCUX_Config/pin_mux.c @@ -66,12 +66,7 @@ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ - /*CH438 IO initialize - IOMUXC_SetPinMux( - IOMUXC_GPIO_SD_B1_05_GPIO3_IO05, /* GPIO3_IO05 is configured as CH438_nRD - 0U);*/ - - /* uart 1 2 3 4 8 io initialize */ + /* uart 1 */ 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 */ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/SConscript b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/SConscript index 5e0d423ee..bf9a14de1 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/SConscript +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/SConscript @@ -13,6 +13,8 @@ CPPPATH = [cwd,cwd + '/MCUX_Config',cwd + '/ports'] CPPDEFINES = ['CPU_MIMXRT1052CVL5B', 'SKIP_SYSCLK_INIT', 'EVK_MCIMXRM', 'FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1','XIP_EXTERNAL_FLASH=1'] if GetDepend('BSP_USING_PHY') and GetDepend('PHY_USING_8720A'): src += ['./ports/LAN8720A.c'] +if GetDepend('BSP_USING_SDCARD'): + src += ['./ports/sdcard_port.c'] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES=CPPDEFINES) Return('group') diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/board.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/board.c index cf8ee12c7..93659f924 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/board.c +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/board.c @@ -211,7 +211,7 @@ void imxrt_uart_pins_init(void) #ifdef BSP_USING_SDRAM void imxrt_semc_pins_init(void) { - IOMUXC_SetPinMux( + IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_00_SEMC_DATA00, /* GPIO_EMC_00 is configured as SEMC_DATA00 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( @@ -331,13 +331,35 @@ void imxrt_semc_pins_init(void) IOMUXC_SetPinMux( IOMUXC_GPIO_EMC_39_SEMC_DQS, /* GPIO_EMC_39 is configured as SEMC_DQS */ 1U); /* Software Input On Field: Force input path of pad GPIO_EMC_39 */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_EMC_40_SEMC_RDY, /* GPIO_EMC_40 is configured as SEMC_RDY */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_EMC_41_SEMC_CSX00, /* GPIO_EMC_41 is configured as SEMC_CSX00 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - + /* + the both io has been as mdio for phy driver + */ +// IOMUXC_SetPinMux( +// IOMUXC_GPIO_EMC_40_SEMC_RDY, /* GPIO_EMC_40 is configured as SEMC_RDY */ +// 0U); /* Software Input On Field: Input Path is determined by functionality */ +// IOMUXC_SetPinMux( +// IOMUXC_GPIO_EMC_41_SEMC_CSX00, /* GPIO_EMC_41 is configured as SEMC_CSX00 */ +// 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 */ IOMUXC_SetPinConfig( IOMUXC_GPIO_EMC_00_SEMC_DATA00, /* GPIO_EMC_00 PAD functional properties : */ 0x0110F9u); /* Slew Rate Field: Fast Slew Rate @@ -738,79 +760,74 @@ void imxrt_semc_pins_init(void) Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Enabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_EMC_40_SEMC_RDY, /* GPIO_EMC_40 PAD functional properties : */ - 0x0110F9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/7 - Speed Field: max(200MHz) - 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 Enabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_EMC_41_SEMC_CSX00, /* GPIO_EMC_41 PAD functional properties : */ - 0x0110F9u); /* Slew Rate Field: Fast Slew Rate - Drive Strength Field: R0/7 - Speed Field: max(200MHz) - 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 Enabled */ + + // IOMUXC_SetPinConfig( + // IOMUXC_GPIO_EMC_40_SEMC_RDY, /* GPIO_EMC_40 PAD functional properties : */ + // 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + // Drive Strength Field: R0/7 + // Speed Field: max(200MHz) + // 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 Enabled */ + // IOMUXC_SetPinConfig( + // IOMUXC_GPIO_EMC_41_SEMC_CSX00, /* GPIO_EMC_41 PAD functional properties : */ + // 0x0110F9u); /* Slew Rate Field: Fast Slew Rate + // Drive Strength Field: R0/7 + // Speed Field: max(200MHz) + // 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 Enabled */ } #endif #ifdef BSP_USING_ETH void imxrt_enet_pins_init(void) { - CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */ - - IOMUXC_SetPinMux( + CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */ + 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 */ - IOMUXC_SetPinMux( + + IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, /* GPIO_AD_B0_10 is configured as GPIO1_IO10 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 is configured as ENET_RX_DATA00 */ 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, /* GPIO_AD_B0_09 is configured as GPIO1_IO09 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, /* GPIO_AD_B0_10 is configured as GPIO1_IO10 */ - 0U); - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 is configured as ENET_RX_DATA00 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_05_ENET_RX_DATA01, /* GPIO_B1_05 is configured as ENET_RX_DATA01 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_06_ENET_RX_EN, /* GPIO_B1_06 is configured as ENET_RX_EN */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_07_ENET_TX_DATA00, /* GPIO_B1_07 is configured as ENET_TX_DATA00 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_08_ENET_TX_DATA01, /* GPIO_B1_08 is configured as ENET_TX_DATA01 */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_09_ENET_TX_EN, /* GPIO_B1_09 is configured as ENET_TX_EN */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_10_ENET_REF_CLK, /* GPIO_B1_10 is configured as ENET_REF_CLK */ - 1U); /* Software Input On Field: Force input path of pad GPIO_B1_10 */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_B1_11_ENET_RX_ER, /* GPIO_B1_11 is configured as ENET_RX_ER */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_EMC_40_ENET_MDC, /* GPIO_EMC_40 is configured as ENET_MDC */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinMux( - IOMUXC_GPIO_EMC_41_ENET_MDIO, /* GPIO_EMC_41 is configured as ENET_MDIO */ - 0U); /* Software Input On Field: Input Path is determined by functionality */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, /* GPIO_AD_B0_09 PAD functional properties : */ - 0xB0A9u); /* Slew Rate Field: Fast Slew Rate + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_05_ENET_RX_DATA01, /* GPIO_B1_05 is configured as ENET_RX_DATA01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_06_ENET_RX_EN, /* GPIO_B1_06 is configured as ENET_RX_EN */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_07_ENET_TX_DATA00, /* GPIO_B1_07 is configured as ENET_TX_DATA00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_08_ENET_TX_DATA01, /* GPIO_B1_08 is configured as ENET_TX_DATA01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_09_ENET_TX_EN, /* GPIO_B1_09 is configured as ENET_TX_EN */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_10_ENET_REF_CLK, /* GPIO_B1_10 is configured as ENET_REF_CLK */ + 1U); /* Software Input On Field: Force input path of pad GPIO_B1_10 */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_11_ENET_RX_ER, /* GPIO_B1_11 is configured as ENET_RX_ER */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_40_ENET_MDC, /* GPIO_EMC_40 is configured as ENET_MDC */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_41_ENET_MDIO, /* GPIO_EMC_41 is configured as ENET_MDIO */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B0_03_GPIO1_IO03, /* GPIO_AD_B0_09 PAD functional properties : */ + 0xB0A9u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/5 Speed Field: medium(100MHz) Open Drain Enable Field: Open Drain Disabled @@ -818,9 +835,10 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Pull Pull Up / Down Config. Field: 100K Ohm Pull Up Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, /* GPIO_AD_B0_10 PAD functional properties : */ - 0xB0A9u); /* Slew Rate Field: Fast Slew Rate + + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, /* GPIO_AD_B0_10 PAD functional properties : */ + 0xB0A9u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/5 Speed Field: medium(100MHz) Open Drain Enable Field: Open Drain Disabled @@ -828,9 +846,9 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Pull Pull Up / Down Config. Field: 100K Ohm Pull Up Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/5 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled @@ -838,9 +856,9 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Pull Pull Up / Down Config. Field: 100K Ohm Pull Up Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_05_ENET_RX_DATA01, /* GPIO_B1_05 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_05_ENET_RX_DATA01, /* GPIO_B1_05 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/5 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled @@ -848,9 +866,9 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Pull Pull Up / Down Config. Field: 100K Ohm Pull Up Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_06_ENET_RX_EN, /* GPIO_B1_06 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_06_ENET_RX_EN, /* GPIO_B1_06 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/5 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled @@ -858,9 +876,9 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Pull Pull Up / Down Config. Field: 100K Ohm Pull Up Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_07_ENET_TX_DATA00, /* GPIO_B1_07 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_07_ENET_TX_DATA00, /* GPIO_B1_07 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/5 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled @@ -868,9 +886,9 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Pull Pull Up / Down Config. Field: 100K Ohm Pull Up Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_08_ENET_TX_DATA01, /* GPIO_B1_08 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_08_ENET_TX_DATA01, /* GPIO_B1_08 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/5 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled @@ -878,9 +896,9 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Pull Pull Up / Down Config. Field: 100K Ohm Pull Up Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_09_ENET_TX_EN, /* GPIO_B1_09 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_09_ENET_TX_EN, /* GPIO_B1_09 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/5 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled @@ -888,9 +906,9 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Pull Pull Up / Down Config. Field: 100K Ohm Pull Up Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_10_ENET_REF_CLK, /* GPIO_B1_10 PAD functional properties : */ - 0x31u); /* Slew Rate Field: Fast Slew Rate + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_10_ENET_REF_CLK, /* GPIO_B1_10 PAD functional properties : */ + 0x31u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/6 Speed Field: low(50MHz) Open Drain Enable Field: Open Drain Disabled @@ -898,9 +916,9 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_B1_11_ENET_RX_ER, /* GPIO_B1_11 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_11_ENET_RX_ER, /* GPIO_B1_11 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/5 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled @@ -908,9 +926,9 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Pull Pull Up / Down Config. Field: 100K Ohm Pull Up Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_EMC_40_ENET_MDC, /* GPIO_EMC_40 PAD functional properties : */ - 0xB0E9u); /* Slew Rate Field: Fast Slew Rate + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_40_ENET_MDC, /* GPIO_EMC_40 PAD functional properties : */ + 0xB0E9u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/5 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled @@ -918,9 +936,9 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Pull Pull Up / Down Config. Field: 100K Ohm Pull Up Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinConfig( - IOMUXC_GPIO_EMC_41_ENET_MDIO, /* GPIO_EMC_41 PAD functional properties : */ - 0xB829u); /* Slew Rate Field: Fast Slew Rate + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_41_ENET_MDIO, /* GPIO_EMC_41 PAD functional properties : */ + 0xB829u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/5 Speed Field: low(50MHz) Open Drain Enable Field: Open Drain Enabled @@ -928,8 +946,107 @@ void imxrt_enet_pins_init(void) Pull / Keep Select Field: Pull Pull Up / Down Config. Field: 100K Ohm Pull Up Hyst. Enable Field: Hysteresis Disabled */ + } +#endif + +#ifdef RT_USING_SDIO +void imxrt_sdio_pins_init(void) +{ + IOMUXC_SetPinMux( + IOMUXC_GPIO_B1_14_USDHC1_VSELECT, /* GPIO_B1_14 is configured as USDHC1_VSELECT */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, /* GPIO_SD_B0_00 is configured as USDHC1_CMD */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, /* GPIO_SD_B0_01 is configured as USDHC1_CLK */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, /* GPIO_SD_B0_02 is configured as USDHC1_DATA0 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, /* GPIO_SD_B0_03 is configured as USDHC1_DATA1 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, /* GPIO_SD_B0_04 is configured as USDHC1_DATA2 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, /* GPIO_SD_B0_05 is configured as USDHC1_DATA3 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B1_14_USDHC1_VSELECT, /* GPIO_B1_14 PAD functional properties : */ + 0x0170A1u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0/4 + 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: 47K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, /* GPIO_SD_B0_00 PAD functional properties : */ + 0x017089u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V) + 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: 47K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, /* GPIO_SD_B0_01 PAD functional properties : */ + 0x014089u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V) + Speed Field: medium(100MHz) + Open Drain Enable Field: Open Drain Disabled + Pull / Keep Enable Field: Pull/Keeper Disabled + Pull / Keep Select Field: Keeper + Pull Up / Down Config. Field: 47K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, /* GPIO_SD_B0_02 PAD functional properties : */ + 0x017089u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V) + 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: 47K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, /* GPIO_SD_B0_03 PAD functional properties : */ + 0x017089u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V) + 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: 47K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, /* GPIO_SD_B0_04 PAD functional properties : */ + 0x017089u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V) + 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: 47K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, /* GPIO_SD_B0_05 PAD functional properties : */ + 0x017089u); /* Slew Rate Field: Fast Slew Rate + Drive Strength Field: R0(150 Ohm @ 3.3V, 260 Ohm@1.8V) + 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: 47K Ohm Pull Up + Hyst. Enable Field: Hysteresis Enabled */ + +} #endif void rt_hw_board_init() { @@ -943,18 +1060,22 @@ void rt_hw_board_init() imxrt_uart_pins_init(); #endif -#ifdef BSP_USING_SDRAM - imxrt_semc_pins_init(); -#endif - #ifdef BSP_USING_ETH imxrt_enet_pins_init(); #endif +#ifdef BSP_USING_SDRAM + imxrt_semc_pins_init(); +#endif + #ifdef BSP_USING_DMA imxrt_dma_init(); #endif +#ifdef RT_USING_SDIO + imxrt_sdio_pins_init(); +#endif + #ifdef RT_USING_HEAP rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); #endif diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/ports/LAN8720A.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/ports/LAN8720A.c index f55a920d1..f09a64780 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/ports/LAN8720A.c +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/ports/LAN8720A.c @@ -5,7 +5,7 @@ * * Change Logs: * Date Author Notes - * 2020-10-14 wangqiang the first version + * 2022-4-1 tianchunyu the first version */ #include diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/ports/sdcard_port.c b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/ports/sdcard_port.c new file mode 100644 index 000000000..084394790 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/board/ports/sdcard_port.c @@ -0,0 +1,33 @@ + +#include +#include +#include "drv_gpio.h" +#include +#include +#include +#define DBG_TAG "sdcard" +#define DBG_LVL DBG_INFO +#include +int sd_mount() +{ + rt_uint32_t result; + result = mmcsd_wait_cd_changed(RT_TICK_PER_SECOND); + if (result == MMCSD_HOST_PLUGED) + { + /* mount sd card fat partition 1 as root directory */ + if (dfs_mount("sd0", "/", "elm", 0, 0) == 0) + { + LOG_I("File System initialized!\n"); + return RT_EOK; + } + else + { + LOG_E("File System init failed!\n"); + return -RT_ERROR; + } + + } + LOG_E("msd_init fail !!!"); + return -RT_ERROR; +} +INIT_APP_EXPORT(sd_mount); \ No newline at end of file diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/rtconfig.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/rtconfig.h index 2aede503c..565db313f 100644 --- a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/rtconfig.h +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/rtconfig.h @@ -85,6 +85,21 @@ #define DFS_FILESYSTEMS_MAX 4 #define DFS_FILESYSTEM_TYPES_MAX 4 #define DFS_FD_MAX 16 +#define RT_USING_DFS_ELMFAT + +/* elm-chan's FatFs, Generic FAT Filesystem Module */ + +#define RT_DFS_ELM_CODE_PAGE 437 +#define RT_DFS_ELM_WORD_ACCESS +#define RT_DFS_ELM_USE_LFN_3 +#define RT_DFS_ELM_USE_LFN 3 +#define RT_DFS_ELM_LFN_UNICODE_0 +#define RT_DFS_ELM_LFN_UNICODE 0 +#define RT_DFS_ELM_MAX_LFN 255 +#define RT_DFS_ELM_DRIVES 2 +#define RT_DFS_ELM_MAX_SECTOR_SIZE 512 +#define RT_DFS_ELM_REENTRANT +#define RT_DFS_ELM_MUTEX_TIMEOUT 3000 #define RT_USING_DFS_DEVFS /* Device Drivers */ @@ -101,6 +116,13 @@ #define RT_USING_CPUTIME #define RT_USING_PHY #define RT_USING_PIN +#define RT_USING_SDIO +#define RT_SDIO_STACK_SIZE 512 +#define RT_SDIO_THREAD_PRIORITY 15 +#define RT_MMCSD_STACK_SIZE 1024 +#define RT_MMCSD_THREAD_PREORITY 22 +#define RT_MMCSD_MAX_PARTITION 16 +#define RT_SDIO_DEBUG /* Using USB */ @@ -202,10 +224,12 @@ #define BSP_USING_GPIO #define BSP_USING_LPUART #define BSP_USING_LPUART1 +#define BSP_USING_SDIO /* Onboard Peripheral Drivers */ #define BSP_USING_SDRAM +#define BSP_USING_SDCARD #define BSP_USING_ETH #define BSP_USING_PHY #define PHY_DEVICE_ADDRESS 0 diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/test/iperf_test_base_8720A.png b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/test/iperf_test_base_8720A.png new file mode 100644 index 000000000..b11159d90 Binary files /dev/null and b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong/test/iperf_test_base_8720A.png differ diff --git a/Ubiquitous/XiZi/board/aiit-riscv64-board/board.c b/Ubiquitous/XiZi/board/aiit-riscv64-board/board.c index 18bab5060..6b5837103 100644 --- a/Ubiquitous/XiZi/board/aiit-riscv64-board/board.c +++ b/Ubiquitous/XiZi/board/aiit-riscv64-board/board.c @@ -222,6 +222,9 @@ void InitBoardHardware(void) DmacInit(); #endif + /* initialize memory system */ + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + /* initalize interrupt */ InitHwinterrupt(); #ifdef BSP_USING_UART @@ -239,8 +242,7 @@ void InitBoardHardware(void) #ifdef ARCH_SMP EnableHwclintIpi(); #endif - /* initialize memory system */ - InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + #ifdef KERNEL_COMPONENTS_INIT for(i = 0; _board_init[i].fn != NONE; i++) { diff --git a/Ubiquitous/XiZi/board/cortex-m0-emulator/board.c b/Ubiquitous/XiZi/board/cortex-m0-emulator/board.c index 3d1e5d76b..0c2515688 100644 --- a/Ubiquitous/XiZi/board/cortex-m0-emulator/board.c +++ b/Ubiquitous/XiZi/board/cortex-m0-emulator/board.c @@ -34,6 +34,8 @@ void InitBoardHardware() { extern int InitHwUart(void); InitHwUart(); - InstallConsole(SERIAL_BUS_NAME_1, SERIAL_DRV_NAME_1, SERIAL_DEVICE_NAME_1); + InitBoardMemory((void*)LM3S_SRAM_START, (void*)LM3S_SRAM_END); + + InstallConsole(SERIAL_BUS_NAME_1, SERIAL_DRV_NAME_1, SERIAL_DEVICE_NAME_1); } diff --git a/Ubiquitous/XiZi/board/cortex-m3-emulator/board.c b/Ubiquitous/XiZi/board/cortex-m3-emulator/board.c index 4f99f34de..9ec3d5ec6 100644 --- a/Ubiquitous/XiZi/board/cortex-m3-emulator/board.c +++ b/Ubiquitous/XiZi/board/cortex-m3-emulator/board.c @@ -34,7 +34,7 @@ void InitBoardHardware() { extern int InitHwUart(void); InitHwUart(); - InstallConsole(SERIAL_BUS_NAME_1, SERIAL_DRV_NAME_1, SERIAL_DEVICE_NAME_1); - InitBoardMemory((void*)LM3S_SRAM_START, (void*)LM3S_SRAM_END); + InitBoardMemory((void*)LM3S_SRAM_START, (void*)LM3S_SRAM_END); + InstallConsole(SERIAL_BUS_NAME_1, SERIAL_DRV_NAME_1, SERIAL_DEVICE_NAME_1); } diff --git a/Ubiquitous/XiZi/board/cortex-m4-emulator/board.c b/Ubiquitous/XiZi/board/cortex-m4-emulator/board.c index 5af339730..526638636 100644 --- a/Ubiquitous/XiZi/board/cortex-m4-emulator/board.c +++ b/Ubiquitous/XiZi/board/cortex-m4-emulator/board.c @@ -109,6 +109,9 @@ void InitBoardHardware() #ifdef BSP_USING_UART Stm32HwUsartInit(); #endif + + InitBoardMemory((void*)MEMORY_START_ADDRESS, (void*)MEMORY_END_ADDRESS); + #ifdef KERNEL_CONSOLE InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); @@ -119,7 +122,5 @@ void InitBoardHardware() KPrintf("\nconsole init completed.\n"); KPrintf("board initialization......\n"); #endif - - InitBoardMemory((void*)MEMORY_START_ADDRESS, (void*)MEMORY_END_ADDRESS); } diff --git a/Ubiquitous/XiZi/board/hifive1-emulator/board.c b/Ubiquitous/XiZi/board/hifive1-emulator/board.c index 99fd47f63..174860df2 100644 --- a/Ubiquitous/XiZi/board/hifive1-emulator/board.c +++ b/Ubiquitous/XiZi/board/hifive1-emulator/board.c @@ -54,6 +54,9 @@ void InitBoardHardware(void) CLINT_MTIMECMP_ADDR = CLINT_MTIME_ADDR + TICK; SET_CSR(mie, MIP_MTIP); + /* initialize memory system */ + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + extern int InitHwUart(void); InitHwUart(); InstallConsole(SERIAL_BUS_NAME, SERIAL_DRV_NAME, SERIAL_DEVICE_NAME); @@ -62,8 +65,6 @@ void InitBoardHardware(void) KPrintf("board initialization......\n"); KPrintf("memory address range: [0x%08x - 0x%08x], size: %d\n", (x_ubase) MEMORY_START_ADDRESS, (x_ubase) MEMORY_END_ADDRESS, MEMORY_SIZE); - /* initialize memory system */ - InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); return; } diff --git a/Ubiquitous/XiZi/board/hifive1-rev-B/board.c b/Ubiquitous/XiZi/board/hifive1-rev-B/board.c index 99fd47f63..174860df2 100644 --- a/Ubiquitous/XiZi/board/hifive1-rev-B/board.c +++ b/Ubiquitous/XiZi/board/hifive1-rev-B/board.c @@ -54,6 +54,9 @@ void InitBoardHardware(void) CLINT_MTIMECMP_ADDR = CLINT_MTIME_ADDR + TICK; SET_CSR(mie, MIP_MTIP); + /* initialize memory system */ + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + extern int InitHwUart(void); InitHwUart(); InstallConsole(SERIAL_BUS_NAME, SERIAL_DRV_NAME, SERIAL_DEVICE_NAME); @@ -62,8 +65,6 @@ void InitBoardHardware(void) KPrintf("board initialization......\n"); KPrintf("memory address range: [0x%08x - 0x%08x], size: %d\n", (x_ubase) MEMORY_START_ADDRESS, (x_ubase) MEMORY_END_ADDRESS, MEMORY_SIZE); - /* initialize memory system */ - InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); return; } diff --git a/Ubiquitous/XiZi/board/k210-emulator/board.c b/Ubiquitous/XiZi/board/k210-emulator/board.c index 8a6a9d558..f38e504fe 100644 --- a/Ubiquitous/XiZi/board/k210-emulator/board.c +++ b/Ubiquitous/XiZi/board/k210-emulator/board.c @@ -153,6 +153,10 @@ void InitBoardHardware(void) #ifdef BSP_USING_UART HwUartInit(); #endif + + /* initialize memory system */ + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + #ifdef KERNEL_CONSOLE /* set console device */ InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); @@ -165,8 +169,6 @@ void InitBoardHardware(void) #ifdef ARCH_SMP EnableHwclintIpi(); #endif - /* initialize memory system */ - InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); #ifdef KERNEL_COMPONENTS_INIT for(i = 0; _board_init[i].fn != NONE; i++) { diff --git a/Ubiquitous/XiZi/board/kd233/board.c b/Ubiquitous/XiZi/board/kd233/board.c index 673939c8b..a3d3786f3 100644 --- a/Ubiquitous/XiZi/board/kd233/board.c +++ b/Ubiquitous/XiZi/board/kd233/board.c @@ -202,6 +202,10 @@ void InitBoardHardware(void) #ifdef BSP_USING_UART HwUartInit(); #endif + + /* initialize memory system */ + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + #ifdef KERNEL_CONSOLE /* set console device */ InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); @@ -214,8 +218,6 @@ void InitBoardHardware(void) #ifdef ARCH_SMP EnableHwclintIpi(); #endif - /* initialize memory system */ - InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); #ifdef KERNEL_COMPONENTS_INIT for(i = 0; _board_init[i].fn != NONE; i++) { diff --git a/Ubiquitous/XiZi/board/maix-go/board.c b/Ubiquitous/XiZi/board/maix-go/board.c index 9dcb652e4..efb51204c 100644 --- a/Ubiquitous/XiZi/board/maix-go/board.c +++ b/Ubiquitous/XiZi/board/maix-go/board.c @@ -146,6 +146,10 @@ void InitBoardHardware(void) #ifdef BSP_USING_UART HwUartInit(); #endif + + /* initialize memory system */ + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + #ifdef KERNEL_CONSOLE /* set console device */ InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); @@ -158,9 +162,6 @@ void InitBoardHardware(void) #ifdef ARCH_SMP EnableHwclintIpi(); #endif - /* initialize memory system */ - InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); - KPrintf("board init done.\n"); KPrintf("start kernel...\n"); diff --git a/Ubiquitous/XiZi/board/ok1052-c/Kconfig b/Ubiquitous/XiZi/board/ok1052-c/Kconfig index 5f685a174..62afaf430 100644 --- a/Ubiquitous/XiZi/board/ok1052-c/Kconfig +++ b/Ubiquitous/XiZi/board/ok1052-c/Kconfig @@ -44,7 +44,6 @@ menu "ok1052-c feature" config MOUNT_SDCARD bool "mount cd card" default n - select BSP_USING_SDIO endmenu endmenu diff --git a/Ubiquitous/XiZi/board/ok1052-c/board.c b/Ubiquitous/XiZi/board/ok1052-c/board.c index 363c8424c..5b1174a39 100644 --- a/Ubiquitous/XiZi/board/ok1052-c/board.c +++ b/Ubiquitous/XiZi/board/ok1052-c/board.c @@ -41,30 +41,6 @@ extern int ExtSramInit(void); #endif #endif -#if defined(FS_VFS) && defined(MOUNT_SDCARD) -#include - -// SD card mount flag 1: OK -int sd_mount_flag = 0; - -/** - * @description: Mount SD card - * @return 0 - */ -int MountSDCard(void) -{ - if (MountFilesystem(SDIO_BUS_NAME, SDIO_DEVICE_NAME, SDIO_DRIVER_NAME, FSTYPE_FATFS, "/") == 0) - { - sd_mount_flag = 1; - KPrintf("sd card mount to '/'"); - } - else - KPrintf("sd card mount to '/' failed!"); - - return 0; -} -#endif - #if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED #include "fsl_lpi2c.h" #endif /* SDK_I2C_BASED_COMPONENT_USED */ diff --git a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c index d04c8adb3..870ed17f3 100755 --- a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c +++ b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c @@ -99,7 +99,7 @@ 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))); + SysTick_Config(SystemCoreClock / TICK_PER_SECOND); } void ethernetif_gpio_init(void) @@ -109,9 +109,7 @@ void ethernetif_gpio_init(void) IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true); GPIO_PinInit(GPIO1, 3, &gpio_config); - GPIO_PinInit(GPIO1, 10, &gpio_config); /* pull up the ENET_INT before RESET. */ - GPIO_WritePinOutput(GPIO1, 10, 1); GPIO_WritePinOutput(GPIO1, 3, 0); enet_delay(); GPIO_WritePinOutput(GPIO1, 3, 1); diff --git a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/include/connect_sdio.h b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/include/connect_sdio.h index 768e0ac3a..501c14422 100644 --- a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/include/connect_sdio.h +++ b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/include/connect_sdio.h @@ -27,11 +27,14 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { #endif +#define SD_CARD_STACK_SIZE 2048 + int Imxrt1052HwSdioInit(void); #ifdef __cplusplus diff --git a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/sdio/Kconfig b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/sdio/Kconfig index 56ebba209..c2ceb303d 100644 --- a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/sdio/Kconfig +++ b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/sdio/Kconfig @@ -10,4 +10,15 @@ if BSP_USING_SDIO config SDIO_DEVICE_NAME string "sdio device name" default "sdio_dev" + + config MOUNT_SDCARD_FS + bool "mount cd card file system" + default n + select MOUNT_SDCARD + + if MOUNT_SDCARD_FS + config MOUNT_SDCARD_FS_TYPE + int "choose file system type : FATFS(0) LWEXT4(3)" + default 0 + endif endif diff --git a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/sdio/connect_sdio.c b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/sdio/connect_sdio.c index b29bc4fe6..bebbce78a 100644 --- a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/sdio/connect_sdio.c +++ b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/sdio/connect_sdio.c @@ -104,9 +104,6 @@ static const sdmmchost_card_switch_voltage_func_t s_sdcard_voltage_switch = { }; #endif -/*! @brief SD card detect flag */ -static volatile bool s_card_inserted = false; - /*! @brief Card descriptor. */ static sd_card_t g_sd; static int sd_lock = -1; @@ -142,11 +139,6 @@ static void BoardPowerOnSdCard(void) BOARD_USDHC_SDCARD_POWER_CONTROL(1); } -static void SdcardDetectCallBack(bool is_inserted, void *user_data) -{ - s_card_inserted = is_inserted; -} - static void CardInformationLog(sd_card_t *card) { NULL_PARAM_CHECK(card); @@ -261,6 +253,19 @@ static uint32 SdioWrite(void *dev, struct BusBlockWriteParam *write_param) return write_param->size; } +static int SdioControl(struct HardwareDev *dev, struct HalDevBlockParam *block_param) +{ + NULL_PARAM_CHECK(dev); + + if (OPER_BLK_GETGEOME == block_param->cmd) { + block_param->dev_block.size_perbank = g_sd.blockSize; + block_param->dev_block.block_size = g_sd.blockSize; + block_param->dev_block.bank_num = g_sd.blockCount; + } + + return EOK; +} + static struct SdioDevDone dev_done = { SdioOpen, @@ -269,10 +274,126 @@ static struct SdioDevDone dev_done = SdioRead, }; +#if defined(FS_VFS) && defined(MOUNT_SDCARD_FS) +#include + +int sd_mount_flag = 0; + +/** + * @description: Mount SD card + * @return 0 + */ +static int MountSDCardFs(enum FilesystemType fs_type) +{ + if (MountFilesystem(SDIO_BUS_NAME, SDIO_DEVICE_NAME, SDIO_DRIVER_NAME, fs_type, "/") == 0) { + sd_mount_flag = 1; + KPrintf("Sd card mount to '/'"); + } else { + KPrintf("Sd card mount to '/' failed!"); + } + + return 0; +} +#endif + +static void SdCardAttach(void) +{ + bool is_read_only; + static sd_card_t *card = &g_sd; + + KPrintf("\r\nCard inserted.\r\n"); + /* reset host once card re-plug in */ + SD_HostReset(&(card->host)); + /* power on the card */ + SD_PowerOnCard(card->host.base, card->usrParam.pwr); + KPrintf("Power on done\n"); + + /* Init card. */ + if (SD_CardInit(card)) { + KPrintf("\r\nSD card init failed.\r\n"); + return; + } + + /* card information log */ + CardInformationLog(card); + + /* Check if card is readonly. */ + is_read_only = SD_CheckReadOnly(card); + +#ifdef MOUNT_SDCARD_FS + /*mount file system*/ + MountSDCardFs(MOUNT_SDCARD_FS_TYPE); +#endif +} + +static void SdCardDetach(void) +{ + /*unmount file system*/ + KPrintf("\r\nCard detect extracted.\r\n"); + +#ifdef MOUNT_SDCARD_FS + UnmountFileSystem("/"); +#endif +} + +static uint8 SdCardReadCd(void) +{ + BusType pin; + + pin = BusFind(PIN_BUS_NAME); + + pin->owner_haldev = BusFindDevice(pin, PIN_DEVICE_NAME); + + struct PinStat PinStat; + + struct BusBlockReadParam read_param; + read_param.buffer = (void *)&PinStat; + + PinStat.pin = IMXRT_GET_PIN(2, 28); + + return BusDevReadData(pin->owner_haldev, &read_param); +} + +static void SdCardTask(void* parameter) +{ + static int sd_card_status = 0; + + while (1) { + if (!SdCardReadCd()) { + if (!sd_card_status) { + SdCardAttach(); + sd_card_status = 1; + } + } else { + if (sd_card_status) { + SdCardDetach(); + sd_card_status = 0; + } + } + } +} + +#ifdef MOUNT_SDCARD +int MountSDCard() +{ + int sd_card_task = 0; + sd_card_task = KTaskCreate("sd_card", SdCardTask, NONE, + SD_CARD_STACK_SIZE, 8); + if(sd_card_task < 0) { + KPrintf("sd_card_task create failed ...%s %d.\n", __FUNCTION__,__LINE__); + return ERROR; + } + + StartupKTask(sd_card_task); + + return EOK; +} +#endif + + int Imxrt1052HwSdioInit(void) { x_err_t ret = EOK; - bool is_read_only; static struct SdioBus sdio_bus; static struct SdioDriver sdio_drv; @@ -305,35 +426,6 @@ int Imxrt1052HwSdioInit(void) return ERROR; } - KPrintf("\r\nPlease insert a card into board.\r\n"); - - /* power off card */ - SD_PowerOffCard(card->host.base, card->usrParam.pwr); - - if (SD_WaitCardDetectStatus(SD_HOST_BASEADDR, &s_sdcard_detect, true) == kStatus_Success) { - KPrintf("\r\nCard inserted.\r\n"); - /* reset host once card re-plug in */ - SD_HostReset(&(card->host)); - /* power on the card */ - SD_PowerOnCard(card->host.base, card->usrParam.pwr); - KPrintf("power on done\n"); - } else { - KPrintf("\r\nCard detect fail.\r\n"); - return ERROR; - } - - /* Init card. */ - if (SD_CardInit(card)) { - KPrintf("\r\nSD card init failed.\r\n"); - return ERROR; - } - - /* card information log */ - CardInformationLog(card); - - /* Check if card is readonly. */ - is_read_only = SD_CheckReadOnly(card); - ret = SdioBusInit(&sdio_bus, SDIO_BUS_NAME); if (ret != EOK) { KPrintf("Sdio bus init error %d\n", ret); @@ -352,6 +444,7 @@ int Imxrt1052HwSdioInit(void) } sdio_dev.dev_done = &dev_done; + sdio_dev.haldev.dev_block_control = SdioControl; ret = SdioDeviceRegister(&sdio_dev, SDIO_DEVICE_NAME); if (ret != EOK) { KPrintf("Sdio device register error %d\n", ret); diff --git a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/uart/connect_uart.c b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/uart/connect_uart.c index 5a6040af7..a6ad397f8 100644 --- a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/uart/connect_uart.c +++ b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/uart/connect_uart.c @@ -41,11 +41,9 @@ void LPUART1_IRQHandler(int irqn, void *arg) { x_base lock = 0; // KPrintf("LPUART1_IRQHandler \n"); - lock = DISABLE_INTERRUPT(); - + lock = DisableIRQ(UART1_IRQn); UartIsr(&serial_bus_1, &serial_driver_1, &serial_device_1); - - ENABLE_INTERRUPT(lock); + EnableIRQ(UART1_IRQn); } DECLARE_HW_IRQ(UART1_IRQn, LPUART1_IRQHandler, NONE); #endif diff --git a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/usb/nxp_usb_driver/host_msd_command.c b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/usb/nxp_usb_driver/host_msd_command.c index 78cb4af70..7bab0d1bc 100644 --- a/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/usb/nxp_usb_driver/host_msd_command.c +++ b/Ubiquitous/XiZi/board/ok1052-c/third_party_driver/usb/nxp_usb_driver/host_msd_command.c @@ -15,8 +15,8 @@ */ /************************************************* -File name: usb_misc.h -Description: modify usb_echo to KPrintf +File name: host_msd_command.c +Description: modify usb msd command test function Others: take SDK_2.6.1_MIMXRT1052xxxxB/boards/evkbimxrt1050/usb_examples/usb_host_msd_command for references History: 1. Date: 2022-02-10 diff --git a/Ubiquitous/XiZi/board/rv32m1_vega/board.c b/Ubiquitous/XiZi/board/rv32m1_vega/board.c index ab7e9d662..02a596ca2 100644 --- a/Ubiquitous/XiZi/board/rv32m1_vega/board.c +++ b/Ubiquitous/XiZi/board/rv32m1_vega/board.c @@ -63,10 +63,12 @@ void InitBoardHardware(void) InitHwUart(); InitHwTick(); + + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + InstallConsole("uart0", "uart0_drv", "uart0_dev0"); KPrintf("console init completed.\n"); - InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); KPrintf("memory address range: [0x%08x - 0x%08x], size: %d\n", (x_ubase) MEMORY_START_ADDRESS, (x_ubase) MEMORY_END_ADDRESS, RV32M1VEGA_SRAM_SIZE); KPrintf("board init done.\n"); KPrintf("start kernel...\n"); diff --git a/Ubiquitous/XiZi/board/stm32f103-nano/board.c b/Ubiquitous/XiZi/board/stm32f103-nano/board.c index c624668ae..8949def96 100644 --- a/Ubiquitous/XiZi/board/stm32f103-nano/board.c +++ b/Ubiquitous/XiZi/board/stm32f103-nano/board.c @@ -89,6 +89,8 @@ void InitBoardHardware() __set_PRIMASK(1); InitHwUart(); - InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); + InitBoardMemory((void*)HEAP_START, (void*)HEAP_END); + InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); + } diff --git a/Ubiquitous/XiZi/board/stm32f407-st-discovery/board.c b/Ubiquitous/XiZi/board/stm32f407-st-discovery/board.c index 78ceee6ce..491e61240 100644 --- a/Ubiquitous/XiZi/board/stm32f407-st-discovery/board.c +++ b/Ubiquitous/XiZi/board/stm32f407-st-discovery/board.c @@ -156,6 +156,9 @@ void InitBoardHardware() #ifdef BSP_USING_UART Stm32HwUsartInit(); #endif + + InitBoardMemory((void*)MEMORY_START_ADDRESS, (void*)MEMORY_END_ADDRESS); + #ifdef KERNEL_CONSOLE InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); @@ -166,8 +169,6 @@ void InitBoardHardware() KPrintf("\nconsole init completed.\n"); KPrintf("board initialization......\n"); #endif - - InitBoardMemory((void*)MEMORY_START_ADDRESS, (void*)MEMORY_END_ADDRESS); for(i = 0; _board_init[i].fn != NONE; i++) { ret = _board_init[i].fn(); diff --git a/Ubiquitous/XiZi/board/xidatong/Kconfig b/Ubiquitous/XiZi/board/xidatong/Kconfig index fedc84638..9653b4851 100644 --- a/Ubiquitous/XiZi/board/xidatong/Kconfig +++ b/Ubiquitous/XiZi/board/xidatong/Kconfig @@ -42,9 +42,8 @@ menu "xidatong feature" menu "config board peripheral" config MOUNT_SDCARD - bool "mount cd card" + bool "mount sd card" default n - select BSP_USING_SDIO endmenu endmenu diff --git a/Ubiquitous/XiZi/board/xidatong/board.c b/Ubiquitous/XiZi/board/xidatong/board.c index 54a2f1966..add8b5c4c 100644 --- a/Ubiquitous/XiZi/board/xidatong/board.c +++ b/Ubiquitous/XiZi/board/xidatong/board.c @@ -29,24 +29,6 @@ Modification: #include "board.h" #include "pin_mux.h" -#if defined(FS_VFS) && defined(MOUNT_SDCARD) -#include - -/** - * @description: Mount SD card - * @return 0 - */ -int MountSDCard(void) -{ - if (MountFilesystem(SDIO_BUS_NAME, SDIO_DEVICE_NAME, SDIO_DRIVER_NAME, FSTYPE_FATFS, "/") == 0) - KPrintf("sd card mount to '/'"); - else - KPrintf("sd card mount to '/' failed!"); - - return 0; -} -#endif - #if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED #include "fsl_lpi2c.h" #endif /* SDK_I2C_BASED_COMPONENT_USED */ diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_sdio.h b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_sdio.h index 6adf230c8..f76b1a46f 100644 --- a/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_sdio.h +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/include/connect_sdio.h @@ -27,11 +27,14 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { #endif +#define SD_CARD_STACK_SIZE 2048 + int Imxrt1052HwSdioInit(void); #ifdef __cplusplus diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/sdio/Kconfig b/Ubiquitous/XiZi/board/xidatong/third_party_driver/sdio/Kconfig index 56ebba209..c2ceb303d 100644 --- a/Ubiquitous/XiZi/board/xidatong/third_party_driver/sdio/Kconfig +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/sdio/Kconfig @@ -10,4 +10,15 @@ if BSP_USING_SDIO config SDIO_DEVICE_NAME string "sdio device name" default "sdio_dev" + + config MOUNT_SDCARD_FS + bool "mount cd card file system" + default n + select MOUNT_SDCARD + + if MOUNT_SDCARD_FS + config MOUNT_SDCARD_FS_TYPE + int "choose file system type : FATFS(0) LWEXT4(3)" + default 0 + endif endif diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/sdio/connect_sdio.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/sdio/connect_sdio.c index 431e3fc98..841ed2fc2 100644 --- a/Ubiquitous/XiZi/board/xidatong/third_party_driver/sdio/connect_sdio.c +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/sdio/connect_sdio.c @@ -104,9 +104,6 @@ static const sdmmchost_card_switch_voltage_func_t s_sdcard_voltage_switch = { }; #endif -/*! @brief SD card detect flag */ -static volatile bool s_card_inserted = false; - /*! @brief Card descriptor. */ static sd_card_t g_sd; static int sd_lock = -1; @@ -142,11 +139,6 @@ static void BoardPowerOnSdCard(void) BOARD_USDHC_SDCARD_POWER_CONTROL(1); } -static void SdcardDetectCallBack(bool is_inserted, void *user_data) -{ - s_card_inserted = is_inserted; -} - static void CardInformationLog(sd_card_t *card) { NULL_PARAM_CHECK(card); @@ -261,6 +253,19 @@ static uint32 SdioWrite(void *dev, struct BusBlockWriteParam *write_param) return write_param->size; } +static int SdioControl(struct HardwareDev *dev, struct HalDevBlockParam *block_param) +{ + NULL_PARAM_CHECK(dev); + + if (OPER_BLK_GETGEOME == block_param->cmd) { + block_param->dev_block.size_perbank = g_sd.blockSize; + block_param->dev_block.block_size = g_sd.blockSize; + block_param->dev_block.bank_num = g_sd.blockCount; + } + + return EOK; +} + static struct SdioDevDone dev_done = { SdioOpen, @@ -269,10 +274,121 @@ static struct SdioDevDone dev_done = SdioRead, }; +#if defined(FS_VFS) && defined(MOUNT_SDCARD_FS) +#include + +/** + * @description: Mount SD card + * @return 0 + */ +static int MountSDCardFs(enum FilesystemType fs_type) +{ + if (MountFilesystem(SDIO_BUS_NAME, SDIO_DEVICE_NAME, SDIO_DRIVER_NAME, fs_type, "/") == 0) + KPrintf("Sd card mount to '/'"); + else + KPrintf("Sd card mount to '/' failed!"); + + return 0; +} +#endif + +static void SdCardAttach(void) +{ + bool is_read_only; + static sd_card_t *card = &g_sd; + + KPrintf("\r\nCard inserted.\r\n"); + /* reset host once card re-plug in */ + SD_HostReset(&(card->host)); + /* power on the card */ + SD_PowerOnCard(card->host.base, card->usrParam.pwr); + KPrintf("Power on done\n"); + + /* Init card. */ + if (SD_CardInit(card)) { + KPrintf("\r\nSD card init failed.\r\n"); + return; + } + + /* card information log */ + CardInformationLog(card); + + /* Check if card is readonly. */ + is_read_only = SD_CheckReadOnly(card); + +#ifdef MOUNT_SDCARD_FS + /*mount file system*/ + MountSDCardFs(MOUNT_SDCARD_FS_TYPE); +#endif +} + +static void SdCardDetach(void) +{ + /*unmount file system*/ + KPrintf("\r\nCard detect extracted.\r\n"); + +#ifdef MOUNT_SDCARD_FS + UnmountFileSystem("/"); +#endif +} + +static uint8 SdCardReadCd(void) +{ + BusType pin; + + pin = BusFind(PIN_BUS_NAME); + + pin->owner_haldev = BusFindDevice(pin, PIN_DEVICE_NAME); + + struct PinStat PinStat; + + struct BusBlockReadParam read_param; + read_param.buffer = (void *)&PinStat; + + PinStat.pin = IMXRT_GET_PIN(2, 28); + + return BusDevReadData(pin->owner_haldev, &read_param); +} + +static void SdCardTask(void* parameter) +{ + static int sd_card_status = 0; + + while (1) { + if (!SdCardReadCd()) { + if (!sd_card_status) { + SdCardAttach(); + sd_card_status = 1; + } + } else { + if (sd_card_status) { + SdCardDetach(); + sd_card_status = 0; + } + } + } +} + +#ifdef MOUNT_SDCARD +int MountSDCard() +{ + int sd_card_task = 0; + sd_card_task = KTaskCreate("sd_card", SdCardTask, NONE, + SD_CARD_STACK_SIZE, 8); + if(sd_card_task < 0) { + KPrintf("sd_card_task create failed ...%s %d.\n", __FUNCTION__,__LINE__); + return ERROR; + } + + StartupKTask(sd_card_task); + + return EOK; +} +#endif + int Imxrt1052HwSdioInit(void) { x_err_t ret = EOK; - bool is_read_only; static struct SdioBus sdio_bus; static struct SdioDriver sdio_drv; @@ -304,35 +420,6 @@ int Imxrt1052HwSdioInit(void) KPrintf("\r\nSD host init fail\r\n"); return ERROR; } - - KPrintf("\r\nPlease insert a card into board.\r\n"); - - /* power off card */ - SD_PowerOffCard(card->host.base, card->usrParam.pwr); - - if (SD_WaitCardDetectStatus(SD_HOST_BASEADDR, &s_sdcard_detect, true) == kStatus_Success) { - KPrintf("\r\nCard inserted.\r\n"); - /* reset host once card re-plug in */ - SD_HostReset(&(card->host)); - /* power on the card */ - SD_PowerOnCard(card->host.base, card->usrParam.pwr); - KPrintf("power on done\n"); - } else { - KPrintf("\r\nCard detect fail.\r\n"); - return ERROR; - } - - /* Init card. */ - if (SD_CardInit(card)) { - KPrintf("\r\nSD card init failed.\r\n"); - return ERROR; - } - - /* card information log */ - CardInformationLog(card); - - /* Check if card is readonly. */ - is_read_only = SD_CheckReadOnly(card); ret = SdioBusInit(&sdio_bus, SDIO_BUS_NAME); if (ret != EOK) { @@ -352,6 +439,7 @@ int Imxrt1052HwSdioInit(void) } sdio_dev.dev_done = &dev_done; + sdio_dev.haldev.dev_block_control = SdioControl; ret = SdioDeviceRegister(&sdio_dev, SDIO_DEVICE_NAME); if (ret != EOK) { KPrintf("Sdio device register error %d\n", ret); diff --git a/Ubiquitous/XiZi/board/xidatong/third_party_driver/usb/nxp_usb_driver/host_msd_command.c b/Ubiquitous/XiZi/board/xidatong/third_party_driver/usb/nxp_usb_driver/host_msd_command.c index 78cb4af70..7bab0d1bc 100644 --- a/Ubiquitous/XiZi/board/xidatong/third_party_driver/usb/nxp_usb_driver/host_msd_command.c +++ b/Ubiquitous/XiZi/board/xidatong/third_party_driver/usb/nxp_usb_driver/host_msd_command.c @@ -15,8 +15,8 @@ */ /************************************************* -File name: usb_misc.h -Description: modify usb_echo to KPrintf +File name: host_msd_command.c +Description: modify usb msd command test function Others: take SDK_2.6.1_MIMXRT1052xxxxB/boards/evkbimxrt1050/usb_examples/usb_host_msd_command for references History: 1. Date: 2022-02-10 diff --git a/Ubiquitous/XiZi/fs/lwext4/Kconfig b/Ubiquitous/XiZi/fs/lwext4/Kconfig index e69de29bb..afa4938f1 100644 --- a/Ubiquitous/XiZi/fs/lwext4/Kconfig +++ b/Ubiquitous/XiZi/fs/lwext4/Kconfig @@ -0,0 +1,7 @@ +config CONFIG_USE_DEFAULT_CFG + int + default 1 + +config CONFIG_HAVE_OWN_OFLAGS + int + default 0 diff --git a/Ubiquitous/XiZi/fs/lwext4/Makefile b/Ubiquitous/XiZi/fs/lwext4/Makefile index 15357b7bc..6c25f1470 100644 --- a/Ubiquitous/XiZi/fs/lwext4/Makefile +++ b/Ubiquitous/XiZi/fs/lwext4/Makefile @@ -1,4 +1,3 @@ +SRC_DIR := lwext4_submodule - - -include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi/fs/lwext4/lwext4_submodule b/Ubiquitous/XiZi/fs/lwext4/lwext4_submodule new file mode 160000 index 000000000..1eba3cfed --- /dev/null +++ b/Ubiquitous/XiZi/fs/lwext4/lwext4_submodule @@ -0,0 +1 @@ +Subproject commit 1eba3cfeda305e5c735827805e90f5f1c8043394 diff --git a/Ubiquitous/XiZi/fs/shared/include/iot-vfs.h b/Ubiquitous/XiZi/fs/shared/include/iot-vfs.h index bc61255da..d1531e5c2 100644 --- a/Ubiquitous/XiZi/fs/shared/include/iot-vfs.h +++ b/Ubiquitous/XiZi/fs/shared/include/iot-vfs.h @@ -24,6 +24,9 @@ enum FilesystemType FSTYPE_FATFS = 0, FSTYPE_IOTDEVICEFILE, FSTYPE_CH376, +#ifdef FS_LWEXT4 + FSTYPE_LWEXT4, +#endif FSTYPE_END, }; diff --git a/Ubiquitous/XiZi/kernel/include/xs_init.h b/Ubiquitous/XiZi/kernel/include/xs_init.h index 745377e91..09e813178 100644 --- a/Ubiquitous/XiZi/kernel/include/xs_init.h +++ b/Ubiquitous/XiZi/kernel/include/xs_init.h @@ -40,6 +40,7 @@ extern int FlashW25qxxSpiDeviceInit(void); extern int LoraSx12xxSpiDeviceInit(void); extern int FatfsInit(void); extern int Ch376fsInit(void); +extern int Lwext4Init(void); extern int LibcSystemInit(void); extern int RtcNtpSyncInit(void); extern int MountSDCard(void); diff --git a/Ubiquitous/XiZi/kernel/thread/init.c b/Ubiquitous/XiZi/kernel/thread/init.c index 4813111cd..00e255d26 100644 --- a/Ubiquitous/XiZi/kernel/thread/init.c +++ b/Ubiquitous/XiZi/kernel/thread/init.c @@ -95,6 +95,9 @@ struct InitSequenceDesc components_init[] = #endif #ifdef FS_CH376 { "ch376", Ch376fsInit }, +#endif +#ifdef FS_LWEXT4 + { "lwext4", Lwext4Init }, #endif { "libc_system", LibcSystemInit }, #ifdef RTC_SYNC_USING_NTP diff --git a/Ubiquitous/XiZi/path_kernel.mk b/Ubiquitous/XiZi/path_kernel.mk index 3b6f53047..91a7f3e45 100755 --- a/Ubiquitous/XiZi/path_kernel.mk +++ b/Ubiquitous/XiZi/path_kernel.mk @@ -305,7 +305,7 @@ KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/connection/zigbee endif ifeq ($(CONFIG_ADAPTER_HFA21_ETHERCAT), y) -KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/connection/ethercat # +KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/connection/industrial_ethernet/ethercat # endif ifeq ($(CONFIG_SUPPORT_KNOWING_FRAMEWORK), y) @@ -354,6 +354,12 @@ ifeq ($(CONFIG_LIB_NEWLIB),y) KERNELPATHS += -I$(KERNEL_ROOT)/lib/newlib/include # endif +ifeq ($(CONFIG_FS_LWEXT4),y) +KERNELPATHS += -I$(KERNEL_ROOT)/fs/lwext4/lwext4_submodule/blockdev/xiuos # +KERNELPATHS += -I$(KERNEL_ROOT)/fs/lwext4/lwext4_submodule/include # +KERNELPATHS += -I$(KERNEL_ROOT)/fs/lwext4/lwext4_submodule/include/misc +endif + ifeq ($(ARCH), risc-v) KERNELPATHS +=-I$(KERNEL_ROOT)/arch/risc-v/shared diff --git a/Ubiquitous/XiZi/resources/ethernet/LwIP/arch/sys_arch.c b/Ubiquitous/XiZi/resources/ethernet/LwIP/arch/sys_arch.c index 5088c7f37..aed1bda45 100644 --- a/Ubiquitous/XiZi/resources/ethernet/LwIP/arch/sys_arch.c +++ b/Ubiquitous/XiZi/resources/ethernet/LwIP/arch/sys_arch.c @@ -184,7 +184,7 @@ sys_sem_free(sys_sem_t *sem) int sys_sem_valid(sys_sem_t *sem) { - return (*sem >= SYS_SEM_NULL); + return (*sem > SYS_SEM_NULL); } void @@ -212,7 +212,7 @@ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) if(KSemaphoreObtain(*sem, wait_time) == EOK) - return ((CurrentTicksGain()-start_tick)*MS_PER_SYSTICK_F407); + return ((CurrentTicksGain()-start_tick)*MS_PER_SYSTICK); else return SYS_ARCH_TIMEOUT; } @@ -226,7 +226,7 @@ void sys_sem_signal(sys_sem_t *sem) err_t sys_mutex_new(sys_mutex_t *mutex) { *mutex = KMutexCreate(); - if(*mutex >= 0) + if(*mutex > SYS_MRTEX_NULL) return ERR_OK; else { @@ -344,7 +344,7 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout) wait_time = timeout; if(KMsgQueueRecv(*q, &(*msg), sizeof(void *), wait_time) == EOK) - return ((CurrentTicksGain()-start_tick)*MS_PER_SYSTICK_F407); + return ((CurrentTicksGain()-start_tick)*MS_PER_SYSTICK); else{ *msg = NULL; return SYS_ARCH_TIMEOUT; diff --git a/Ubiquitous/XiZi/resources/ethernet/LwIP/arch/sys_arch.h b/Ubiquitous/XiZi/resources/ethernet/LwIP/arch/sys_arch.h index 64ae8e826..bea4e6943 100644 --- a/Ubiquitous/XiZi/resources/ethernet/LwIP/arch/sys_arch.h +++ b/Ubiquitous/XiZi/resources/ethernet/LwIP/arch/sys_arch.h @@ -62,7 +62,7 @@ /* USER CODE END 0 */ #define SYS_MBOX_NULL -1 -#define SYS_SEM_NULL 0 +#define SYS_SEM_NULL -1 #define SYS_MRTEX_NULL SYS_SEM_NULL typedef int32 sys_sem_t; @@ -71,7 +71,7 @@ typedef int32 sys_mbox_t; typedef int32 sys_thread_t; typedef x_base sys_prot_t; -#define MS_PER_SYSTICK_F407 (1000 / TICK_PER_SECOND) +#define MS_PER_SYSTICK (1000 / TICK_PER_SECOND) //debug rtos with IRQ //#define FSL_RTOS_XIUOS diff --git a/Ubiquitous/XiZi/tool/shell/letter-shell/shell.c b/Ubiquitous/XiZi/tool/shell/letter-shell/shell.c index 7cab44a65..6a923ece8 100644 --- a/Ubiquitous/XiZi/tool/shell/letter-shell/shell.c +++ b/Ubiquitous/XiZi/tool/shell/letter-shell/shell.c @@ -1652,7 +1652,6 @@ void shellTask(void *param) shellHandler(shell, data[i]); } } - KPrintf(""); } }