diff --git a/APP_Framework/Applications/Make.defs b/APP_Framework/Applications/Make.defs index 03adcc80f..581c8c124 100644 --- a/APP_Framework/Applications/Make.defs +++ b/APP_Framework/Applications/Make.defs @@ -2,7 +2,6 @@ # APP_Framework/Applications/Make.defs ############################################################################ CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Applications -CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Applications/app_test CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Applications/general_functions/list include $(wildcard $(APPDIR)/../../../APP_Framework/Applications/*/Make.defs) diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index bffda4b64..e1e9b084e 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -26,6 +26,131 @@ menu "test app" endif endif + menuconfig USER_TEST_FS + bool "Config test fs with sd or usb" + default n + if USER_TEST_FS + if ADD_XIZI_FETURES + config FPATH + string "Set test file path" + default "/test_file" + endif + endif + + + menuconfig USER_TEST_GPIO + select BSP_USING_GPIO + select RESOURCES_PIN + select BSP_USING_LED + select BSP_USING_KEY + bool "Config test gpio with led and key" + default n + if USER_TEST_GPIO + if ADD_XIZI_FETURES + config GPIO_DEV_DRIVER + string "Set gpio dev path" + default "/dev/pin_dev" + endif + endif + + menuconfig USER_TEST_LORA + select BSP_USING_UART + select BSP_USING_GPIO + select RESOURCES_PIN + select BSP_USING_UART2 + select BSP_USING_LORA + bool "Config test uart(loraE220)" + default n + if USER_TEST_LORA + if ADD_XIZI_FETURES + config LORA_UART_DEV_DRIVER + string "Set uart dev path" + default "/dev/uart2_dev2" + config LORA_PIN_DEV_DRIVER + string "Set pin dev path" + default "/dev/pin_dev" + endif + endif + + menuconfig USER_TEST_RS485 + select BSP_USING_UART + select BSP_USING_GPIO + select RESOURCES_PIN + select BSP_USING_UART1 + bool "Config test uart(RS485)" + default n + if USER_TEST_RS485 + if ADD_XIZI_FETURES + config RS485_UART_DEV_DRIVER + string "Set uart dev path" + default "/dev/uart1_dev1" + config RS485_PIN_DEV_DRIVER + string "Set pin dev path" + default "/dev/pin_dev" + endif + endif + + menuconfig USER_TEST_RTC + select BSP_USING_RTC + bool "Config test rtc" + default n + if USER_TEST_RTC + if ADD_XIZI_FETURES + config RTC_DEV_DRIVER + string "Set rtc dev path" + default "/dev/rtc_dev" + endif + endif + + menuconfig USER_TEST_HWTIMER + select BSP_USING_HWTIMER + select BSP_USING_GPIO + bool "Config test hwtimer" + default n + if USER_TEST_HWTIMER + if ADD_XIZI_FETURES + config HWTIMER_PIN_DEV_DRIVER + string "Set pin dev path" + default "/dev/pin_dev" + endif + endif + + menuconfig USER_TEST_WDT + select BSP_USING_WDT0 + bool "Config test watchdog" + default n + if USER_TEST_WDT + if ADD_XIZI_FETURES + config WDT0_DEV_DRIVER + string "Set wdt dev path" + default "/dev/wdt0_dev0" + endif + endif + + menuconfig USER_TEST_LCD_EDU + select BSP_USING_LCD + bool "Config test lcd in PrivOpen" + default n + if USER_TEST_LCD_EDU + if ADD_XIZI_FETURES + config EDU_LCD_DEV_DRIVER + string "Set lcd dev path" + default "/dev/lcd_dev" + endif + endif + + menuconfig USER_TEST_I2C + select BSP_USING_I2C + bool "Config test i2c" + default n + if USER_TEST_I2C + if ADD_XIZI_FETURES + config I2C_DEV_DRIVER + string "Set i2c dev path" + default "/dev/i2c1_dev0" + endif + endif + config USER_TEST_SEMC bool "Config test semc sdram" default n @@ -33,5 +158,7 @@ menu "test app" config USER_TEST_LCD bool "Config test lcd device" default n + + endif endmenu diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index be43d9839..8361d10a4 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -10,6 +10,14 @@ ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) CSRCS += test_lcd.c endif + ifeq ($(CONFIG_BSP_USING_TOUCH),y) + CSRCS += test_touch.c + endif + + ifeq ($(CONFIG_MUSL_LIBC),y) + CSRCS += test_musl.c + endif + include $(APPDIR)/Application.mk endif @@ -25,6 +33,10 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_FILES += test_dac.c endif + ifeq ($(CONFIG_USER_TEST_FS),y) + SRC_FILES += test_fs.c + endif + ifeq ($(CONFIG_USER_TEST_SEMC),y) SRC_FILES += test_extsram.c endif @@ -33,5 +45,37 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_FILES += endif + ifeq ($(CONFIG_USER_TEST_I2C),y) + SRC_FILES += test_i2c.c + endif + + ifeq ($(CONFIG_USER_TEST_GPIO),y) + SRC_FILES += test_gpio.c + endif + + ifeq ($(CONFIG_USER_TEST_LORA),y) + SRC_FILES += test_loraE220.c + endif + + ifeq ($(CONFIG_USER_TEST_RTC),y) + SRC_FILES += test_rtc.c + endif + + ifeq ($(CONFIG_USER_TEST_RS485),y) + SRC_FILES += test_rs485.c + endif + + ifeq ($(CONFIG_USER_TEST_HWTIMER),y) + SRC_FILES += test_hwtimer.c + endif + + ifeq ($(CONFIG_USER_TEST_LCD_EDU),y) + SRC_FILES += test_lcd_edu.c + endif + + ifeq ($(CONFIG_USER_TEST_WDT),y) + SRC_FILES += test_wdt.c + endif + include $(KERNEL_ROOT)/compiler.mk endif diff --git a/APP_Framework/Applications/app_test/test_adc.c b/APP_Framework/Applications/app_test/test_adc.c index 1d6ad202a..6366555be 100644 --- a/APP_Framework/Applications/app_test/test_adc.c +++ b/APP_Framework/Applications/app_test/test_adc.c @@ -56,4 +56,4 @@ void TestAdc(void) return; } -PRIV_SHELL_CMD_FUNCTION(TestAdc, a adc test sample, PRIV_SHELL_CMD_MAIN_ATTR); +PRIV_SHELL_CMD_FUNCTION(TestAdc, a adc test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_fs.c b/APP_Framework/Applications/app_test/test_fs.c new file mode 100644 index 000000000..74d7493b6 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_fs.c @@ -0,0 +1,62 @@ +#include +#include +#include + +#define MAX_READ_LENGTH 1000 + +// sd card here is loaded as "/" +void TestFs(void) +{ + //open the file in sdcard + int fd = open(FPATH,O_RDWR|O_CREAT); + if(fd<0){ + printf("fs fd open error:%d\n",fd); + return; + } + + char filewords[MAX_READ_LENGTH]; + memset(filewords,0,MAX_READ_LENGTH); + const char *input_words = "these words are going to write in fs\n"; + + //read and write then close file + int err_flag = read(fd,filewords,MAX_READ_LENGTH); + if(err_flag<0){ + printf("read failed,error:%d\n",err_flag); + return; + } + printf("read data is \n%s\n",filewords); + + err_flag = write(fd,input_words,strlen(input_words)); + if(err_flag<0){ + printf("write failed,error:%d\n",err_flag); + return; + } + err_flag = close(fd); + if(err_flag<0){ + printf("close failed,error %d\n",err_flag); + return ; + } + + //re-open the file and re-read the file + fd = open(FPATH,O_RDWR); + if(fd<0){ + printf("fs fd open error:%d\n",fd); + return; + } + err_flag = read(fd,filewords,MAX_READ_LENGTH); + if(err_flag<0){ + printf("read failed,error:%d\n",err_flag); + return; + } + + printf("read data is \n%s\n",filewords); + err_flag = close(fd); + if(err_flag<0){ + printf("close failed,error:%d\n",err_flag); + return; + } + + return; +} + +PRIV_SHELL_CMD_FUNCTION(TestFs, a sd or usb filesystem test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_gpio.c b/APP_Framework/Applications/app_test/test_gpio.c new file mode 100644 index 000000000..42c353dbf --- /dev/null +++ b/APP_Framework/Applications/app_test/test_gpio.c @@ -0,0 +1,73 @@ +#include +#include +#include + +#define BSP_LED_PIN 29 +#define BSP_KEY_PIN 31 +#define NULL_PARAMETER 0 + +void TestGpio(void) +{ + int pin_fd = PrivOpen(GPIO_DEV_DRIVER, O_RDWR); + if(pin_fd<0){ + printf("open pin fd error:%d\n",pin_fd); + return; + } + + //config led pin in board + struct PinParam parameter; + parameter.cmd = GPIO_CONFIG_MODE; + parameter.pin = BSP_LED_PIN; + parameter.mode = GPIO_CFG_OUTPUT; + + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = PIN_TYPE; + ioctl_cfg.args = (void *)¶meter; + + if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) { + printf("ioctl pin fd error %d\n", pin_fd); + PrivClose(pin_fd); + return; + } + + //config key pin in board + parameter.pin = BSP_KEY_PIN; + parameter.mode = GPIO_CFG_INPUT; + + if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) { + printf("ioctl pin fd error %d\n", pin_fd); + PrivClose(pin_fd); + return; + } + + struct PinStat pin_led; + struct PinStat pin_key; + + pin_led.pin = BSP_LED_PIN; + pin_key.pin = BSP_KEY_PIN; + + //recycle read pin and write pin until key break + while(1){ + if(0>PrivRead(pin_fd,&pin_key,NULL_PARAMETER)){ + printf("read pin fd error %d\n", pin_fd); + PrivClose(pin_fd); + return; + } + + //led on if key pressed,or led off + if(pin_key.val){ + pin_led.val = GPIO_HIGH; + }else{ + pin_led.val = GPIO_LOW; + } + + if(0>PrivWrite(pin_fd,&pin_led,NULL_PARAMETER)){ + printf("write pin fd error %d\n", pin_fd); + PrivClose(pin_fd); + return; + } + + } +} + +PRIV_SHELL_CMD_FUNCTION(TestGpio, a gpio test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_hwtimer.c b/APP_Framework/Applications/app_test/test_hwtimer.c new file mode 100644 index 000000000..985d7fac7 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_hwtimer.c @@ -0,0 +1,62 @@ +#include +#include +#include + +#define BSP_LED_PIN 29 +#define NULL_PARAMETER 0 + +static uint16_t pinval=0; + +void ledflip(void *parameter) +{ + int tmp_fd = *(int*)parameter; + struct PinStat pin_led; + pin_led.pin = BSP_LED_PIN; + pin_led.val = !pinval; + pinval = !pinval; + PrivWrite(tmp_fd,&pin_led,NULL_PARAMETER); + printf("Timer has callback once\n"); +} + +void TestHwTimer(int argc, char *argv[]) +{ + x_ticks_t period = 100;//uint:10ms + + if(argc>1){ + period = (x_ticks_t)atoi(argv[1]); + } + + + int pin_fd = PrivOpen(HWTIMER_PIN_DEV_DRIVER, O_RDWR); + if(pin_fd<0){ + printf("open pin fd error:%d\n",pin_fd); + return; + } + + //config led pin in board + struct PinParam parameter; + parameter.cmd = GPIO_CONFIG_MODE; + parameter.pin = BSP_LED_PIN; + parameter.mode = GPIO_CFG_OUTPUT; + + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = PIN_TYPE; + ioctl_cfg.args = (void *)¶meter; + + if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) { + printf("ioctl pin fd error %d\n", pin_fd); + PrivClose(pin_fd); + return; + } + + int32 timer_handle = KCreateTimer("LED on and off by 1s",&ledflip,&pin_fd,period,TIMER_TRIGGER_PERIODIC); + + KTimerStartRun(timer_handle); + PrivTaskDelay(10000); + KTimerQuitRun(timer_handle); + + KDeleteTimer(timer_handle); + +} + +PRIV_SHELL_CMD_FUNCTION(TestHwTimer, a timer test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_i2c.c b/APP_Framework/Applications/app_test/test_i2c.c new file mode 100644 index 000000000..43a2f224a --- /dev/null +++ b/APP_Framework/Applications/app_test/test_i2c.c @@ -0,0 +1,50 @@ +#include +#include +#include + +#define I2C_SLAVE_ADDRESS 0x0012U + +void TestI2C(void) +{ + // config IIC pin(SCL:34.SDA:35) in menuconfig + int iic_fd = PrivOpen(I2C_DEV_DRIVER, O_RDWR); + if (iic_fd < 0) + { + printf("open iic_fd fd error:%d\n", iic_fd); + return; + } + printf("IIC open successful!\n"); + + // init iic + uint16 iic_address = I2C_SLAVE_ADDRESS; + + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = I2C_TYPE; + ioctl_cfg.args = (void *)&iic_address; + + if (0 != PrivIoctl(iic_fd, OPE_INT, &ioctl_cfg)) + { + printf("ioctl iic fd error %d\n", iic_fd); + PrivClose(iic_fd); + return; + } + printf("IIC configure successful!\n"); + + // I2C read and write + char tmp_buff[100]; + while (1) + { + PrivTaskDelay(1000); + PrivWrite(iic_fd, "Hello World!\n", sizeof("Hello World!\n")); + printf("msg send:%s\n", "Hello World!\n"); + PrivTaskDelay(1000); + memset(tmp_buff, 0, sizeof(tmp_buff)); + PrivRead(iic_fd, tmp_buff, sizeof(tmp_buff)); + printf("msg recv:%s\n", tmp_buff); + } + + PrivClose(iic_fd); + return; +} + +PRIV_SHELL_CMD_FUNCTION(TestI2C, a iic test sample, PRIV_SHELL_CMD_MAIN_ATTR); diff --git a/APP_Framework/Applications/app_test/test_lcd.c b/APP_Framework/Applications/app_test/test_lcd.c index d6633dd1b..0e8b4be28 100755 --- a/APP_Framework/Applications/app_test/test_lcd.c +++ b/APP_Framework/Applications/app_test/test_lcd.c @@ -1,26 +1,22 @@ -/**************************************************************************** - * apps/examples/fb/fb_main.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. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ -/**************************************************************************** - * Included Files - ****************************************************************************/ +/** +* @file: test_lcd.c +* @brief: a application of dac function +* @version: 2.0 +* @author: AIIT XUOS Lab +* @date: 2022/1/11 +*/ #include @@ -29,40 +25,39 @@ #ifdef CONFIG_K210_LCD void LcdDemo(void) { - int x1 = 50, y1 = 50, x2 = LCD_XSIZE_TFT - 50, y2 = LCD_YSIZE_TFT - 50; + int lcd_fd = PrivOpen("/dev/lcd_dev",O_RDWR); + LcdWriteParam disp_info; - Main_Image_Start_Address(LCD_START_ADDR); - Main_Image_Width(LCD_XSIZE_TFT); - Main_Window_Start_XY(0, 0); - Canvas_Image_Start_address(LCD_START_ADDR); - Canvas_image_width(LCD_XSIZE_TFT); - Active_Window_XY(0, 0); - Active_Window_WH(LCD_XSIZE_TFT, LCD_YSIZE_TFT); - up_mdelay(10); - Canvas_Image_Start_address(LCD_START_ADDR); + disp_info.type = 0; + disp_info.string_info.x_pos = 80; + disp_info.string_info.y_pos = 80; + disp_info.string_info.width = 250; + disp_info.string_info.height = 24; + disp_info.string_info.font_size = 24; + disp_info.string_info.addr = "wecome test lcd"; + disp_info.string_info.font_color = GREEN; + disp_info.string_info.back_color = BLUE; + PrivWrite(lcd_fd, &disp_info, sizeof(LcdWriteParam)); + PrivTaskDelay(2000); - for(int i = 0; i < 3; i++) - { - x1 = 50; - y1 = 50; - x2 = LCD_XSIZE_TFT - 50; - y2 = LCD_YSIZE_TFT - 50; - syslog(LOG_NOTICE, "Disp_demo %d (%d,%d - %d,%d)\n", i, x1, y1, x2, y2); - LT768_DrawSquare_Fill(x1, y1, x2, y2, Red); - up_mdelay(2000); - x1 += 20; - y1 += 20; - x2 -= 20; - y2 -= 20; - LT768_DrawSquare_Fill(x1, y1, x2, y2, Green); - up_mdelay(2000); - x1 += 20; - y1 += 20; - x2 -= 20; - y2 -= 20; - LT768_DrawSquare_Fill(x1, y1, x2, y2, Blue); - up_mdelay(2000); - } + disp_info.type = 1; + lv_color_t redcolor = { + .ch = { + .red = 0b11111, + .green = 0, + .blue = 0 + } + }; + disp_info.pixel_info.x_startpos = 0; + disp_info.pixel_info.x_endpos = 50; + disp_info.pixel_info.y_startpos = 0; + disp_info.pixel_info.y_endpos = 50; + disp_info.pixel_info.pixel_color = &redcolor; + PrivWrite(lcd_fd, &disp_info, sizeof(LcdWriteParam)); + PrivTaskDelay(2000); + + disp_info.type = SHOW_TRIANGLE; + PrivWrite(lcd_fd, &disp_info, sizeof(LcdWriteParam)); } #else diff --git a/APP_Framework/Applications/app_test/test_lcd_edu.c b/APP_Framework/Applications/app_test/test_lcd_edu.c new file mode 100644 index 000000000..0d87ef2ea --- /dev/null +++ b/APP_Framework/Applications/app_test/test_lcd_edu.c @@ -0,0 +1,50 @@ +#include +#include +#include + +#define GRAPHIC_CTRL_RECT_UPDATE 0x00 +#define LCD_STRING_TYPE 0 +#define LCD_DOT_TYPE 1 +#define LCD_FONT_RECT_WIDTH 150 +#define LCD_FONT_RECT_HEIGHT 50 +#define NULL_PARAMETER 0 + +void TestLcd(void) +{ + int lcd_fd = PrivOpen(EDU_LCD_DEV_DRIVER, O_RDWR); + if (lcd_fd < 0) + { + printf("open lcd fd error:%d\n", lcd_fd); + return; + } + + // draw text + LcdWriteParam graph_param; + graph_param.type = LCD_STRING_TYPE; + graph_param.string_info.x_pos = 0; + graph_param.string_info.y_pos = 0; + graph_param.string_info.width = 250; + graph_param.string_info.height = 24; + graph_param.string_info.font_size = 24; + graph_param.string_info.back_color = 0xFFFF; + graph_param.string_info.font_color = 0x0000; + graph_param.string_info.addr = "hello_world!"; + + PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER); + + uint16 color_select = 0xF800; + for (int i = 0; i < 5; i++) + { + graph_param.type = LCD_DOT_TYPE; + graph_param.pixel_info.x_startpos = 0; + graph_param.pixel_info.y_startpos = 50 * i; + graph_param.pixel_info.x_endpos = 320; + graph_param.pixel_info.y_endpos = 50 * i; + graph_param.pixel_info.pixel_color = &color_select; + PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER); + } + + PrivClose(lcd_fd); +} + +PRIV_SHELL_CMD_FUNCTION(TestLcd, a lcd test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_loraE220.c b/APP_Framework/Applications/app_test/test_loraE220.c new file mode 100644 index 000000000..c4409dd21 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_loraE220.c @@ -0,0 +1,147 @@ +#include +#include +#include + +#define NULL_PARAMETER 0 +#define E220_CFG_LENGTH +#define GPIOSET(fd, buf, bit) \ + { \ + buf.val = bit; \ + if (0 > PrivWrite(fd, &buf, NULL_PARAMETER)) \ + { \ + printf("write pin fd error %d\n", fd); \ + PrivClose(fd); \ + return; \ + } \ + } +#define BSP_E220_M0_PIN 32 +#define BSP_E220_M1_PIN 33 + +void TestLora(int argc, char *argv[]) +{ + char uart_recvbuff[100]; + memset(uart_recvbuff, 0, sizeof(uart_recvbuff)); + + int pin_fd = PrivOpen(LORA_PIN_DEV_DRIVER, O_RDWR); + if (pin_fd < 0) + { + printf("open pin fd error:%d\n", pin_fd); + return; + } + + int uart_fd = PrivOpen(LORA_UART_DEV_DRIVER, O_RDWR); + if (uart_fd < 0) + { + printf("open pin fd error:%d\n", uart_fd); + return; + } + printf("uart and pin fopen success\n"); + + struct PinStat pin_m0; + struct PinStat pin_m1; + pin_m0.pin = BSP_E220_M0_PIN; + pin_m1.pin = BSP_E220_M1_PIN; + + // config led pin in board + struct PrivIoctlCfg ioctl_cfg; + struct PinParam pin_param; + pin_param.cmd = GPIO_CONFIG_MODE; + pin_param.mode = GPIO_CFG_OUTPUT; + pin_param.pin = BSP_E220_M0_PIN; + ioctl_cfg.ioctl_driver_type = PIN_TYPE; + ioctl_cfg.args = &pin_param; + if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) + { + printf("ioctl pin fd error %d\n", pin_fd); + PrivClose(pin_fd); + return; + } + + pin_param.pin = BSP_E220_M1_PIN; + if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) + { + printf("ioctl pin fd error %d\n", pin_fd); + PrivClose(pin_fd); + return; + } + + printf("pin configure success\n"); + struct SerialDataCfg uart_cfg; + memset(&uart_cfg, 0, sizeof(struct SerialDataCfg)); + + // loraE220 support only 9600bps with 8N1 during initializing + uart_cfg.serial_baud_rate = BAUD_RATE_9600; + uart_cfg.serial_data_bits = DATA_BITS_8; + uart_cfg.serial_stop_bits = STOP_BITS_1; + uart_cfg.serial_parity_mode = PARITY_NONE; + uart_cfg.serial_bit_order = BIT_ORDER_LSB; + uart_cfg.serial_invert_mode = NRZ_NORMAL; + uart_cfg.serial_buffer_size = SERIAL_RB_BUFSZ; + uart_cfg.serial_timeout = 1000; + uart_cfg.is_ext_uart = 0; + + ioctl_cfg.ioctl_driver_type = SERIAL_TYPE; + ioctl_cfg.args = (void *)&uart_cfg; + + if (0 != PrivIoctl(uart_fd, OPE_INT, &ioctl_cfg)) + { + printf("ioctl uart fd error %d\n", uart_fd); + PrivClose(uart_fd); + return; + } + printf("uart configure success\n"); + + GPIOSET(pin_fd, pin_m0, GPIO_HIGH); + GPIOSET(pin_fd, pin_m1, GPIO_HIGH); + printf("lora configure into sleep(configure) mode\n"); + + // send configure data, and receive the same length of data + char sendbuff[] = {0xC0, 0x00, 0x05, 0x19, 0x49, 0xE6, 0x00, 0x17}; // config as address 1949 CH17 36.8kps + + PrivTaskDelay(2000); + + printf("Sending lora configure information(SIZE:%d)\n", sizeof(sendbuff)); + PrivWrite(uart_fd, sendbuff, sizeof(sendbuff)); + printf("lora configure information send\n"); + + PrivTaskDelay(2000); + + PrivRead(uart_fd, uart_recvbuff, sizeof(sendbuff)); + printf("%x %x %x %x", uart_recvbuff[0], uart_recvbuff[1], uart_recvbuff[2], uart_recvbuff[3]); + printf("lora configure success\n"); + + // error when all bytes are 0xff + if (0xFF == (uart_recvbuff[0] & uart_recvbuff[1] & uart_recvbuff[2])) + { + printf("from lora receive error:%d\n", 0xff); + return; + } + + uart_cfg.serial_baud_rate = BAUD_RATE_115200; + if (0 != PrivIoctl(uart_fd, OPE_INT, &ioctl_cfg)) + { + printf("ioctl uart fd error %d\n", uart_fd); + PrivClose(uart_fd); + return; + } + + // into transparent transmission mode + GPIOSET(pin_fd, pin_m0, GPIO_LOW); + GPIOSET(pin_fd, pin_m1, GPIO_LOW); + // receive and send "Hello World" + while (1) + { + PrivTaskDelay(500); + PrivWrite(uart_fd, "Hello_World!", sizeof("Hello_World!")); + printf("Data Send:\n%s\n", "Hello_World!"); + + PrivTaskDelay(500); + memset(uart_recvbuff, 0, sizeof(uart_recvbuff)); + PrivRead(uart_fd, uart_recvbuff, sizeof(uart_recvbuff)); + printf("Receive Data is :\n%s\n", uart_recvbuff); + } + PrivClose(pin_fd); + PrivClose(uart_fd); +} + +PRIV_SHELL_CMD_FUNCTION(TestLora, a lora test sample, PRIV_SHELL_CMD_MAIN_ATTR); diff --git a/APP_Framework/Applications/app_test/test_musl.c b/APP_Framework/Applications/app_test/test_musl.c new file mode 100644 index 000000000..bfa1ba1f7 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_musl.c @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: test_musl.c +* @brief: a application of musl test function +* @version: 2.0 +* @author: AIIT XUOS Lab +* @date: 2022/11/8 +*/ + +#include + +#ifdef ADD_NUTTX_FETURES + +#if defined(CONFIG_MUSL_LIBC) && defined(CONFIG_FS_AUTOMOUNTER) + +static void file_read_and_write(void) +{ + FILE *p; + char s[] = "good luck to you!"; + char buffer[20]; + + if((p = fopen("/mnt/sdcard/test.txt","w+")) == NULL) + { + printf("Can not open file!\n"); + } + fwrite(s, sizeof(s) + 1, 1, p); + fseek(p, SEEK_SET, 0); + fread(buffer, sizeof(buffer) + 1, 1, p); + printf("read string is: %s\n", buffer); + fclose(p); +} + +static void file_operations(void) +{ + int ret; + FILE *fp; + char filename1[] = "/mnt/sdcard/file1.txt"; + char filename2[] = "/mnt/sdcard/file2.txt"; + + fp = fopen(filename1, "w"); + + fprintf(fp, "%s", "this is runoob.com"); + fclose(fp); + + ret = remove(filename1); + + if(ret == 0) + { + printf("remove file1 success!\n"); + } + else + { + printf("error,can not remove file1!\n"); + } + + ret = remove(filename2); + if(ret == 0) + { + printf("remove file2 success!\n"); + } + else + { + printf("error,can not remove file2!\n"); + } +} + +static void malloc_and_free(void) +{ + int *p; + int len; + for(int i = 0; i < 100; i++) + { + len = 1024*(i+1); + p = malloc(len); + if(p) + { + printf("malloc %d bytes success!\n",len); + free(p); + } + } +} +void Testmusl(void) +{ + printf("--------start test file read and write!--------\n"); + file_read_and_write(); + printf("----------start test file operationsn!---------\n"); + file_operations(); + printf("---------start test malloc and free!-----------\n"); + malloc_and_free(); +} +#endif +#endif diff --git a/APP_Framework/Applications/app_test/test_rs485.c b/APP_Framework/Applications/app_test/test_rs485.c new file mode 100644 index 000000000..029c7d4b1 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_rs485.c @@ -0,0 +1,86 @@ +#include +#include +#include + +#define BSP_485_DIR_PIN 24 + +void Test485(void) +{ + int pin_fd = PrivOpen(RS485_PIN_DEV_DRIVER, O_RDWR); + if (pin_fd < 0) + { + printf("open pin fd error:%d\n", pin_fd); + return; + } + + int uart_fd = PrivOpen(RS485_UART_DEV_DRIVER, O_RDWR); + if (uart_fd < 0) + { + printf("open pin fd error:%d\n", uart_fd); + return; + } + printf("uart and pin fopen success\n"); + + //config led pin in board + struct PinParam pin_parameter; + memset(&pin_parameter, 0, sizeof(struct PinParam)); + pin_parameter.cmd = GPIO_CONFIG_MODE; + pin_parameter.pin = BSP_485_DIR_PIN; + pin_parameter.mode = GPIO_CFG_OUTPUT; + + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = PIN_TYPE; + ioctl_cfg.args = (void *)&pin_parameter; + + if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) { + printf("ioctl pin fd error %d\n", pin_fd); + PrivClose(pin_fd); + return; + } + + struct SerialDataCfg uart_cfg; + memset(&uart_cfg, 0, sizeof(struct SerialDataCfg)); + + uart_cfg.serial_baud_rate = BAUD_RATE_115200; + uart_cfg.serial_data_bits = DATA_BITS_8; + uart_cfg.serial_stop_bits = STOP_BITS_1; + uart_cfg.serial_parity_mode = PARITY_NONE; + uart_cfg.serial_bit_order = BIT_ORDER_LSB; + uart_cfg.serial_invert_mode = NRZ_NORMAL; + uart_cfg.serial_buffer_size = SERIAL_RB_BUFSZ; + uart_cfg.serial_timeout = 1000; + uart_cfg.is_ext_uart = 0; + + ioctl_cfg.ioctl_driver_type = SERIAL_TYPE; + ioctl_cfg.args = (void *)&uart_cfg; + + if (0 != PrivIoctl(uart_fd, OPE_INT, &ioctl_cfg)) + { + printf("ioctl uart fd error %d\n", uart_fd); + PrivClose(uart_fd); + return; + } + + struct PinStat pin_dir; + pin_dir.pin = BSP_485_DIR_PIN; + while (1) + { + pin_dir.val = GPIO_HIGH; + PrivWrite(pin_fd,&pin_dir,0); + PrivWrite(uart_fd,"Hello world!\n",sizeof("Hello world!\n")); + PrivTaskDelay(100); + + pin_dir.val = GPIO_LOW; + PrivWrite(pin_fd,&pin_dir,0); + char recv_buff[100]; + memset(recv_buff,0,sizeof(recv_buff)); + PrivRead(uart_fd,recv_buff,20); + printf("%s",recv_buff); + PrivTaskDelay(100); + } + PrivClose(pin_fd); + PrivClose(uart_fd); + return; +} + +PRIV_SHELL_CMD_FUNCTION(Test485, a RS485 test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_rtc.c b/APP_Framework/Applications/app_test/test_rtc.c new file mode 100644 index 000000000..3a95c6cea --- /dev/null +++ b/APP_Framework/Applications/app_test/test_rtc.c @@ -0,0 +1,38 @@ +#include +#include +#include + +void TestRTC(int argc,char *argv[]) +{ + int rtc_fd = PrivOpen(RTC_DEV_DRIVER, O_RDWR); + if(rtc_fd<0){ + printf("open rtc fd error:%d\n",rtc_fd); + return; + } + + if(argc>1){ + + int times = atoi(argv[1]); + printf("Time will be printf %d times\n",times); + struct RtcDrvConfigureParam rtc_para; + rtc_para.rtc_operation_cmd = OPER_RTC_SET_TIME; + *(rtc_para.time) = 0; + + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = RTC_TYPE; + ioctl_cfg.args = (void *)&rtc_para; + PrivIoctl(rtc_fd,0,&ioctl_cfg); + + rtc_para.rtc_operation_cmd = OPER_RTC_GET_TIME; + for(size_t i=0;i + +#ifdef ADD_NUTTX_FETURES + +#ifdef CONFIG_BSP_USING_TOUCH +void TestTouch(void) +{ + int fd; + TouchDataParam point = {0, 0, 0}; + fd = PrivOpen("/dev/touch_dev", O_RDWR); + while(1) + { + PrivRead(fd,&point,1); + printf("Now touch point:(%d,%d)\n",point.x,point.y); + } +} +#endif + +#endif diff --git a/APP_Framework/Applications/app_test/test_wdt.c b/APP_Framework/Applications/app_test/test_wdt.c new file mode 100644 index 000000000..67195466d --- /dev/null +++ b/APP_Framework/Applications/app_test/test_wdt.c @@ -0,0 +1,45 @@ +#include +#include +#include + +void TestWDT(int argc, char *agrv[]) +{ + int wdt_fd = PrivOpen(WDT0_DEV_DRIVER, O_RDWR); + if (wdt_fd < 0) + { + printf("open wdt_fd fd error:%d\n", wdt_fd); + return; + } + printf("hw watchdog open!\n"); + + // init watchdog + int wdt_time = 1000; + + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = WDT_TYPE; + ioctl_cfg.args = (void *)&wdt_time; + + if (0 != PrivIoctl(wdt_fd, OPER_WDT_SET_TIMEOUT, &ioctl_cfg)) + { + printf("ioctl wdt fd error %d\n", wdt_fd); + PrivClose(wdt_fd); + return; + } + + int test_counter = 100; + + // wdt feed or not according to argc,if argc!=1 then dog won't be feed + while (test_counter--) + { + if (1 == argc) + { + printf("dog is feed\n"); + PrivIoctl(wdt_fd, OPER_WDT_KEEPALIVE, &ioctl_cfg); // feed dog + } + PrivTaskDelay(100); + } + PrivClose(wdt_fd); + return; +} + +PRIV_SHELL_CMD_FUNCTION(TestWDT, a wdt test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/APP_Framework/Framework/transform_layer/nuttx/transform.h b/APP_Framework/Framework/transform_layer/nuttx/transform.h index 2c17c31cf..766e9a129 100644 --- a/APP_Framework/Framework/transform_layer/nuttx/transform.h +++ b/APP_Framework/Framework/transform_layer/nuttx/transform.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,7 @@ #ifdef CONFIG_USER_TEST_LCD #ifdef CONFIG_K210_LCD # include "nuttx/lcd/lt768.h" +# include "nuttx/lcd/lt768_learn.h" # include "nuttx/lcd/lt768_lib.h" # include "nuttx/lcd/if_port.h" #else @@ -127,6 +129,23 @@ extern "C" { #define EOK 0 #define x_err_t int +typedef union { + struct { + uint16_t blue : 5; + uint16_t green : 6; + uint16_t red : 5; + } ch; + uint16_t full; +} lv_color16_t; +typedef lv_color16_t lv_color_t; + +typedef struct +{ + uint16_t x; + uint16_t y; + uint16_t press; +}TouchDataParam; + struct PinDevIrq { int irq_mode;//< RISING/FALLING/HIGH/LOW diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.c b/APP_Framework/Framework/transform_layer/xizi/transform.c index 62e226b35..5f56c6f25 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.c +++ b/APP_Framework/Framework/transform_layer/xizi/transform.c @@ -169,6 +169,7 @@ int PrivIoctl(int fd, int cmd, void *args) case LCD_TYPE: ret = PrivLcdIoctl(fd, cmd, ioctl_cfg->args); break; + case RTC_TYPE: case ADC_TYPE: case DAC_TYPE: case WDT_TYPE: diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.h b/APP_Framework/Framework/transform_layer/xizi/transform.h index eddcf2153..0a0780798 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.h +++ b/APP_Framework/Framework/transform_layer/xizi/transform.h @@ -149,6 +149,7 @@ enum IoctlDriverType ADC_TYPE, DAC_TYPE, WDT_TYPE, + RTC_TYPE, DEFAULT_TYPE, }; @@ -193,6 +194,12 @@ typedef struct uint16_t press; }TouchDataParam; +struct RtcDrvConfigureParam +{ + int rtc_operation_cmd; + time_t *time; +}; + #define PRIV_SYSTICK_GET (CurrentTicksGain()) #define PRIV_LCD_DEV "/dev/lcd_dev" #define MY_DISP_HOR_RES BSP_LCD_Y_MAX diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-arm32/configs/muslnsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-arm32/configs/muslnsh/defconfig new file mode 100644 index 000000000..9b1048d9e --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-arm32/configs/muslnsh/defconfig @@ -0,0 +1,74 @@ +# +# 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-arm32" +CONFIG_ARCH_BOARD_XIDATONG_ARM32=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_IDLETHREAD_STACKSIZE=2048 +CONFIG_EXAMPLES_HELLO=y +CONFIG_IMXRT_GPIO_IRQ=y +CONFIG_IMXRT_GPIO2_16_31_IRQ=y +CONFIG_IMXRT_GPIO3_0_15_IRQ=y +CONFIG_DEV_GPIO=y +CONFIG_IMXRT_LPUART1=y +CONFIG_IMXRT_USDHC1=y +CONFIG_IMXRT_USDHC1_WIDTH_D1_D4=y +CONFIG_INTELHEX_BINARY=y +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_NCHAINS=8 +CONFIG_LIBC_STRERROR=y +CONFIG_LPUART1_SERIAL_CONSOLE=y +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=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=32768 +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_SDIO_BLOCKSETUP=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_FS_AUTOMOUNTER=y +CONFIG_XIDATONG_ARM32_SDIO_AUTOMOUNT=y +CONFIG_SYSTEM_NSH=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=100 +CONFIG_READLINE_CMD_HISTORY_LINELEN=120 +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_BOARDCTL_RESET=y +CONFIG_MUSL_LIBC=y +CONFIG_INIT_ENTRYPOINT="nsh_main" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig index a4a4dac80..1c4b20310 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig @@ -39,6 +39,12 @@ menuconfig BSP_USING_TOUCH bool "Using touch device" default n +menuconfig BSP_USING_CAN + select K210_16550_UART + select K210_16550_UART1 + bool "Using CAN device" + default n + menuconfig BSP_USING_CH438 bool "Using CH438 device" default n diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/cannsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/cannsh/defconfig new file mode 100644 index 000000000..cedd3946d --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/cannsh/defconfig @@ -0,0 +1,73 @@ +# +# 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_NSH_DISABLE_LOSMART is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ADD_NUTTX_FETURES=y +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="xidatong-riscv64" +CONFIG_ARCH_BOARD_XIDATONG_RISCV64=y +CONFIG_ARCH_CHIP="k210" +CONFIG_ARCH_CHIP_K210=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARD_LOOPSPERMSEC=46000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3072 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_DISABLE_MKDIR=y +CONFIG_NSH_DISABLE_RM=y +CONFIG_NSH_DISABLE_RMDIR=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=2097152 +CONFIG_RAM_START=0x80400000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=100 +CONFIG_READLINE_CMD_HISTORY_LINELEN=120 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=28 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=20 +CONFIG_TESTING_GETPRIME=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_SCHED_HPWORK=y +CONFIG_DEV_GPIO=y +CONFIG_BOARDCTL_RESET=y +CONFIG_K210_16550_UART=y +CONFIG_K210_16550_UART1=y +CONFIG_K210_16550_UART1_BASE=0x50210000 +CONFIG_K210_16550_UART1_CLOCK=195000000 +CONFIG_K210_16550_UART1_IRQ=38 +CONFIG_K210_16550_UART1_BAUD=115200 +CONFIG_K210_16550_UART1_PARITY=0 +CONFIG_K210_16550_UART1_BITS=8 +CONFIG_K210_16550_UART1_2STOP=0 +CONFIG_K210_16550_UART1_RXBUFSIZE=128 +CONFIG_K210_16550_UART1_TXBUFSIZE=128 +CONFIG_BSP_USING_CAN=y +CONFIG_SERIAL_TERMIOS=y diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h index d429da72a..9828984d6 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h @@ -78,8 +78,6 @@ extern "C" #endif /*************************** GPIO define ***************************/ -/* Connected to red led */ -#define BOARD_LED_PAD 14 /* UART IO */ #define GPIO_WIFI_RXD 7 @@ -88,6 +86,8 @@ extern "C" #define GPIO_EC200T_TXD 20 #define GPIO_CH376T_RXD 22 #define GPIO_CH376T_TXD 23 +#define GPIO_CAN_RXD 18 +#define GPIO_CAN_TXD 19 /* ch438 IO */ #define CH438_ALE_PIN 24 @@ -128,12 +128,12 @@ extern "C" #define GPIO_E220_M1 45 #define GPIO_E18_MODE 46 #define GPIO_WIFI_EN 8 +#define GPIO_CAN_CFG 43 /************************** end GPIO define **************************/ /*************************** FPIOA define ***************************/ -#define BOARD_LED_IO 0 /* UART FPOA */ #define FPOA_USART1_RX K210_IO_FUNC_UART1_RX @@ -182,6 +182,7 @@ extern "C" #define FPIOA_E220_M1 2 #define FPIOA_E18_MODE 3 #define FPIOA_WIFI_EN 4 +#define FPIOA_CAN_NCFG 5 /************************** end FPIOA define **************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile index 7ac890b57..c5c32c0ae 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile @@ -58,4 +58,8 @@ ifeq ($(CONFIG_BSP_USING_TOUCH),y) CSRCS += k210_touch.c endif +ifeq ($(CONFIG_BSP_USING_CAN),y) +CSRCS += can_demo.c +endif + include $(TOPDIR)/boards/Board.mk diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/can_demo.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/can_demo.c new file mode 100644 index 000000000..9a98e1446 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/can_demo.c @@ -0,0 +1,147 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file can_demo.c + * @brief xidatong-riscv64 can_demo.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.11.10 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "time.h" +#include +#include +#include +#include +#include +#include "k210_uart_16550.h" +#include "k210_fpioa.h" +#include "k210_gpiohs.h" +#include "k210_gpio_common.h" + +static int fd, flag=0; + +static void serial_thread_entry(void) +{ + uint8_t ch; + while(read(fd, &ch, 1) == 1) + { + printf("%02x ",ch); + } +} + +static void start_thread(void) +{ + int ret; + pthread_t thread; + pthread_attr_t attr = PTHREAD_ATTR_INITIALIZER; + attr.priority = 20; + attr.stacksize = 2048; + + ret = pthread_create(&thread, &attr, (void*)serial_thread_entry, NULL); + if (ret != 0) + { + printf("task create failed, status=%d\n", ret); + } + + flag = 1; +} + +static void set_baud(unsigned long speed) +{ + struct termios cfg; + tcgetattr(fd, &cfg); + cfsetspeed(&cfg, speed); + tcsetattr(fd, TCSANOW, &cfg); +} + +static void can_cfg_start(void) +{ + uint8_t cmd[8]; + set_baud(9600); + up_mdelay(1000); + + k210_gpiohs_set_direction(FPIOA_CAN_NCFG, GPIO_DM_OUTPUT); + k210_gpiohs_set_value(FPIOA_CAN_NCFG, GPIO_PV_LOW); + up_mdelay(200); + + cmd[0] = 0xAA; + cmd[1] = 0x55; + cmd[2] = 0xFD; + cmd[3] = 0x32; + cmd[4] = 0x01; + cmd[5] = 0x0B; + cmd[6] = 0xc4; + cmd[7] = 0x29; + write(fd, cmd, 8); +} + +static void can_cfg_end(void) +{ + k210_gpiohs_set_direction(FPIOA_CAN_NCFG, GPIO_DM_OUTPUT); + k210_gpiohs_set_value(FPIOA_CAN_NCFG, GPIO_PV_HIGH); + set_baud(115200); +} + +void can_test(void) +{ + uint8_t msg[8]; + uint8_t i; + + fd = open("/dev/ttyS1", O_RDWR); + if (flag == 0) + { + /* 1、start thread */ + start_thread(); + up_mdelay(20); + + /* 2、config can prama */ + can_cfg_start(); + up_mdelay(20); + + /* 3、exit config */ + can_cfg_end(); + up_mdelay(20);; + } + + /* 4、send data */ + for(i=0;i<10;i++) + { + msg[0] = 0x11; + msg[1] = 0x22; + msg[2] = 0x33; + msg[3] = 0x44; + msg[4] = 0x55; + msg[5] = 0x66; + msg[6] = 0x77; + msg[7] = 0x99; + write(fd, msg, 8); + up_mdelay(20); + } +} \ No newline at end of file diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c index f8d439e52..dd3e7b01f 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c @@ -60,7 +60,7 @@ void CH376Demo(void) printf( "CH376FileCreatePath:0x%02x\n",(uint16_t)s ); printf( "Write some data to file\n" ); - strcpy( (char *)buf, "This is 演示数据\xd\xa" ); + strcpy( (char *)buf, "This is test case!\xd\xa" ); s = CH376ByteWrite(buf, strlen((char *)buf), NULL ); printf( "CH376ByteWrite:0x%02x\n",(uint16_t)s ); diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c index 4f4eb7b0f..48e1f7fbc 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c @@ -47,6 +47,10 @@ # include "k210_ch438.h" #endif +#ifdef CONFIG_BSP_USING_TOUCH +# include "k210_touch.h" +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -87,23 +91,40 @@ int k210_bringup(void) board_lcd_initialize(); #endif +#ifdef CONFIG_BSP_USING_TOUCH + board_touch_initialize(); +#endif + #ifdef CONFIG_K210_16550_UART1 +#ifdef CONFIG_ADAPTER_ESP8285_WIFI sysctl_clock_enable(SYSCTL_CLOCK_UART1); sysctl_reset(SYSCTL_RESET_UART1); fpioa_set_function(GPIO_WIFI_TXD, FPOA_USART1_RX); fpioa_set_function(GPIO_WIFI_RXD, FPOA_USART1_TX); - fpioa_set_function(GPIO_WIFI_EN, K210_IO_FUNC_GPIOHS0 + GPIO_WIFI_EN); - k210_gpiohs_set_direction(GPIO_WIFI_EN, GPIO_DM_OUTPUT); - k210_gpiohs_set_value(GPIO_WIFI_EN, GPIO_PV_LOW); + fpioa_set_function(GPIO_WIFI_EN, K210_IO_FUNC_GPIOHS0 + FPIOA_WIFI_EN); + k210_gpiohs_set_direction(FPIOA_WIFI_EN, GPIO_DM_OUTPUT); + k210_gpiohs_set_value(FPIOA_WIFI_EN, GPIO_PV_LOW); up_mdelay(50); - k210_gpiohs_set_value(GPIO_WIFI_EN, GPIO_PV_HIGH); + k210_gpiohs_set_value(FPIOA_WIFI_EN, GPIO_PV_HIGH); +#endif + +#ifdef CONFIG_BSP_USING_CAN + sysctl_clock_enable(SYSCTL_CLOCK_UART1); + sysctl_reset(SYSCTL_RESET_UART1); + + fpioa_set_function(GPIO_CAN_TXD, FPOA_USART1_TX); + fpioa_set_function(GPIO_CAN_RXD, FPOA_USART1_RX); + + k210_fpioa_config(GPIO_CAN_CFG, HS_GPIO(FPIOA_CAN_NCFG) | K210_IOFLAG_GPIOHS); +#endif #endif #ifdef CONFIG_K210_16550_UART2 sysctl_clock_enable(SYSCTL_CLOCK_UART2); sysctl_reset(SYSCTL_RESET_UART2); + fpioa_set_function(GPIO_EC200T_RXD, FPOA_USART2_RX); fpioa_set_function(GPIO_EC200T_TXD, FPOA_USART2_TX); #endif @@ -111,6 +132,7 @@ int k210_bringup(void) #ifdef CONFIG_K210_16550_UART3 sysctl_clock_enable(SYSCTL_CLOCK_UART3); sysctl_reset(SYSCTL_RESET_UART3); + fpioa_set_function(GPIO_CH376T_RXD, FPOA_USART3_RX); fpioa_set_function(GPIO_CH376T_TXD, FPOA_USART3_TX); #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch438.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch438.h index 510e5757b..d51b4ac9a 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch438.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch438.h @@ -18,8 +18,8 @@ * @date 2022.04.26 */ -#ifndef __BOARDS_ARM_IMXRT_XIDATONG_SRC_IMXRT_CH438_H -#define __BOARDS_ARM_IMXRT_XIDATONG_SRC_IMXRT_CH438_H +#ifndef __BOARDS_XIDATONG_SRC_RISCV64_CH438_H +#define __BOARDS_XIDATONG_SRC_RISCV64_CH438_H /**************************************************************************** * Included Files @@ -322,5 +322,5 @@ void board_ch438_initialize(void); #endif -#endif /* __BOARDS_ARM_IMXRT_XIDATONG_SRC_IMXRT_CH438_H */ +#endif /* __BOARDS_XIDATONG_SRC_RISCV64_CH438_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_lcd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_lcd.c index bc689c08f..e5a54f668 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_lcd.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_lcd.c @@ -22,19 +22,25 @@ /**************************************************************************** * Included Files ****************************************************************************/ - +#include #include "k210_fpioa.h" #include "k210_gpiohs.h" #include "nuttx/arch.h" #include "nuttx/lcd/lt768.h" #include "nuttx/lcd/lt768_lib.h" #include "nuttx/lcd/if_port.h" +#include "nuttx/lcd/lt768_learn.h" #include #include +#include +#include #ifdef CONFIG_LCD_LCDDRV_SPIIF #include "nuttx/lcd/lcddrv_spiif.h" #endif +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ #define NCS_H() k210_gpiohs_set_value(FPIOA_LCD_NCS, GPIO_PV_HIGH); up_udelay(20) #define NCS_L() k210_gpiohs_set_value(FPIOA_LCD_NCS, GPIO_PV_LOW); up_udelay(20) #define CLK_H() k210_gpiohs_set_value(FPIOA_LCD_SCLK, GPIO_PV_HIGH); up_udelay(20) @@ -42,6 +48,25 @@ #define MOSI_H() k210_gpiohs_set_value(FPIOA_LCD_MOSI, GPIO_PV_HIGH) #define MOSI_L() k210_gpiohs_set_value(FPIOA_LCD_MOSI, GPIO_PV_LOW) +static int lcd_open(FAR struct file *filep); +static int lcd_close(FAR struct file *filep); +static ssize_t lcd_read(FAR struct file *filep, FAR char *buffer, size_t buflen); +static ssize_t lcd_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* LCD POSIX interface */ +static const struct file_operations g_lcdfops = +{ + lcd_open, + lcd_close, + lcd_read, + lcd_write, + NULL, + NULL, + NULL +}; /**************************************************************************** * Public Functions ****************************************************************************/ @@ -184,23 +209,7 @@ void lcd_drv_init(void) Canvas_Image_Start_address(LCD_START_ADDR); //fill blue background - LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, Blue); -} - -/**************************************************************************** - * Name: k210_lcd_initialize - * - * Description: - * Initialize the LCD. Setup backlight (initially off) - * - ****************************************************************************/ - -int board_lcd_initialize(void) -{ - /* Configure the LCD backlight (and turn the backlight off) */ - lcd_backlight_init(true); - lcd_drv_init(); - return 0; + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); } /**************************************************************************** @@ -218,3 +227,127 @@ void k210_backlight(bool blon) lcd_backlight_init(blon); } #endif + + +/**************************************************************************** + * Name: lcd_open + ****************************************************************************/ +static int lcd_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: lcd_close + ****************************************************************************/ +static int lcd_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: lcd_read + ****************************************************************************/ +static ssize_t lcd_read(FAR struct file *filep, FAR char *buffer, size_t buflen) +{ + return OK; +} + +/**************************************************************************** + * Name: ch438_write + ****************************************************************************/ + static ssize_t lcd_write(FAR struct file *filep, FAR const char *buffer, size_t buflen) +{ + ssize_t ret = buflen; + if (buffer == NULL) + { + return -ERROR; + } + LcdWriteParam * show = (LcdWriteParam *)buffer; + + /* output string */ + switch (show->type) + { + + /* output string */ + case SHOW_STRING: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + LT768_Select_Internal_Font_Init(show->string_info.height, 1, 1, 1, 1); + LT768_Print_Internal_Font_String(show->string_info.x_pos, show->string_info.y_pos, show->string_info.font_color,show->string_info.back_color,show->string_info.addr); + break; + + /* output dot */ + case SHOW_WDOT: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + LT768_DrawSquare_Fill(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos, *(uint32_t *)(show->pixel_info.pixel_color)); + break; + + /* output rgb */ + case SHOW_RGB: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_RGB(); + break; + + /* output pip */ + case SHOW_PIP: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_PIP(); + break; + + /* output Internal Font */ + case SHOW_INTERNAL_FONT: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_Internal_Font(); + break; + + /* output Outside Font */ + case SHOW_OUTSIDE_FONT: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_Outside_Font(); + break; + + /* output Triangle */ + case SHOW_TRIANGLE: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_Triangle(); + break; + + /* output picture */ + case SHOW_PICTURE: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_Picture(); + break; + + default: + ret = -ERROR; + break; + } + + return ret; +} +/**************************************************************************** + * Name: k210_lcd_initialize + * + * Description: + * Initialize the LCD. Setup backlight (initially off) + * + ****************************************************************************/ +int board_lcd_initialize(void) +{ + /* Configure the LCD backlight (and turn the backlight off) */ + lcd_backlight_init(true); + lcd_drv_init(); + up_mdelay(10); + Main_Image_Start_Address(LCD_START_ADDR); + Main_Image_Width(LCD_XSIZE_TFT); + Main_Window_Start_XY(0, 0); + Canvas_Image_Start_address(LCD_START_ADDR); + Canvas_image_width(LCD_XSIZE_TFT); + Active_Window_XY(0, 0); + Active_Window_WH(LCD_XSIZE_TFT, LCD_YSIZE_TFT); + up_mdelay(10); + Canvas_Image_Start_address(LCD_START_ADDR); + /* register device */ + register_driver("/dev/lcd_dev", &g_lcdfops, 0666, NULL); + return OK; +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c index 5d255a6f4..c9cdfee0c 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c @@ -36,23 +36,12 @@ void board_autoled_initialize(void) { - k210_fpioa_config(BOARD_LED_PAD, BOARD_LED_IO_FUNC | K210_IOFLAG_GPIOHS); - k210_gpiohs_set_direction(BOARD_LED_IO, GPIO_DM_OUTPUT); - k210_gpiohs_set_value(BOARD_LED_IO, true); /* LED off */ } void board_autoled_on(int led) { - if (led == LED_PANIC) - { - k210_gpiohs_set_value(BOARD_LED_IO, false); - } } void board_autoled_off(int led) { - if (led == LED_PANIC) - { - k210_gpiohs_set_value(BOARD_LED_IO, true); - } } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c index 4649cf1d4..288de316c 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c @@ -24,6 +24,44 @@ ****************************************************************************/ #include "k210_touch.h" +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +static void IIC_Init(void); +static void SDA_IN(void); +static void SDA_OUT(void); +static uint8_t READ_SDA(void); +static void IIC_SCL(uint8_t val); +static void IIC_SDA(uint8_t val); +static void IIC_Start(void); +static void IIC_Stop(void); +static uint8_t IIC_Wait_Ack(void); +static void IIC_Ack(void); +static void IIC_NAck(void); +static void IIC_Send_Byte(uint8_t txd); +static uint8_t IIC_Read_Byte(uint8_t ack); +static bool GT911_Scan(POINT* point); + +static int touch_open(FAR struct file *filep); +static int touch_close(FAR struct file *filep); +static ssize_t touch_read(FAR struct file *filep, FAR char *buffer, size_t buflen); +static ssize_t touch_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* touch POSIX interface */ +static const struct file_operations g_touchfops = +{ + touch_open, + touch_close, + touch_read, + touch_write, + NULL, + NULL, + NULL +}; + /**************************************************************************** * Name: IIC_Init * Description: i2c pin mode configure @@ -31,7 +69,7 @@ * output: None * return:none ****************************************************************************/ -void IIC_Init(void) +static void IIC_Init(void) { /* config simluate IIC bus */ k210_fpioa_config(BSP_IIC_SDA, GT911_FUNC_GPIO(FPIOA_IIC_SDA)); @@ -48,7 +86,7 @@ void IIC_Init(void) * output: None * return:none ****************************************************************************/ -void SDA_IN(void) +static void SDA_IN(void) { k210_gpiohs_set_direction(FPIOA_IIC_SDA, GPIO_DM_INPUT_PULL_UP); } @@ -60,7 +98,7 @@ void SDA_IN(void) * output: None * return:none ****************************************************************************/ -void SDA_OUT(void) +static void SDA_OUT(void) { k210_gpiohs_set_direction(FPIOA_IIC_SDA, GPIO_DM_OUTPUT); } @@ -72,7 +110,7 @@ void SDA_OUT(void) * output: None * return: sda pin value ****************************************************************************/ -uint8_t READ_SDA(void) +static uint8_t READ_SDA(void) { return k210_gpiohs_get_value(FPIOA_IIC_SDA); } @@ -84,7 +122,7 @@ uint8_t READ_SDA(void) * output: None * return: None ****************************************************************************/ -void IIC_SCL(uint8_t val) +static void IIC_SCL(uint8_t val) { if (val) k210_gpiohs_set_value(FPIOA_IIC_SCL,GPIO_PV_HIGH); @@ -101,7 +139,7 @@ void IIC_SCL(uint8_t val) * output: None * return: None ****************************************************************************/ -void IIC_SDA(uint8_t val) +static void IIC_SDA(uint8_t val) { if (val) k210_gpiohs_set_value(FPIOA_IIC_SDA,GPIO_PV_HIGH); @@ -118,7 +156,7 @@ void IIC_SDA(uint8_t val) * output: None * return: None ****************************************************************************/ -void IIC_Start(void) +static void IIC_Start(void) { SDA_OUT(); IIC_SDA(1); @@ -136,7 +174,7 @@ void IIC_Start(void) * output: None * return: None ****************************************************************************/ -void IIC_Stop(void) +static void IIC_Stop(void) { SDA_OUT(); IIC_SCL(1); @@ -153,7 +191,7 @@ void IIC_Stop(void) * output: None * return: Return value: 1:failed to receive response,0:the received response is successful. ********************************************************************************************/ -uint8_t IIC_Wait_Ack(void) +static uint8_t IIC_Wait_Ack(void) { uint16_t ucErrTime=0; SDA_IN(); @@ -181,7 +219,7 @@ uint8_t IIC_Wait_Ack(void) * output: None * return: None ****************************************************************************/ -void IIC_Ack(void) +static void IIC_Ack(void) { IIC_SCL(0); SDA_OUT(); @@ -200,7 +238,7 @@ void IIC_Ack(void) * output: None * return: None ****************************************************************************/ -void IIC_NAck(void) +static void IIC_NAck(void) { IIC_SCL(0); SDA_OUT(); @@ -219,7 +257,7 @@ void IIC_NAck(void) * output: None * return: 1:there is a response,0:no response ****************************************************************************/ -void IIC_Send_Byte(uint8_t txd) +static void IIC_Send_Byte(uint8_t txd) { uint8_t t; SDA_OUT(); @@ -243,7 +281,7 @@ void IIC_Send_Byte(uint8_t txd) * output: None * return: Returns one byte of data read ****************************************************************************/ -uint8_t IIC_Read_Byte(uint8_t ack) +static uint8_t IIC_Read_Byte(uint8_t ack) { uint8_t i,receive=0; SDA_IN(); @@ -322,20 +360,6 @@ static void GT911_RD_Reg(uint16_t reg,uint8_t *buf,uint8_t len) IIC_Stop(); } -/*********************************************************************************** - * Name: GT911_ReadFirmwareVersion - * Description: Get firmware version number - * input: None - * output: None - * return: version number - ***********************************************************************************/ -static uint16_t GT911_ReadFirmwareVersion(void) -{ - uint8_t buf[2]; - GT911_RD_Reg(GT911_FIRMWARE_VERSION_REG, buf, 2); - return ((uint16_t)buf[1] << 8) + buf[0]; -} - /*********************************************************************************** * Name: GT911_Scan * Description: point:structure to store coordinates @@ -343,7 +367,7 @@ static uint16_t GT911_ReadFirmwareVersion(void) * output: None * return: Returns true for touch, false for no touch ***********************************************************************************/ -bool GT911_Scan(POINT* point) +static bool GT911_Scan(POINT* point) { GT911_Dev Dev_Now; uint8_t Clearbuf = 0; @@ -378,32 +402,74 @@ bool GT911_Scan(POINT* point) if(Dev_Now.Y[i] > GT911_MAX_HEIGHT -20) Dev_Now.Y[i]=GT911_MAX_HEIGHT - 20; if(Dev_Now.X[i] < 20) Dev_Now.X[i] = 20; if(Dev_Now.X[i] > GT911_MAX_WIDTH-20) Dev_Now.X[i] = GT911_MAX_WIDTH - 20; - point->X = Dev_Now.X[i]; - point->Y = Dev_Now.Y[i]; + point->x = Dev_Now.X[i]; + point->y = Dev_Now.Y[i]; } } return true; } +/**************************************************************************** + * Name: touch_open + ****************************************************************************/ +static int touch_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: touch_close + ****************************************************************************/ +static int touch_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: lcd_read + ****************************************************************************/ +static ssize_t touch_read(FAR struct file *filep, FAR char *buffer, size_t buflen) +{ + int ret = -ERROR; + POINT touch_point = {0, 0, 0}; + + if (buffer == NULL) + { + return -ERROR; + } + + POINT* data = (POINT*)buffer; + while(1) + { + if(GT911_Scan(&touch_point)) + { + data->x = touch_point.x; + data->y = touch_point.y; + ret = buflen; + break; + } + } + return ret; +} + +/**************************************************************************** + * Name: lcd_read + ****************************************************************************/ +static ssize_t touch_write(FAR struct file *filep, FAR const char *buffer, size_t buflen) +{ + return OK; +} + /*********************************************************************************** - * Name: GT911_test - * Description: gt911 test code + * Name: board_touch_initialize + * Description: touch initialize * input: None * output: None - * return: Returns true for touch, false for no touch + * return: None ***********************************************************************************/ -void GT911_test(void) +void board_touch_initialize(void) { - uint16_t res; - POINT point = {0, 0}; IIC_Init(); - res = GT911_ReadFirmwareVersion(); - printf("FirmwareVersion:%2x\n",res); - while(1) - { - if(GT911_Scan(&point)) - { - printf("Now touch point:(%d,%d)\n",point.X,point.Y); - } - } + /* register device */ + register_driver("/dev/touch_dev", &g_touchfops, 0666, NULL); } \ No newline at end of file diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.h index 26ad5ed32..0956f2fce 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.h @@ -63,26 +63,13 @@ typedef struct uint16_t S[CT_MAX_TOUCH]; }GT911_Dev; -typedef struct +typedef struct { - uint16_t X; - uint16_t Y; + uint16_t x; + uint16_t y; + uint16_t press; }POINT; -void IIC_Init(void); -void SDA_IN(void); -void SDA_OUT(void); -uint8_t READ_SDA(void); -void IIC_SCL(uint8_t val); -void IIC_SDA(uint8_t val); -void IIC_Start(void); -void IIC_Stop(void); -uint8_t IIC_Wait_Ack(void); -void IIC_Ack(void); -void IIC_NAck(void); -void IIC_Send_Byte(uint8_t txd); -uint8_t IIC_Read_Byte(uint8_t ack); -bool GT911_Scan(POINT* point); -void GT911_test(void); +void board_touch_initialize(void); #endif 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 fcffc9750..11a5d1fdc 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig @@ -667,6 +667,14 @@ config NSH_DISABLE_K210_FFT bool "Disable the K210 fft device." default n +config NSH_DISABLE_MUSL_TEST + bool "Disable the musl test." + default n + +config NSH_NSH_DISABLE_CAN_TEST + bool "Disable the can test." + default n + endmenu if MMCSD diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h index 918ba31a7..0e738d443 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h @@ -1587,6 +1587,13 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb, int cmd_fft(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif +#if defined(CONFIG_MUSL_LIBC) && !defined(CONFIG_NSH_DISABLE_MUSL_TEST) + int cmd_musl(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + +#if defined(CONFIG_BSP_USING_CAN) && !defined(CONFIG_NSH_DISABLE_CAN_TEST) + int cmd_cantest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif #if defined(__cplusplus) } #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c index 820d3360d..538de55d7 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c @@ -68,11 +68,11 @@ int cmd_w5500(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) * Name: cmd_Touch ****************************************************************************/ #if defined(CONFIG_BSP_USING_TOUCH) && !defined(CONFIG_NSH_DISABLE_TOUCH) -extern void GT911_test(void); +extern void TestTouch(void); int cmd_Touch(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { nsh_output(vtbl, "Hello, world!\n"); - GT911_test(); + TestTouch(); return OK; } #endif @@ -500,3 +500,23 @@ int cmd_fft(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) return OK; } #endif + +#if defined(CONFIG_MUSL_LIBC) && !defined(CONFIG_NSH_DISABLE_MUSL_TEST) +extern void Testmusl(void); +int cmd_musl(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, test musl!\n"); + Testmusl(); + return OK; +} +#endif + +#if defined(CONFIG_BSP_USING_CAN) && !defined(CONFIG_NSH_DISABLE_CAN_TEST) +extern void can_test(void); +int cmd_cantest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + can_test(); + return OK; +} +#endif \ No newline at end of file diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c index 1b03f5cc9..9366dce5b 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c @@ -732,6 +732,14 @@ static const struct cmdmap_s g_cmdmap[] = { "fft", cmd_fft, 1, 1, "[K210 fft function.]" }, #endif +#if defined(CONFIG_MUSL_LIBC) && !defined(CONFIG_NSH_DISABLE_MUSL_TEST) + { "testmusl", cmd_musl, 1, 1, "[test musl function.]" }, +#endif + +#if defined(CONFIG_BSP_USING_CAN) && !defined(CONFIG_NSH_DISABLE_CAN_TEST) + { "cantest", cmd_cantest, 1, 1, "[test can function.]" }, +#endif + { NULL, NULL, 1, 1, NULL } }; diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/mmu.c.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/boards/arm/hc32/.gitkeep old mode 100755 new mode 100644 similarity index 100% rename from Ubiquitous/XiZi_AIoT/hardkernel/abstraction/mmu.c.c rename to Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/boards/arm/hc32/.gitkeep diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/Make.defs b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/Make.defs index 392c7894d..77269bc02 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/Make.defs +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/Make.defs @@ -118,7 +118,7 @@ ifeq ($(CONFIG_LCD_ILI9341),y) endif ifeq ($(CONFIG_LCD_LT768),y) - CSRCS += lt768.c lt768_lib.c + CSRCS += lt768.c lt768_lib.c lt768_learn.c endif ifeq ($(CONFIG_LCD_LCDDRV_SPIIF),y) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/lt768.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/lt768.c index 6045def7d..ba6b2d64e 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/lt768.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/lt768.c @@ -6282,7 +6282,7 @@ uint8_t Read_Key_Strobe_Data_2(void) return temp; } -void Show_String(char *str) +void Show_String(uint8_t *str) { Text_Mode(); //text mode LCD_CmdWrite(0x04); diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/lt768_learn.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/lt768_learn.c new file mode 100644 index 000000000..390be1177 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/lt768_learn.c @@ -0,0 +1,545 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file lt768_learn.c + * @brief lt768_learn.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.9.19 + */ +#include +#include "nuttx/arch.h" +#include "nuttx/lcd/lt768_learn.h" + +const uint8_t g_Image_pen_il[256] = { /* 0X00,0X02,0X20,0X00,0X20,0X00, */ +0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +0X96,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X91,0X6A,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +0XA4,0X15,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XA4,0X00,0X6A,0XAA,0XAA,0XAA,0XAA,0XAA, +0XA9,0X01,0X1A,0XAA,0XAA,0XAA,0XAA,0XAA,0XA9,0X00,0X46,0XAA,0XAA,0XAA,0XAA,0XAA, +0XAA,0X40,0X51,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X90,0X14,0X6A,0XAA,0XAA,0XAA,0XAA, +0XAA,0XA4,0X05,0X1A,0XAA,0XAA,0XAA,0XAA,0XAA,0XA9,0X01,0X46,0XAA,0XAA,0XAA,0XAA, +0XAA,0XAA,0X40,0X51,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X90,0X14,0X6A,0XAA,0XAA,0XAA, +0XAA,0XAA,0XA4,0X05,0X1A,0XAA,0XAA,0XAA,0XAA,0XAA,0XA9,0X01,0X46,0XAA,0XAA,0XAA, +0XAA,0XAA,0XAA,0X40,0X51,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X90,0X14,0X69,0XAA,0XAA, +0XAA,0XAA,0XAA,0XA4,0X01,0X14,0X6A,0XAA,0XAA,0XAA,0XAA,0XA9,0X00,0X44,0X1A,0XAA, +0XAA,0XAA,0XAA,0XAA,0X40,0X11,0X06,0XAA,0XAA,0XAA,0XAA,0XAA,0X90,0X04,0X41,0XAA, +0XAA,0XAA,0XAA,0XAA,0XA4,0X01,0X10,0X6A,0XAA,0XAA,0XAA,0XAA,0XA9,0X00,0X44,0X1A, +0XAA,0XAA,0XAA,0XAA,0XAA,0X40,0X11,0X1A,0XAA,0XAA,0XAA,0XAA,0XAA,0X90,0X04,0X1A, +0XAA,0XAA,0XAA,0XAA,0XAA,0XA4,0X01,0X1A,0XAA,0XAA,0XAA,0XAA,0XAA,0XA9,0X00,0X1A, +0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X40,0X6A,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X95,0XAA, +0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +}; + +const uint8_t g_Image_arrow_il[256] = { /* 0X00,0X02,0X20,0X00,0X20,0X00, */ +0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X6A,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +0X5A,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X46,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +0X41,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X40,0X6A,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +0X40,0X1A,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X40,0X06,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +0X40,0X01,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X40,0X00,0X6A,0XAA,0XAA,0XAA,0XAA,0XAA, +0X40,0X00,0X1A,0XAA,0XAA,0XAA,0XAA,0XAA,0X40,0X00,0X06,0XAA,0XAA,0XAA,0XAA,0XAA, +0X40,0X00,0X01,0XAA,0XAA,0XAA,0XAA,0XAA,0X40,0X00,0X00,0X6A,0XAA,0XAA,0XAA,0XAA, +0X40,0X00,0X00,0X1A,0XAA,0XAA,0XAA,0XAA,0X40,0X00,0X00,0X06,0XAA,0XAA,0XAA,0XAA, +0X40,0X00,0X00,0X01,0XAA,0XAA,0XAA,0XAA,0X40,0X00,0X00,0X00,0X6A,0XAA,0XAA,0XAA, +0X40,0X00,0X15,0X55,0X5A,0XAA,0XAA,0XAA,0X40,0X10,0X1A,0XAA,0XAA,0XAA,0XAA,0XAA, +0X40,0X64,0X06,0XAA,0XAA,0XAA,0XAA,0XAA,0X41,0XA4,0X06,0XAA,0XAA,0XAA,0XAA,0XAA, +0X46,0XA9,0X01,0XAA,0XAA,0XAA,0XAA,0XAA,0X5A,0XA9,0X01,0XAA,0XAA,0XAA,0XAA,0XAA, +0X6A,0XAA,0X40,0X6A,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X40,0X6A,0XAA,0XAA,0XAA,0XAA, +0XAA,0XAA,0X90,0X1A,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X90,0X1A,0XAA,0XAA,0XAA,0XAA, +0XAA,0XAA,0XA4,0X06,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XA4,0X06,0XAA,0XAA,0XAA,0XAA, +0XAA,0XAA,0XA9,0X5A,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +}; + +const uint8_t g_Image_busy_im[256] = { /* 0X00,0X02,0X20,0X00,0X20,0X00, */ +0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X55,0X55,0X55,0X55,0X6A,0XAA, +0XAA,0XAA,0X54,0X00,0X00,0X05,0X6A,0XAA,0XAA,0XAA,0X55,0X55,0X55,0X55,0X6A,0XAA, +0XAA,0XAA,0X94,0X00,0X00,0X05,0XAA,0XAA,0XAA,0XAA,0X94,0X00,0X00,0X05,0XAA,0XAA, +0XAA,0XAA,0X94,0X44,0X44,0X45,0XAA,0XAA,0XAA,0XAA,0X94,0X11,0X11,0X05,0XAA,0XAA, +0XAA,0XAA,0X95,0X04,0X44,0X15,0XAA,0XAA,0XAA,0XAA,0XA5,0X41,0X10,0X56,0XAA,0XAA, +0XAA,0XAA,0XA9,0X50,0X41,0X5A,0XAA,0XAA,0XAA,0XAA,0XAA,0X54,0X05,0X6A,0XAA,0XAA, +0XAA,0XAA,0XAA,0X94,0X05,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X94,0X05,0XAA,0XAA,0XAA, +0XAA,0XAA,0XAA,0X94,0X45,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X94,0X05,0XAA,0XAA,0XAA, +0XAA,0XAA,0XAA,0X50,0X01,0X6A,0XAA,0XAA,0XAA,0XAA,0XA9,0X40,0X40,0X5A,0XAA,0XAA, +0XAA,0XAA,0XA5,0X00,0X10,0X16,0XAA,0XAA,0XAA,0XAA,0X94,0X00,0X00,0X05,0XAA,0XAA, +0XAA,0XAA,0X94,0X04,0X44,0X05,0XAA,0XAA,0XAA,0XAA,0X94,0X11,0X11,0X05,0XAA,0XAA, +0XAA,0XAA,0X94,0X44,0X44,0X45,0XAA,0XAA,0XAA,0XAA,0X95,0X11,0X11,0X15,0XAA,0XAA, +0XAA,0XAA,0X55,0X55,0X55,0X55,0X6A,0XAA,0XAA,0XAA,0X54,0X00,0X00,0X05,0X6A,0XAA, +0XAA,0XAA,0X55,0X55,0X55,0X55,0X6A,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +}; + +const uint8_t g_Image_no_im[256] = { /* 0X00,0X02,0X20,0X00,0X20,0X00, */ +0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0X95,0X55,0XAA,0XAA,0XAA, +0XAA,0XAA,0XA9,0X40,0X00,0X5A,0XAA,0XAA,0XAA,0XAA,0X94,0X00,0X00,0X05,0XAA,0XAA, +0XAA,0XAA,0X40,0X00,0X00,0X00,0X6A,0XAA,0XAA,0XA9,0X00,0X15,0X55,0X00,0X1A,0XAA, +0XAA,0XA4,0X00,0X6A,0XAA,0X50,0X06,0XAA,0XAA,0XA4,0X00,0X6A,0XAA,0XA4,0X06,0XAA, +0XAA,0X90,0X00,0X1A,0XAA,0XA9,0X01,0XAA,0XAA,0X90,0X10,0X06,0XAA,0XA9,0X01,0XAA, +0XAA,0X40,0X64,0X01,0XAA,0XAA,0X40,0X6A,0XAA,0X40,0X69,0X00,0X6A,0XAA,0X40,0X6A, +0XAA,0X40,0X6A,0X40,0X1A,0XAA,0X40,0X6A,0XAA,0X40,0X6A,0X90,0X06,0XAA,0X40,0X6A, +0XAA,0X40,0X6A,0XA4,0X01,0XAA,0X40,0X6A,0XAA,0X40,0X6A,0XA9,0X00,0X6A,0X40,0X6A, +0XAA,0X40,0X6A,0XAA,0X40,0X1A,0X40,0X6A,0XAA,0X90,0X1A,0XAA,0X90,0X05,0X01,0XAA, +0XAA,0X90,0X1A,0XAA,0XA4,0X00,0X01,0XAA,0XAA,0XA4,0X06,0XAA,0XA9,0X00,0X06,0XAA, +0XAA,0XA4,0X01,0X6A,0XAA,0X40,0X06,0XAA,0XAA,0XA9,0X00,0X15,0X55,0X00,0X1A,0XAA, +0XAA,0XAA,0X40,0X00,0X00,0X00,0X6A,0XAA,0XAA,0XAA,0X94,0X00,0X00,0X05,0XAA,0XAA, +0XAA,0XAA,0XA9,0X40,0X00,0X5A,0XAA,0XAA,0XAA,0XAA,0XAA,0X95,0X55,0XAA,0XAA,0XAA, +0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA,0XAA, +}; + + +void Display_RGB(void) +{ + Select_Main_Window_16bpp(); + Main_Image_Start_Address(0); + Main_Image_Width(LCD_XSIZE_TFT); + Main_Window_Start_XY(0,0); + Canvas_Image_Start_address(0); + Canvas_image_width(LCD_XSIZE_TFT); + Active_Window_XY(0,0); + Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT); + + while(1) + { + BTE_Solid_Fill(0,LCD_XSIZE_TFT,0,0,RED,LCD_XSIZE_TFT,LCD_YSIZE_TFT); + up_mdelay(500); + BTE_Solid_Fill(0,LCD_XSIZE_TFT,0,0,GREEN,LCD_XSIZE_TFT,LCD_YSIZE_TFT); + up_mdelay(500); + BTE_Solid_Fill(0,LCD_XSIZE_TFT,0,0,BLUE,LCD_XSIZE_TFT,LCD_YSIZE_TFT); + up_mdelay(500); + } +} + +#define Picture_1_Addr 0 +#define Picture_2_Addr (LCD_XSIZE_TFT*LCD_YSIZE_TFT*2) +#define Picture_3_Addr (LCD_XSIZE_TFT*LCD_YSIZE_TFT*4) +#define Picture_4_Addr (LCD_XSIZE_TFT*LCD_YSIZE_TFT*6) + +void Display_Picture(void) +{ + uint8_t i = 0; + + Select_Main_Window_16bpp(); + Main_Image_Start_Address(0); + Main_Image_Width(LCD_XSIZE_TFT); + Main_Window_Start_XY(0,0); + Canvas_Image_Start_address(0); + Canvas_image_width(LCD_XSIZE_TFT); + Active_Window_XY(0,0); + Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT); + + while(1) + { + for(i = 0;i < 4;i++) + { + switch(i) + { + case 0:LT768_DMA_24bit_Block(1,0,0,0,LCD_XSIZE_TFT,LCD_YSIZE_TFT,LCD_XSIZE_TFT,Picture_1_Addr);break; + case 1:LT768_DMA_24bit_Block(1,0,0,0,LCD_XSIZE_TFT,LCD_YSIZE_TFT,LCD_XSIZE_TFT,Picture_2_Addr);break; + case 2:LT768_DMA_24bit_Block(1,0,0,0,LCD_XSIZE_TFT,LCD_YSIZE_TFT,LCD_XSIZE_TFT,Picture_3_Addr);break; + case 3:LT768_DMA_24bit_Block(1,0,0,0,LCD_XSIZE_TFT,LCD_YSIZE_TFT,LCD_XSIZE_TFT,Picture_4_Addr);break; + default: break; + } + up_mdelay(500); + } + } +} + + +void Display_PIP(void) +{ + unsigned int i; + + Select_Main_Window_16bpp(); + Main_Image_Start_Address(0); + Main_Image_Width(LCD_XSIZE_TFT); + Main_Window_Start_XY(0,0); + Canvas_Image_Start_address(0); + Canvas_image_width(LCD_XSIZE_TFT); + Active_Window_XY(0,0); + Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT); + + BTE_Solid_Fill(0,LCD_XSIZE_TFT,0,0,BLUE2,LCD_XSIZE_TFT,LCD_YSIZE_TFT); // 底图颜色 + BTE_Solid_Fill(LCD_XSIZE_TFT*LCD_YSIZE_TFT*2,LCD_XSIZE_TFT,0,0,RED,LCD_XSIZE_TFT,LCD_YSIZE_TFT); // PIP1颜色 + BTE_Solid_Fill(LCD_XSIZE_TFT*LCD_YSIZE_TFT*4,LCD_XSIZE_TFT,0,0,GREEN,LCD_XSIZE_TFT,LCD_YSIZE_TFT); // PIP2颜色 + + LT768_PIP_Init(1,1,LCD_XSIZE_TFT*LCD_YSIZE_TFT*2,250,250,1024,0,175,250,250); // 初始化PIP1 + LT768_PIP_Init(1,2,LCD_XSIZE_TFT*LCD_YSIZE_TFT*4,300,300,1024,774,150,300,300); // 初始化PIP2 + + while(1) + { + for(i=0;i<550;i=i+2) + { + LT768_Set_DisWindowPos(1,1,i,175); + LT768_Set_DisWindowPos(1,2,734-i,150); + up_mdelay(5); + } + + for(i=0;i<550;i=i+2) + { + LT768_Set_DisWindowPos(1,1,550-i,175); + LT768_Set_DisWindowPos(1,2,734-550+i,150); + up_mdelay(5); + } + } +} + +void Display_Internal_Font(void) +{ + char c[2] = "0"; + unsigned int i = 0; + unsigned int x = 0; + unsigned int y = 0; + unsigned int z = 0; + + Select_Main_Window_16bpp(); + Main_Image_Start_Address(0); + Main_Image_Width(LCD_XSIZE_TFT); + Main_Window_Start_XY(0,0); + Canvas_Image_Start_address(0); + Canvas_image_width(LCD_XSIZE_TFT); + Active_Window_XY(0,0); + Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT); + + while(1) + { + LT768_DrawSquare_Fill(0,0,LCD_XSIZE_TFT,LCD_YSIZE_TFT,BLUE2); + + LT768_Select_Internal_Font_Init(16,1,1,0,0); + LT768_Print_Internal_Font_String(0,10,BLACK,BLUE2,"Embedded 8x16 ASCII Character"); + + LT768_Select_Internal_Font_Init(24,1,1,0,0); + LT768_Print_Internal_Font_String(0,30,BLUE,BLUE2,"Embedded 12x24 ASCII Character"); + + LT768_Select_Internal_Font_Init(32,1,1,0,0); + LT768_Print_Internal_Font_String(0,55,GREEN,BLUE2,"Embedded 16x32 ASCII Character"); + + LT768_Print_Internal_Font_String(0,95,RED,BLUE2,"The Text Cursor"); + + for(i = 0 ; i < 14 ; i++) + { + up_mdelay(100); + LT768_Text_cursor_Init(1,15,1+i,15-i); + } + up_mdelay(100); + LT768_Text_cursor_Init(1,15,10,2); + + + c[0] = '0'; + for(i = 0 ; i < 10 ; i++) + { + up_mdelay(50); + LT768_Print_Internal_Font_String(10+16*i,135,RED,BLUE2,&c[0]); + c[0]++; + } + + c[0] = 0; + x = 0; + y = 175; + z = 0; + for(i = 0 ; i < 127 ; i++) + { + up_mdelay(50); + x = z * 16; + z++; + if(x>1024) + { + y = y + 40; + x = 0; + z = 0; + } + + LT768_Print_Internal_Font_String(x,y,RED,BLUE2,&c[0]); + c[0]++; + } + + up_mdelay(1000); + up_mdelay(1000); + + + LT768_DMA_24bit_Block(1,0,200,300,600,280,1024,Picture_3_Addr); + + LT768_Graphic_cursor_Init(1,0xff,0x00,0,0,(uint8_t*)g_Image_pen_il); + LT768_Graphic_cursor_Init(2,0xff,0x00,0,0,(uint8_t*)g_Image_arrow_il); + LT768_Graphic_cursor_Init(3,0xff,0x00,0,0,(uint8_t*)g_Image_busy_im); + LT768_Graphic_cursor_Init(4,0xff,0x00,0,0,(uint8_t*)g_Image_no_im); + + + LT768_Set_Graphic_cursor_Pos(1,100,300); + up_mdelay(500); + LT768_Set_Graphic_cursor_Pos(2,100,300); + up_mdelay(500); + LT768_Set_Graphic_cursor_Pos(3,100,300); + up_mdelay(500); + LT768_Set_Graphic_cursor_Pos(4,100,300); + up_mdelay(500); + LT768_Set_Graphic_cursor_Pos(1,100,300); + + for(i = 100 ; i < 924 ; i++) + { + LT768_Set_Graphic_cursor_Pos(1,i,90); + up_mdelay(2); + } + + for(i = 200 ; i < 800 ; i++) + { + LT768_Set_Graphic_cursor_Pos(2,i,i-200); + up_mdelay(2); + } + + for(i = 800 ; i > 100 ; i--) + { + LT768_Set_Graphic_cursor_Pos(3,i,800-i); + up_mdelay(2); + } + + for(i = 924 ; i > 100 ; i--) + { + LT768_Set_Graphic_cursor_Pos(4,i,400); + up_mdelay(2); + } + + up_mdelay(1000); + up_mdelay(1000); + + LT768_Disable_Text_Cursor(); + LT768_Disable_Graphic_Cursor(); + } +} + + + +#define MEMORY_ADDR_16 0x003E0D760 +#define MEMORY_ADDR_24 0x003E537E0 +#define MEMORY_ADDR_32 0x003EEBD00 + +#define FLASH_ADDR_16 0x00829150 +#define FLASH_ADDR_24 0x0078DC20 +#define FLASH_ADDR_32 0x00679A10 + +#define SIZE_16_NUM 0x00045080 +#define SIZE_24_NUM 0x0009B520 +#define SIZE_32_NUM 0x00114200 + +void Display_Outside_Font(void) +{ + Select_Main_Window_16bpp(); + Main_Image_Start_Address(0); + Main_Image_Width(LCD_XSIZE_TFT); + Main_Window_Start_XY(0,0); + Canvas_Image_Start_address(0); + Canvas_image_width(LCD_XSIZE_TFT); + Active_Window_XY(0,0); + Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT); + + while(1) + { + LT768_DrawSquare_Fill(0,0,LCD_XSIZE_TFT,LCD_YSIZE_TFT,WHITE); + LT768_Select_Outside_Font_Init(1,0,FLASH_ADDR_16,MEMORY_ADDR_16,SIZE_16_NUM,16,1,1,0,0); + LT768_Print_Outside_Font_String(425,50,RED,WHITE,(uint8_t*)"16X16微软雅黑字体"); + up_mdelay(500); + Font_Width_X2(); + Font_Height_X2(); + LT768_Print_Outside_Font_String(250,75,GREY-1200,WHITE,(uint8_t*)"16X16微软雅黑字体长宽各扩1倍"); + up_mdelay(500); + Font_Width_X3(); + Font_Height_X3(); + LT768_Print_Outside_Font_String(150,120,BLUE,WHITE,(uint8_t*)"16X16微软雅黑字体长宽各扩2倍"); + up_mdelay(500); + Font_Width_X4(); + Font_Height_X4(); + LT768_Print_Outside_Font_String(60,178,MAGENTA,WHITE,(uint8_t*)"16X16微软雅黑字体长宽各扩3倍"); + up_mdelay(500); + + LT768_Select_Outside_Font_Init(1,0,FLASH_ADDR_24,MEMORY_ADDR_24,SIZE_24_NUM,24,1,1,0,0); + LT768_Print_Outside_Font_String(445,280,RED,WHITE,(uint8_t*)"24X24楷体"); + up_mdelay(500); + Font_Width_X2(); + Font_Height_X2(); + LT768_Print_Outside_Font_String(260,315,GREEN,WHITE,(uint8_t*)"24X24楷体长宽各扩1倍"); + up_mdelay(500); + Font_Width_X3(); + Font_Height_X3(); + LT768_Print_Outside_Font_String(150,375,CYAN,WHITE,(uint8_t*)"24X24楷体长宽各扩2倍"); + up_mdelay(500); + Font_Width_X4(); + Font_Height_X4(); + LT768_Print_Outside_Font_String(30,455,YELLOW,WHITE,(uint8_t*)"24X24楷体长宽各扩3倍"); + up_mdelay(500); + + LT768_Select_Outside_Font_Init(1,0,FLASH_ADDR_32,MEMORY_ADDR_32,SIZE_32_NUM,32,1,1,0,0); + LT768_DrawSquare_Fill(0,0,LCD_XSIZE_TFT,LCD_YSIZE_TFT,WHITE); + LT768_Print_Outside_Font_String(430,105,RED,WHITE,(uint8_t*)"32X32隶书"); + up_mdelay(500); + Font_Width_X2(); + Font_Height_X2(); + LT768_Print_Outside_Font_String(360,165,GREEN,WHITE,(uint8_t*)"32X32隶书"); + up_mdelay(500); + Font_Width_X3(); + Font_Height_X3(); + LT768_Print_Outside_Font_String(285,250,BLUE,WHITE,(uint8_t*)"32X32隶书"); + up_mdelay(500); + Font_Width_X4(); + Font_Height_X4(); + LT768_Print_Outside_Font_String(220,360,YELLOW,WHITE,(uint8_t*)"32X32隶书"); + up_mdelay(500); + } +} + +void Display_Triangle(void) +{ + unsigned long i,j,h; + unsigned long resx1,resy1,resx2,resy2,resx3,resy3; + + Select_Main_Window_16bpp(); + Main_Image_Start_Address(0); + Main_Image_Width(LCD_XSIZE_TFT); + Canvas_Image_Start_address(0); + Canvas_image_width(LCD_XSIZE_TFT); + Active_Window_XY(0,0); + Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT); + + Main_Window_Start_XY(0,0); + + while(1) + { + LT768_DrawSquare_Fill(0,0,LCD_XSIZE_TFT,LCD_YSIZE_TFT,WHITE); + h=0; + do + { + resx1=rand()%LCD_XSIZE_TFT; // 点1的x轴 + resy1=rand()%(LCD_YSIZE_TFT); // 点1的y轴 + resx2=rand()%LCD_XSIZE_TFT; // 点2的x轴 + resy2=rand()%(LCD_YSIZE_TFT); // 点2的y轴 + resx3=rand()%LCD_XSIZE_TFT; // 点3的x轴 + resy3=rand()%(LCD_YSIZE_TFT); // 点3的y轴 + i=rand()%65536; // 颜色 + j=rand()%3; + if(j) LT768_DrawTriangle(resx1,resy1,resx2,resy2,resx3,resy3,i); // 无填充色三角形 + else LT768_DrawTriangle_Fill(resx1,resy1,resx2,resy2,resx3,resy3,i); // 填充色三角形 + h++; + up_mdelay(120); + } + while(h<20); + + h=0; + do + { + resx1=rand()%LCD_XSIZE_TFT; // 点1的x轴 + resy1=rand()%(LCD_YSIZE_TFT); // 点1的y轴 + resx2=rand()%LCD_XSIZE_TFT; // 点2的x轴 + resy2=rand()%(LCD_YSIZE_TFT); // 点2的y轴 + resx3=rand()%LCD_XSIZE_TFT; // 点3的x轴 + resy3=rand()%(LCD_YSIZE_TFT); // 点3的y轴 + i=rand()%65536; // 颜色 + j=rand()%3; + if(j) LT768_DrawTriangle(resx1,resy1,resx2,resy2,resx3,resy3,i); // 无填充色三角形 + else LT768_DrawTriangle_Fill(resx1,resy1,resx2,resy2,resx3,resy3,i); // 填充色三角形 + h++; + up_mdelay(1); + } + while(h<2500); + + } +} + +void Tsst(void) +{ + unsigned long i,j,h; + unsigned long resx1,resy1,resx2,resy2,resx3,resy3; + + Select_Main_Window_16bpp(); + Main_Image_Start_Address(0); + Main_Image_Width(LCD_XSIZE_TFT); + Main_Window_Start_XY(0,0); + Canvas_Image_Start_address(0); + Canvas_image_width(LCD_XSIZE_TFT); + Active_Window_XY(0,0); + Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT); + + while(1) + { + + BTE_Solid_Fill(0,LCD_XSIZE_TFT,0,0,RED,LCD_XSIZE_TFT,LCD_YSIZE_TFT); + up_mdelay(600); + BTE_Solid_Fill(0,LCD_XSIZE_TFT,0,0,GREEN,LCD_XSIZE_TFT,LCD_YSIZE_TFT); + up_mdelay(600); + BTE_Solid_Fill(0,LCD_XSIZE_TFT,0,0,BLUE,LCD_XSIZE_TFT,LCD_YSIZE_TFT); + up_mdelay(600); + + BTE_Solid_Fill(LCD_XSIZE_TFT*LCD_YSIZE_TFT*2,LCD_XSIZE_TFT,0,0,RED,LCD_XSIZE_TFT,LCD_YSIZE_TFT); // PIP1颜色 + BTE_Solid_Fill(LCD_XSIZE_TFT*LCD_YSIZE_TFT*4,LCD_XSIZE_TFT,0,0,GREEN,LCD_XSIZE_TFT,LCD_YSIZE_TFT); // PIP2颜色 + LT768_PIP_Init(1,1,LCD_XSIZE_TFT*LCD_YSIZE_TFT*2,0,0,LCD_XSIZE_TFT,0,100,50,50); // 初始化PIP1 + LT768_PIP_Init(1,2,LCD_XSIZE_TFT*LCD_YSIZE_TFT*4,0,0,LCD_XSIZE_TFT,430,85,80,80); // 初始化PIP2 + + for(i=0;i<300;i=i+4) + { + LT768_Set_DisWindowPos(1,1,i,100); + LT768_Set_DisWindowPos(1,2,430-i,85); + up_mdelay(15); + } + + for(i=0;i<300;i=i+2) + { + LT768_Set_DisWindowPos(1,1,300-i,100); + LT768_Set_DisWindowPos(1,2,430-300+i,85); + up_mdelay(10); + } + Disable_PIP1(); + Disable_PIP2(); + + + LT768_DrawSquare_Fill(0,0,LCD_XSIZE_TFT,LCD_YSIZE_TFT,WHITE); + h=0; + do + { + resx1=rand()%LCD_XSIZE_TFT; // 点1的x轴 + resy1=rand()%(LCD_YSIZE_TFT); // 点1的y轴 + resx2=rand()%LCD_XSIZE_TFT; // 点2的x轴 + resy2=rand()%(LCD_YSIZE_TFT); // 点2的y轴 + resx3=rand()%LCD_XSIZE_TFT; // 点3的x轴 + resy3=rand()%(LCD_YSIZE_TFT); // 点3的y轴 + i=rand()%65536; // 颜色 + j=rand()%3; + if(j) LT768_DrawTriangle(resx1,resy1,resx2,resy2,resx3,resy3,i); // 无填充色三角形 + else LT768_DrawTriangle_Fill(resx1,resy1,resx2,resy2,resx3,resy3,i); // 填充色三角形 + h++; + up_mdelay(120); + } + while(h<20); + + h=0; + do + { + resx1=rand()%LCD_XSIZE_TFT; // 点1的x轴 + resy1=rand()%(LCD_YSIZE_TFT); // 点1的y轴 + resx2=rand()%LCD_XSIZE_TFT; // 点2的x轴 + resy2=rand()%(LCD_YSIZE_TFT); // 点2的y轴 + resx3=rand()%LCD_XSIZE_TFT; // 点3的x轴 + resy3=rand()%(LCD_YSIZE_TFT); // 点3的y轴 + i=rand()%65536; // 颜色 + j=rand()%3; + if(j) LT768_DrawTriangle(resx1,resy1,resx2,resy2,resx3,resy3,i); // 无填充色三角形 + else LT768_DrawTriangle_Fill(resx1,resy1,resx2,resy2,resx3,resy3,i); // 填充色三角形 + h++; + up_mdelay(1); + } + while(h<2500); + + up_mdelay(100); + } +} + + + + diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/lt768_lib.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/lt768_lib.c index 63059405b..adb9d3b14 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/lt768_lib.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/drivers/lcd/lt768_lib.c @@ -303,7 +303,7 @@ void MPU8_24bpp_Memory_Write -void MPuint16_t_16bpp_Memory_Write +void MPU16_16bpp_Memory_Write ( uint16_t x , uint16_t y @@ -332,7 +332,7 @@ void MPuint16_t_16bpp_Memory_Write Check_Mem_WR_FIFO_Empty(); } -void MPuint16_t_24bpp_Mode1_Memory_Write +void MPU16_24bpp_Mode1_Memory_Write ( uint16_t x , uint16_t y @@ -368,7 +368,7 @@ void MPuint16_t_24bpp_Mode1_Memory_Write } -void MPuint16_t_24bpp_Mode2_Memory_Write +void MPU16_24bpp_Mode2_Memory_Write ( uint16_t x , uint16_t y @@ -1388,7 +1388,7 @@ void LT768_Print_Internal_Font_String , uint16_t y // font start y , uint32_t FontColor // font color , uint32_t BackGroundColor // font background color(when font background is transparent, it is invalid) - , char *c // data start address + , uint8_t *c // data start address ) { Text_Mode(); diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/lcd/lt768.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/lcd/lt768.h index f60fdf799..2bbd8d8fd 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/lcd/lt768.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/lcd/lt768.h @@ -21,6 +21,46 @@ #ifndef __LT768_H_ #define __LT768_H_ +typedef enum _LcdOperation +{ + SHOW_STRING = 0, + SHOW_WDOT, + SHOW_RGB, + SHOW_PIP, + SHOW_INTERNAL_FONT, + SHOW_OUTSIDE_FONT, + SHOW_TRIANGLE, + SHOW_PICTURE, +} LcdOperation; + +typedef struct +{ + uint16_t x_pos; + uint16_t y_pos; + uint16_t width; + uint16_t height; + uint8_t font_size; + uint8_t *addr; + uint16_t font_color; + uint16_t back_color; +}LcdStringParam; + +typedef struct +{ + uint16_t x_startpos; + uint16_t x_endpos; + uint16_t y_startpos; + uint16_t y_endpos; + void* pixel_color; +}LcdPixelParam; + +typedef struct +{ + LcdOperation type; + LcdPixelParam pixel_info; + LcdStringParam string_info; +}LcdWriteParam; + #define cSetb0 0x01 #define cSetb1 0x02 #define cSetb2 0x04 @@ -691,7 +731,7 @@ uint8_t Read_Key_Strobe_Data_0(void); uint8_t Read_Key_Strobe_Data_1(void); uint8_t Read_Key_Strobe_Data_2(void); -void Show_String(char *str); +void Show_String(uint8_t *str); void Show_picture(uint32_t numbers, const uint16_t *data); void PWM0_ON(void); //PWM0 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/lcd/lt768_learn.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/lcd/lt768_learn.h new file mode 100644 index 000000000..e4a4b1ffd --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/lcd/lt768_learn.h @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file lt768.h + * @brief lt768 register relative driver, inherit from Levetop Electronics + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.9.19 + */ + +#ifndef _LT768_LEARN_H +#define _LT768_LEARN_H +#include "nuttx/lcd/if_port.h" +#include + +void Display_RGB(void); +void Display_Picture(void); +void Display_PIP(void); +void Display_Internal_Font(void); +void Display_Outside_Font(void); +void Display_Triangle(void); +void Tsst(void); + +#endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/lcd/lt768_lib.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/lcd/lt768_lib.h index 345eb2e58..187b88f1c 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/lcd/lt768_lib.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/include/nuttx/lcd/lt768_lib.h @@ -99,16 +99,31 @@ #define color16M_purple color16M_red|color16M_blue /* LCD color */ -#define White 0xFFFF -#define Black 0x0000 -#define Grey 0xF7DE -#define Blue 0x001F -#define Blue2 0x051F -#define Red 0xF800 -#define Magenta 0xF81F -#define Green 0x07E0 -#define Cyan 0x7FFF -#define Yellow 0xFFE0 +#define WHITE 0xFFFF +#define BLACK 0x0000 +#define BLUE 0x001F +#define GREY 0xF7DE +#define BRED 0xF81F +#define GRED 0xFFE0 +#define GBLUE 0x07FF +#define BLUE2 0x051F +#define RED 0xF800 +#define MAGENTA 0xF81F +#define GREEN 0x07E0 +#define CYAN 0x7FFF +#define YELLOW 0xFFE0 +#define BROWN 0xBC40 +#define BRRED 0xFC07 +#define GRAY 0x8430 + +#define DARKBLUE 0x01CF +#define LIGHTBLUE 0x7D7C +#define GRAYBLUE 0x5458 +#define LIGHTGREEN 0x841F +#define LGRAY 0xC618 +#define LGRAYBLUE 0xA651 +#define LBBLUE 0x2B12 + #define Line0 0 #define Line1 24 @@ -140,32 +155,32 @@ void lt768_init(void); /* write to memory */ -void MPuint8_t_8bpp_Memory_Write(uint16_t x, +void MPU8_8bpp_Memory_Write(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint8_t *data); -void MPuint8_t_16bpp_Memory_Write(uint16_t x, +void MPU8_16bpp_Memory_Write(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint8_t *data); -void MPuint8_t_24bpp_Memory_Write(uint16_t x, +void MPU8_24bpp_Memory_Write(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint8_t *data); -void MPuint16_t_16bpp_Memory_Write(uint16_t x, +void MPU16_16bpp_Memory_Write(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint16_t *data); -void MPuint16_t_24bpp_Mode1_Memory_Write(uint16_t x, +void MPU16_24bpp_Mode1_Memory_Write(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint16_t *data); -void MPuint16_t_24bpp_Mode2_Memory_Write(uint16_t x, +void MPU16_24bpp_Mode2_Memory_Write(uint16_t x, uint16_t y, uint16_t w, uint16_t h, @@ -474,7 +489,7 @@ void LT768_Print_Internal_Font_String(uint16_t x, uint16_t y, uint32_t FontColor, uint32_t BackGroundColor, - char *c); + uint8_t *c); /* nor flash use outside font */ /* 16*16 24*24 32*32 */ diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c index e69de29bb..5af33edcf 100755 --- a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c @@ -0,0 +1,16 @@ + + +void InvalidInsCache() +{ + PlatInvalidInsCache(); +} + +void InvalidDataCache(unsigned long start, unsigned long end) +{ + PlatInvalidDateCache(start, end); +} + +void CleanDataCache(unsigned long start, unsigned long end) +{ + PlatCleanDateCache(start, end); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/mmu.c b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/mmu.c new file mode 100755 index 000000000..e69de29bb diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/cache.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/cache.S new file mode 100644 index 000000000..e69de29bb diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/exception.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a7/exception.S new file mode 100644 index 000000000..e69de29bb diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/cache.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/cache.S new file mode 100644 index 000000000..e69de29bb diff --git a/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/hc32f4a0/boot.S b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/hc32f4a0/boot.S index c70e3a195..08860b4e2 100644 --- a/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/hc32f4a0/boot.S +++ b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/hc32f4a0/boot.S @@ -48,7 +48,7 @@ Modification: ; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> ; */ - .equ Stack_Size, 0x00002000 + .equ Stack_Size, 0x00004000 .section .stack .align 3 @@ -60,26 +60,6 @@ __StackLimit: __StackTop: .size __StackTop, . - __StackTop - -/* -; Heap Configuration -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; -*/ - .equ Heap_Size, 0x00002000 - - .if Heap_Size != 0 /* Heap is provided */ - .section .heap - .align 3 - .globl __HeapBase - .globl __HeapLimit -__HeapBase: - .space Heap_Size - .size __HeapBase, . - __HeapBase -__HeapLimit: - .size __HeapLimit, . - __HeapLimit - .endif - /* ; Reset handler start. */ diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/Kconfig b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/Kconfig index acd352867..56757c3a3 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/Kconfig @@ -35,9 +35,11 @@ menu "aiit-arm32-board feature" menu "config board peripheral" config MOUNT_SDCARD - bool "mount cd card" + bool + default n + config MOUNT_USB + bool default n - select BSP_USING_SDIO endmenu endmenu endmenu diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/board.c b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/board.c index 7a4460487..cb386904b 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/board.c +++ b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/board.c @@ -51,6 +51,7 @@ extern int HwSramInit(void); extern int Stm32HwAdcInit(void); extern int Stm32HwDacInit(void); extern int Stm32HwLcdInit(void); +extern int Stm32HwUsbInit(void); static void ClockConfiguration() { @@ -147,6 +148,11 @@ struct InitSequenceDesc _board_init[] = #ifdef BSP_USING_SDIO {"hw sdcard init",HwSdioInit}, #endif +#ifdef BSP_USING_USB +#ifdef BSP_USING_STM32_USBH + { "hw usb", Stm32HwUsbInit }, +#endif +#endif #ifdef BSP_USING_EXTMEM { "hw extern sram", HwSramInit }, #endif diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/connect_lora_spi.c b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/connect_lora_spi.c index ec61b30b4..76cdb61db 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/connect_lora_spi.c +++ b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/connect_lora_spi.c @@ -396,7 +396,7 @@ static const struct LoraDevDone lora_done = * @param bus_name spi bus name * @param dev_name spi dev name * @param drv_name spi drv name - * @param flash_name flash dev name + * @param lora_name lora name */ SpiLoraDeviceType SpiLoraInit(char *bus_name, char *dev_name, char *drv_name, char *lora_name) { @@ -493,7 +493,7 @@ int LoraSx12xxSpiDeviceInit(void) return EOK; } -//#define LORA_TEST +#define LORA_TEST #ifdef LORA_TEST /*Just for lora test*/ static struct Bus *bus; @@ -504,11 +504,11 @@ void LoraOpen(void) { x_err_t ret = EOK; - ret = LoraSx12xxSpiDeviceInit(); - if (EOK != ret) { - KPrintf("LoraSx12xxSpiDeviceInit failed\n"); - return; - } + // ret = LoraSx12xxSpiDeviceInit(); + // if (EOK != ret) { + // KPrintf("LoraSx12xxSpiDeviceInit failed\n"); + // return; + // } bus = BusFind(SPI_BUS_NAME_2); dev = BusFindDevice(bus, SX12XX_DEVICE_NAME); diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/connect_spi.c index 813a46a64..029d7744d 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/connect_spi.c +++ b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/connect_spi.c @@ -103,7 +103,7 @@ static x_err_t Stm32SpiInit(struct Stm32Spi *SpiDrv, struct SpiMasterParam *cfg) SPI_InitTypeDef *SpiInit = &SpiDrv->init; - if (cfg->spi_work_mode & DEV_SPI_SLAVE) + if (cfg->spi_work_mode & SPI_DEV_SLAVE) { SpiInit->SPI_Mode = SPI_Mode_Slave; } diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/third_party_spi_lora/src/radio/sx1276-LoRa.c b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/third_party_spi_lora/src/radio/sx1276-LoRa.c index f8645b09f..8de3686b4 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/third_party_spi_lora/src/radio/sx1276-LoRa.c +++ b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/spi/third_party_spi_lora/src/radio/sx1276-LoRa.c @@ -784,12 +784,12 @@ uint32_t SX1276LoraChannelEmpty( void ) if(result == RF_CHANNEL_EMPTY) { - KPrintf("\nLora--信道可用(RF_CHANNEL_EMPTY)\n"); + KPrintf("\nLora--RF_CHANNEL_EMPTY\n"); return 0; } else if(result == RF_CHANNEL_ACTIVITY_DETECTED) { - KPrintf("\nLora--信道正被占用(RF_CHANNEL_ACTIVITY_DETECTED)\n"); + KPrintf("\nLora--RF_CHANNEL_ACTIVITY_DETECTED\n"); return 1; } else diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/usb/Kconfig b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/usb/Kconfig index 4fcd37871..93fdfd6f4 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/usb/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/usb/Kconfig @@ -1,6 +1,6 @@ config BSP_USING_STM32_USBH bool "Using usb host" - default y + default n if BSP_USING_STM32_USBH config USB_BUS_NAME string "usb bus name" @@ -11,5 +11,15 @@ config BSP_USING_STM32_USBH config USB_DEVICE_NAME string "usb bus device name" default "usb_dev" + config MOUNT_USB_FS + bool "mount usb file system" + default y + select MOUNT_USB + + if MOUNT_USB_FS + config MOUNT_USB_FS_TYPE + int "choose file system type : FATFS(0) LWEXT4(3)" + default 0 + endif endif diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/usb/connect_usb.c b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/usb/connect_usb.c index 64b5668ea..52934f7db 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/usb/connect_usb.c +++ b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/usb/connect_usb.c @@ -25,6 +25,14 @@ uint32 UdiskRead_new_api(void *dev, struct BusBlockReadParam *read_param); uint32 UdiskWirte_new_api(void *dev, struct BusBlockWriteParam *write_param); +#ifdef MOUNT_USB +int MountUsb(void) +{ + STM32USBHostRegister(); + return 0; +} +#endif + static uint32 UdiskOpenNewApi(void *dev) { return EOK; diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/Kconfig b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/Kconfig index af91dd200..3022556ec 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/Kconfig @@ -37,7 +37,7 @@ menu "aiit-riscv64-board feature" menu "config board peripheral" config MOUNT_SDCARD - bool "mount cd card" + bool "mount sd card" default n select BSP_USING_SDIO config MOUNT_USB diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/board.c b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/board.c index d267826a5..a74dc25e9 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/board.c +++ b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/board.c @@ -71,7 +71,7 @@ extern int HwCh376Init(void); * @description: Mount USB * @return 0 */ -int MountUSB(void) +int MountUsb(void) { if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, FSTYPE_CH376, "/") == 0) KPrintf("usb mount to '/'"); diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/connect_lora_spi.c b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/connect_lora_spi.c index 12f7b3555..5d3e7c7a2 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/connect_lora_spi.c +++ b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/connect_lora_spi.c @@ -389,7 +389,7 @@ static const struct LoraDevDone lora_done = * @param bus_name spi bus name * @param dev_name spi dev name * @param drv_name spi drv name - * @param flash_name flash dev name + * @param lora_name lora name */ SpiLoraDeviceType SpiLoraInit(char *bus_name, char *dev_name, char *drv_name, char *lora_name) { diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/connect_spi.c index c2a7ee5fb..ba9054ad1 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/connect_spi.c +++ b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/connect_spi.c @@ -221,7 +221,7 @@ static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStand { SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); - uint32 spi_read_length = 0;; + uint32 spi_read_length = 0; uint8 device_id = dev_param->spi_slave_param->spi_slave_id; uint8 device_master_id = dev_param->spi_dma_param->spi_master_id; uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; @@ -394,9 +394,15 @@ static int BoardSpiDevBend(struct SpiDmaParam *spi_initparam) static struct SpiHardwareDevice spi_device2; memset(&spi_device2, 0, sizeof(struct SpiHardwareDevice)); - spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_2] = SPI_DEVICE_SLAVE_ID_2; - spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_2] = SPI1_CS2_PIN; - spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_2] = SPI_CHIP_SELECT_2; + static struct SpiSlaveParam spi_slaveparam2; + memset(&spi_slaveparam2, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam2.spi_slave_id = SPI_DEVICE_SLAVE_ID_2; + spi_slaveparam2.spi_cs_gpio_pin = SPI1_CS2_PIN; + spi_slaveparam2.spi_cs_select_id = SPI_CHIP_SELECT_2; + + spi_device2.spi_param.spi_dma_param = spi_initparam; + spi_device2.spi_param.spi_slave_param = &spi_slaveparam2; spi_device2.spi_dev_done = &(spi_dev_done); @@ -417,9 +423,15 @@ static int BoardSpiDevBend(struct SpiDmaParam *spi_initparam) static struct SpiHardwareDevice spi_device3; memset(&spi_device3, 0, sizeof(struct SpiHardwareDevice)); - spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_3] = SPI_DEVICE_SLAVE_ID_3; - spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_3] = SPI1_CS3_PIN; - spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_3] = SPI_CHIP_SELECT_3; + static struct SpiSlaveParam spi_slaveparam3; + memset(&spi_slaveparam3, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam3.spi_slave_id = SPI_DEVICE_SLAVE_ID_3; + spi_slaveparam3.spi_cs_gpio_pin = SPI1_CS3_PIN; + spi_slaveparam3.spi_cs_select_id = SPI_CHIP_SELECT_3; + + spi_device3.spi_param.spi_dma_param = spi_initparam; + spi_device3.spi_param.spi_slave_param = &spi_slaveparam3; spi_device3.spi_dev_done = &(spi_dev_done); diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/third_party_spi_lora/src/radio/sx1276-LoRa.c b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/third_party_spi_lora/src/radio/sx1276-LoRa.c index f8645b09f..247c2d222 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/third_party_spi_lora/src/radio/sx1276-LoRa.c +++ b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/spi/third_party_spi_lora/src/radio/sx1276-LoRa.c @@ -784,12 +784,12 @@ uint32_t SX1276LoraChannelEmpty( void ) if(result == RF_CHANNEL_EMPTY) { - KPrintf("\nLora--信道可用(RF_CHANNEL_EMPTY)\n"); + KPrintf("\nLora--RF_CHANNEL_EMPTY\n"); return 0; } else if(result == RF_CHANNEL_ACTIVITY_DETECTED) { - KPrintf("\nLora--信道正被占用(RF_CHANNEL_ACTIVITY_DETECTED)\n"); + KPrintf("\nLora--RF_CHANNEL_ACTIVITY_DETECTED)\n"); return 1; } else diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/.defconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/.defconfig index 6df3af17a..2fa96ea66 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/.defconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/.defconfig @@ -32,16 +32,16 @@ CONFIG_BSP_USING_UART_HS=y # # General Purpose UARTs # -CONFIG_BSP_USING_UART1=y -CONFIG_BSP_UART1_TXD_PIN=20 -CONFIG_BSP_UART1_RXD_PIN=21 -CONFIG_BSP_USING_UART2=y -CONFIG_BSP_UART2_TXD_PIN=28 -CONFIG_BSP_UART2_RXD_PIN=27 -CONFIG_BSP_USING_UART3=y -CONFIG_BSP_UART3_TXD_PIN=22 -CONFIG_BSP_UART3_RXD_PIN=23 -CONFIG___STACKSIZE__=4096 +# CONFIG_BSP_USING_UART1=y +# CONFIG_BSP_UART1_TXD_PIN=20 +# CONFIG_BSP_UART1_RXD_PIN=21 +# CONFIG_BSP_USING_UART2=y +# CONFIG_BSP_UART2_TXD_PIN=28 +# CONFIG_BSP_UART2_RXD_PIN=27 +# CONFIG_BSP_USING_UART3=y +# CONFIG_BSP_UART3_TXD_PIN=22 +# CONFIG_BSP_UART3_RXD_PIN=23 +# CONFIG___STACKSIZE__=4096 # # Hardware feature diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c index 6dd32085d..1f37845f3 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c @@ -44,10 +44,14 @@ Modification: #include "fpioa.h" #include "dmac.h" #include "connect_gpio.h" +#include "connect_soft_spi.h" +#include "connect_rtc.h" +#include "connect_hwtimer.h" +#include "connect_wdt.h" -#if defined(FS_VFS) -#include -#endif +// #if defined(FS_VFS) +// #include +// #endif #define CPU0 (0) #define CPU1 (1) @@ -60,15 +64,15 @@ extern int HwTouchInit(void); extern int HwCh376Init(void); extern int HwLcdInit(void); extern int HwSpiInit(void); +extern int HwSoftSPIInit(void); -#ifdef FS_CH376 #include #ifdef MOUNT_USB /** * @description: Mount USB * @return 0 */ -int MountUSB(void) +int MountUsb(void) { if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, FSTYPE_CH376, "/") == 0) KPrintf("usb mount to '/'\n"); @@ -78,23 +82,34 @@ int MountUSB(void) return 0; } #endif -#ifdef MOUNT_SDCARD + +#if defined(FS_VFS) && defined (MOUNT_SDCARD) +#include +#include +extern SpiSdDeviceType SpiSdInit(struct Bus *bus, const char *dev_name, const char *drv_name, const char *sd_name); + /** * @description: Mount SD card * @return 0 */ - -int MountSDCard(void) +int MountSDCard(void) { - if (MountFilesystem(SDIO_BUS_NAME,SDIO_DEVICE_NAME ,SDIO_DRIVER_NAME , FSTYPE_CH376, "/") == 0) - KPrintf("sd card mount to '/'\n"); - else - KPrintf("sd card mount to '/' failed!\n"); - - return 0; + struct Bus *spi_bus; + spi_bus = BusFind(SOFT_SPI_BUS_NAME); + if (NONE == SpiSdInit(spi_bus, SOFT_SPI_DEVICE_NAME, SOFT_SPI_DRV_NAME, SPI_SD_NAME)) { + KPrintf("MountSDCard SpiSdInit error!\n"); + return -1; + } + if (EOK != MountFilesystem(SOFT_SPI_BUS_NAME, SPI_SD_NAME, SOFT_SPI_DRV_NAME, FSTYPE_FATFS, "/")) { + return -1; + } + + KPrintf("SPI SD card fatfs mounted\n"); + return 0; } #endif -#endif + + void InitBss(void) { @@ -172,6 +187,9 @@ struct InitSequenceDesc _board_init[] = #ifdef BSP_USING_I2C { "hw_i2c", HwI2cInit }, #endif +#ifdef BSP_USING_RTC + { "hw_rtc", HwRtcInit }, +#endif #ifdef BSP_USING_SPI { "hw_spi", HwSpiInit }, #endif @@ -183,10 +201,20 @@ struct InitSequenceDesc _board_init[] = #endif #ifdef BSP_USING_TOUCH {"touch", HwTouchInit }, +#endif +#ifdef BSP_USING_SOFT_SPI + {"soft_spi", HwSoftSPIInit }, +#endif +#ifdef BSP_USING_HWTIMER + {"hw_timer", HwTimerInit }, +#endif +#ifdef BSP_USING_WDT + {"hw_wdt", HwWdtInit }, #endif { " NONE ",NONE }, }; + void InitBoardHardware(void) { int i = 0; diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig index 4b4572352..11ecca978 100755 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig @@ -16,6 +16,16 @@ menuconfig BSP_USING_SPI source "$BSP_DIR/third_party_driver/spi/Kconfig" endif +menuconfig BSP_USING_SOFT_SPI + bool "Using SOFT_SPI device" + default n + select BSP_USING_SPI + select MOUNT_SDCARD + select FS_VFS + if BSP_USING_SOFT_SPI + source "$BSP_DIR/third_party_driver/soft_spi/Kconfig" + endif + menuconfig BSP_USING_LCD bool "Using LCD device" default n @@ -78,3 +88,27 @@ menuconfig BSP_USING_UART if BSP_USING_UART source "$BSP_DIR/third_party_driver/uart/Kconfig" endif + +menuconfig BSP_USING_RTC + bool "Using RTC device" + default y + select RESOURCES_RTC + if BSP_USING_RTC + source "$BSP_DIR/third_party_driver/rtc/Kconfig" + endif + +menuconfig BSP_USING_HWTIMER + bool "Using TIMER device" + default y + select RESOURCES_HWTIMER + if BSP_USING_HWTIMER + source "$BSP_DIR/third_party_driver/timer/Kconfig" + endif + +menuconfig BSP_USING_WDT + bool "Using WATCHDOG device" + default y + select RESOURCES_WDT + if BSP_USING_WDT + source "$BSP_DIR/third_party_driver/watchdog/Kconfig" + endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile index dd458fd0c..b8f466166 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile @@ -40,4 +40,21 @@ ifeq ($(CONFIG_BSP_USING_LCD),y) SRC_DIR += lcd endif +ifeq ($(CONFIG_BSP_USING_SOFT_SPI),y) + SRC_DIR += soft_spi +endif + +ifeq ($(CONFIG_BSP_USING_RTC),y) + SRC_DIR += rtc +endif + +ifeq ($(CONFIG_BSP_USING_HWTIMER),y) + SRC_DIR += timer +endif + +ifeq ($(CONFIG_BSP_USING_WDT),y) + SRC_DIR += watchdog +endif + + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/drv_io_config.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/drv_io_config.c index 2211e5832..defc6e6b6 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/drv_io_config.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/drv_io_config.c @@ -75,12 +75,13 @@ static struct io_config IOCONFIG(BSP_UART3_TXD_PIN, FUNC_UART3_RX), IOCONFIG(BSP_UART3_RXD_PIN, FUNC_UART3_TX), #endif -#ifdef BSP_USING_I2C1 +#ifdef BSP_USING_I2C IOCONFIG(BSP_I2C_SDA, FUNC_GPIO3), IOCONFIG(BSP_I2C_SCL, FUNC_GPIO4), #endif #ifdef BSP_USING_TOUCH - IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FPIOA_TOUCH_TP_INT)), + // IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FPIOA_TOUCH_TP_INT)), + IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FUNC_GPIOHS30)), #endif #ifdef BSP_USING_CH438 @@ -95,7 +96,31 @@ static struct io_config IOCONFIG(BSP_CH438_D4_PIN, HS_GPIO(FPIOA_CH438_D4)), IOCONFIG(BSP_CH438_D5_PIN, HS_GPIO(FPIOA_CH438_D5)), IOCONFIG(BSP_CH438_D6_PIN, HS_GPIO(FPIOA_CH438_D6)), - IOCONFIG(BSP_CH438_D7_PIN, HS_GPIO(FPIOA_CH438_D7)) + IOCONFIG(BSP_CH438_D7_PIN, HS_GPIO(FPIOA_CH438_D7)), +#endif + +#ifdef BSP_USING_SOFT_SPI + IOCONFIG(BSP_SOFT_SPI_SCK_PIN, HS_GPIO(FPIOA_SOFT_SPI_SCK)), + IOCONFIG(BSP_SOFT_SPI_MIOS_PIN, HS_GPIO(FPIOA_SOFT_SPI_MIOS)), + IOCONFIG(BSP_SOFT_SPI_MSOI_PIN, HS_GPIO(FPIOA_SOFT_SPI_MSOI)), + IOCONFIG(BSP_SOFT_SPI_NCS_PIN, HS_GPIO(FPIOA_SOFT_SPI_NCS)), +#endif + +#ifdef BSP_USING_LORA + IOCONFIG(BSP_E220_M0_PIN, HS_GPIO(FUNC_GPIOHS10)), + IOCONFIG(BSP_E220_M1_PIN, HS_GPIO(FUNC_GPIOHS11)), +#endif + +#ifdef BSP_USING_RS485 + IOCONFIG(BSP_485_DIR_PIN,HS_GPIO(FUNC_GPIOHS12)); +#endif + +#ifdef BSP_USING_LED + IOCONFIG(BSP_LED_PIN,FUNC_GPIO5); +#endif + +#ifdef BSP_USING_KEY + IOCONFIG(BSP_KEY_PIN,FUNC_GPIO6); #endif }; diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/Kconfig index c93536961..da6562c44 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/Kconfig @@ -12,6 +12,6 @@ if BSP_USING_I2C string "i2c bus 1 driver name" default "i2c1_drv" config I2C_1_DEVICE_NAME_0 - string "i2c bus 1 device 0 name" - default "i2c1_dev0" + string "i2c bus 1 device 0 name" + default "i2c1_dev0" endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_hwtimer.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_hwtimer.h new file mode 100644 index 000000000..cb0a99eda --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_hwtimer.h @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_hwtimer.h +* @brief define aiit-riscv64-board hwtimer function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_HWTIMER_H +#define CONNECT_HWTIMER_H + +#include +#include "hardware_hwtimer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int HwTimerInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_rtc.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_rtc.h new file mode 100644 index 000000000..8d02d6e6b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_rtc.h @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_rtc.h +* @brief define aiit-riscv64-board rtc function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_RTC_H +#define CONNECT_RTC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwRtcInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_soft_spi.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_soft_spi.h new file mode 100644 index 000000000..687c1383d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_soft_spi.h @@ -0,0 +1,14 @@ +#ifndef CONNECT_TF_H +#define CONNECT_TF_H + +#ifdef __cplusplus +extern "C" { +#endif + +int HwSoftSPIInit(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_wdt.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_wdt.h new file mode 100644 index 000000000..96cdb3e0e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_wdt.h @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_wdt.h +* @brief define aiit-riscv64-board wdt function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_WDT_H +#define CONNECT_WDT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwWdtInit(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h index c61e62412..f48e34c0d 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h @@ -78,6 +78,36 @@ enum HS_GPIO_CONFIG #define BSP_CH438_INT_PIN 35 #endif +#ifdef BSP_USING_SOFT_SPI +#define FPIOA_SOFT_SPI_SCK 26 +#define FPIOA_SOFT_SPI_MIOS 25 +#define FPIOA_SOFT_SPI_MSOI 27 +#define FPIOA_SOFT_SPI_NCS 28 + +#define BSP_SOFT_SPI_SCK_PIN 26 +#define BSP_SOFT_SPI_MIOS_PIN 25 +#define BSP_SOFT_SPI_MSOI_PIN 27 +#define BSP_SOFT_SPI_NCS_PIN 28 + +#endif + +#ifdef BSP_USING_LED +#define BSP_LED_PIN 29 +#endif + +#ifdef BSP_USING_KEY +#define BSP_KEY_PIN 31 +#endif + +#ifdef BSP_USING_LORA +#define BSP_E220_M0_PIN 32 +#define BSP_E220_M1_PIN 33 +#endif + +#ifdef BSP_USING_RS485 +#define BSP_485_DIR_PIN 24 +#endif + extern int IoConfigInit(void); #endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_hwtimer.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_hwtimer.h new file mode 100644 index 000000000..57ac51a3c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_hwtimer.h @@ -0,0 +1,171 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed 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. + */ + +/** +* @file hardware_hwtimer.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef __HARDWARE_HWTIMER_H__ +#define __HARDWARE_HWTIMER_H__ + +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +typedef struct _timer_channel +{ + /* TIMER_N Load Count Register (0x00+(N-1)*0x14) */ + volatile uint32_t load_count; + /* TIMER_N Current Value Register (0x04+(N-1)*0x14) */ + volatile uint32_t current_value; + /* TIMER_N Control Register (0x08+(N-1)*0x14) */ + volatile uint32_t control; + /* TIMER_N Interrupt Clear Register (0x0c+(N-1)*0x14) */ + volatile uint32_t eoi; + /* TIMER_N Interrupt Status Register (0x10+(N-1)*0x14) */ + volatile uint32_t intr_stat; +} __attribute__((packed, aligned(4))) timer_channel_t; + +typedef struct _kendryte_timer +{ + /* TIMER_N Register (0x00-0x4c) */ + volatile timer_channel_t channel[4]; + /* reserverd (0x50-0x9c) */ + volatile uint32_t resv1[20]; + /* TIMER Interrupt Status Register (0xa0) */ + volatile uint32_t intr_stat; + /* TIMER Interrupt Clear Register (0xa4) */ + volatile uint32_t eoi; + /* TIMER Raw Interrupt Status Register (0xa8) */ + volatile uint32_t raw_intr_stat; + /* TIMER Component Version Register (0xac) */ + volatile uint32_t comp_version; + /* TIMER_N Load Count2 Register (0xb0-0xbc) */ + volatile uint32_t load_count2[4]; +} __attribute__((packed, aligned(4))) kendryte_timer_t; + +typedef enum _timer_deivce_number +{ + TIMER_DEVICE_0, + TIMER_DEVICE_1, + TIMER_DEVICE_2, + TIMER_DEVICE_MAX, +} timer_device_number_t; + +typedef enum _timer_channel_number +{ + TIMER_CHANNEL_0, + TIMER_CHANNEL_1, + TIMER_CHANNEL_2, + TIMER_CHANNEL_3, + TIMER_CHANNEL_MAX, +} timer_channel_number_t; + +/* TIMER Control Register */ +#define TIMER_CR_ENABLE 0x00000001 +#define TIMER_CR_MODE_MASK 0x00000002 +#define TIMER_CR_FREE_MODE 0x00000000 +#define TIMER_CR_USER_MODE 0x00000002 +#define TIMER_CR_INTERRUPT_MASK 0x00000004 +#define TIMER_CR_PWM_ENABLE 0x00000008 +/* clang-format on */ + +extern volatile kendryte_timer_t *const timer[3]; + +/** + * @brief Definitions for the timer callbacks + */ +typedef int (*timer_callback_t)(void *ctx); + +/** + * @brief Set timer timeout + * + * @param[in] timer timer + * @param[in] channel channel + * @param[in] nanoseconds timeout + * + * @return the real timeout + */ +size_t timer_set_interval(timer_device_number_t timer_number, timer_channel_number_t channel, size_t nanoseconds); + +/** + * @brief Init timer + * + * @param[in] timer timer + */ +void timer_init(timer_device_number_t timer_number); + +/** + * @brief [DEPRECATED] Set timer timeout function + * + * @param[in] timer timer + * @param[in] channel channel + * @param[in] func timeout function + * @param[in] priority interrupt priority + * + */ +void timer_set_irq(timer_device_number_t timer_number, timer_channel_number_t channel, void(*func)(), uint32_t priority); + +/** + * @brief Register timer interrupt user callback function + * + * @param[in] device The timer device number + * @param[in] channel The channel + * @param[in] is_one_shot Indicates if single shot + * @param[in] priority The priority + * @param[in] callback The callback function + * @param[in] ctx The context + * + * @return result + * - 0 Success + * - Other Fail + */ +int timer_irq_register(timer_device_number_t device, timer_channel_number_t channel, int is_single_shot, uint32_t priority, timer_callback_t callback, void *ctx); + +/** + * @brief Deregister timer interrupt user callback function + * + * @param[in] device The timer device number + * @param[in] channel The channel + * + * @return result + * - 0 Success + * - Other Fail + */ +int timer_irq_unregister(timer_device_number_t device, timer_channel_number_t channel); + +/** + * @brief Enable timer + * + * @param[in] timer timer + * @param[in] channel channel + * @param[in] enable Enable or disable + * + */ +void timer_set_enable(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t enable); + +#ifdef __cplusplus +} +#endif + +#endif /* __TIMER_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_rtc.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_rtc.h new file mode 100644 index 000000000..b9c416dbb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_rtc.h @@ -0,0 +1,448 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed 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. + */ +/** + * @file + * @brief A real-time clock (RTC) is a computer clock that keeps track of + * the current time. + */ + +/** +* @file hardware_rtc.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef __HARDWARE_RTC_H__ +#define __HARDWARE_RTC_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief RTC timer mode + * + * Timer mode selector + * | Mode | Description | + * |------|------------------------| + * | 0 | Timer pause | + * | 1 | Timer time running | + * | 2 | Timer time setting | + */ +typedef enum _rtc_timer_mode_e +{ + /* 0: Timer pause */ + RTC_TIMER_PAUSE, + /* 1: Timer time running */ + RTC_TIMER_RUNNING, + /* 2: Timer time setting */ + RTC_TIMER_SETTING, + /* Max count of this enum*/ + RTC_TIMER_MAX +} rtc_timer_mode_t; + +/* + * @brief RTC tick interrupt mode + * + * Tick interrupt mode selector + * | Mode | Description | + * |------|------------------------| + * | 0 | Interrupt every second | + * | 1 | Interrupt every minute | + * | 2 | Interrupt every hour | + * | 3 | Interrupt every day | + */ +typedef enum _rtc_tick_interrupt_mode_e +{ + /* 0: Interrupt every second */ + RTC_INT_SECOND, + /* 1: Interrupt every minute */ + RTC_INT_MINUTE, + /* 2: Interrupt every hour */ + RTC_INT_HOUR, + /* 3: Interrupt every day */ + RTC_INT_DAY, + /* Max count of this enum*/ + RTC_INT_MAX +} rtc_tick_interrupt_mode_t; + +/** + * @brief RTC mask structure + * + * RTC mask structure for common use + */ +typedef struct _rtc_mask +{ + /* Reserved */ + uint32_t resv : 1; + /* Second mask */ + uint32_t second : 1; + /* Minute mask */ + uint32_t minute : 1; + /* Hour mask */ + uint32_t hour : 1; + /* Week mask */ + uint32_t week : 1; + /* Day mask */ + uint32_t day : 1; + /* Month mask */ + uint32_t month : 1; + /* Year mask */ + uint32_t year : 1; +} __attribute__((packed, aligned(1))) rtc_mask_t; + +/** + * @brief RTC register + * + * @note RTC register table + * + * | Offset | Name | Description | + * |-----------|----------------|-------------------------------------| + * | 0x00 | date | Timer date information | + * | 0x04 | time | Timer time information | + * | 0x08 | alarm_date | Alarm date information | + * | 0x0c | alarm_time | Alarm time information | + * | 0x10 | initial_count | Timer counter initial value | + * | 0x14 | current_count | Timer counter current value | + * | 0x18 | interrupt_ctrl | RTC interrupt settings | + * | 0x1c | register_ctrl | RTC register settings | + * | 0x20 | reserved0 | Reserved | + * | 0x24 | reserved1 | Reserved | + * | 0x28 | extended | Timer extended information | + * + */ + + +/** + * @brief Timer date information + * + * No. 0 Register (0x00) + */ +typedef struct _rtc_date +{ + /* Week. Range [0,6]. 0 is Sunday. */ + uint32_t week : 3; + /* Reserved */ + uint32_t resv0 : 5; + /* Day. Range [1,31] or [1,30] or [1,29] or [1,28] */ + uint32_t day : 5; + /* Reserved */ + uint32_t resv1 : 3; + /* Month. Range [1,12] */ + uint32_t month : 4; + /* Year. Range [0,99] */ + uint32_t year : 12; +} __attribute__((packed, aligned(4))) rtc_date_t; + +/** + * @brief Timer time information + * + * No. 1 Register (0x04) + */ +typedef struct _rtc_time +{ + /* Reserved */ + uint32_t resv0 : 10; + /* Second. Range [0,59] */ + uint32_t second : 6; + /* Minute. Range [0,59] */ + uint32_t minute : 6; + /* Reserved */ + uint32_t resv1 : 2; + /* Hour. Range [0,23] */ + uint32_t hour : 5; + /* Reserved */ + uint32_t resv2 : 3; +} __attribute__((packed, aligned(4))) rtc_time_t; + +/** + * @brief Alarm date information + * + * No. 2 Register (0x08) + */ +typedef struct _rtc_alarm_date +{ + /* Alarm Week. Range [0,6]. 0 is Sunday. */ + uint32_t week : 3; + /* Reserved */ + uint32_t resv0 : 5; + /* Alarm Day. Range [1,31] or [1,30] or [1,29] or [1,28] */ + uint32_t day : 5; + /* Reserved */ + uint32_t resv1 : 3; + /* Alarm Month. Range [1,12] */ + uint32_t month : 4; + /* Alarm Year. Range [0,99] */ + uint32_t year : 12; +} __attribute__((packed, aligned(4))) rtc_alarm_date_t; + +/** + * @brief Alarm time information + * + * No. 3 Register (0x0c) + */ +typedef struct _rtc_alarm_time +{ + /* Reserved */ + uint32_t resv0 : 10; + /* Alarm Second. Range [0,59] */ + uint32_t second : 6; + /* Alarm Minute. Range [0,59] */ + uint32_t minute : 6; + /* Reserved */ + uint32_t resv1 : 2; + /* Alarm Hour. Range [0,23] */ + uint32_t hour : 5; + /* Reserved */ + uint32_t resv2 : 3; +} __attribute__((packed, aligned(4))) rtc_alarm_time_t; + +/** + * @brief Timer counter initial value + * + * No. 4 Register (0x10) + */ +typedef struct _rtc_initial_count +{ + /* RTC counter initial value */ + uint32_t count : 32; +} __attribute__((packed, aligned(4))) rtc_initial_count_t; + +/** + * @brief Timer counter current value + * + * No. 5 Register (0x14) + */ +typedef struct _rtc_current_count +{ + /* RTC counter current value */ + uint32_t count : 32; +} __attribute__((packed, aligned(4))) rtc_current_count_t; + +/** + * @brief RTC interrupt settings + * + * No. 6 Register (0x18) + */ +typedef struct _rtc_interrupt_ctrl +{ + /* Reserved */ + uint32_t tick_enable : 1; + /* Alarm interrupt enable */ + uint32_t alarm_enable : 1; + /* Tick interrupt enable */ + uint32_t tick_int_mode : 2; + /* Reserved */ + uint32_t resv : 20; + /* Alarm compare mask for interrupt */ + uint32_t alarm_compare_mask : 8; +} __attribute__((packed, aligned(4))) rtc_interrupt_ctrl_t; + +/** + * @brief RTC register settings + * + * No. 7 Register (0x1c) + */ +typedef struct _rtc_register_ctrl +{ + /* RTC timer read enable */ + uint32_t read_enable : 1; + /* RTC timer write enable */ + uint32_t write_enable : 1; + /* Reserved */ + uint32_t resv0 : 11; + /* RTC timer mask */ + uint32_t TimerMask : 8; + /* RTC alarm mask */ + uint32_t alarm_mask : 8; + /* RTC counter initial count value mask */ + uint32_t initial_count_mask : 1; + /* RTC interrupt register mask */ + uint32_t interrupt_register_mask : 1; + /* Reserved */ + uint32_t resv1 : 1; +} __attribute__((packed, aligned(4))) rtc_register_ctrl_t; + +/** + * @brief Reserved + * + * No. 8 Register (0x20) + */ +typedef struct _rtc_reserved0 +{ + /* Reserved */ + uint32_t resv : 32; +} __attribute__((packed, aligned(4))) rtc_reserved0_t; + +/** + * @brief Reserved + * + * No. 9 Register (0x24) + */ +typedef struct _rtc_reserved1 +{ + /* Reserved */ + uint32_t resv : 32; +} __attribute__((packed, aligned(4))) rtc_reserved1_t; + +/** + * @brief Timer extended information + * + * No. 10 Register (0x28) + */ +typedef struct _rtc_extended +{ + /* Century. Range [0,31] */ + uint32_t century : 5; + /* Is leap year. 1 is leap year, 0 is not leap year */ + uint32_t leap_year : 1; + /* Reserved */ + uint32_t resv : 26; +} __attribute__((packed, aligned(4))) rtc_extended_t; + + +/** + * @brief Real-time clock struct + * + * A real-time clock (RTC) is a computer clock that keeps track of + * the current time. + */ +typedef struct _rtc +{ + /* No. 0 (0x00): Timer date information */ + rtc_date_t date; + /* No. 1 (0x04): Timer time information */ + rtc_time_t time; + /* No. 2 (0x08): Alarm date information */ + rtc_alarm_date_t alarm_date; + /* No. 3 (0x0c): Alarm time information */ + rtc_alarm_time_t alarm_time; + /* No. 4 (0x10): Timer counter initial value */ + rtc_initial_count_t initial_count; + /* No. 5 (0x14): Timer counter current value */ + rtc_current_count_t current_count; + /* No. 6 (0x18): RTC interrupt settings */ + rtc_interrupt_ctrl_t interrupt_ctrl; + /* No. 7 (0x1c): RTC register settings */ + rtc_register_ctrl_t register_ctrl; + /* No. 8 (0x20): Reserved */ + rtc_reserved0_t reserved0; + /* No. 9 (0x24): Reserved */ + rtc_reserved1_t reserved1; + /* No. 10 (0x28): Timer extended information */ + rtc_extended_t extended; +} __attribute__((packed, aligned(4))) rtc_t; + + +/** + * @brief Real-time clock object + */ +extern volatile rtc_t *const rtc; +extern volatile uint32_t *const rtc_base; + +/** + * @brief Set date time to RTC + * + * @param[in] year The year + * @param[in] month The month + * @param[in] day The day + * @param[in] hour The hour + * @param[in] minute The minute + * @param[in] second The second + * + * @return result + * - 0 Success + * - Other Fail + */ +int rtc_timer_set(int year, int month, int day, int hour, int minute, int second); + +/** + * @brief Get date time from RTC + * + * @param year The year + * @param month The month + * @param day The day + * @param hour The hour + * @param minute The minute + * @param second The second + * + * @return result + * - 0 Success + * - Other Fail + */ +int rtc_timer_get(int *year, int *month, int *day, int *hour, int *minute, int *second); + +/** + * @brief Initialize RTC + * + * @return Result + * - 0 Success + * - Other Fail + */ +int rtc_init(void); + +/** + * @brief Set RTC in protect mode or not + * + * @param enable Enable flag + * + * @return result + * - 0 Success + * - Other Fail + */ +int rtc_protect_set(int enable); + +/** + * @brief Set RTC timer mode + * + * @param timer_mode Timer mode + * + */ +void rtc_timer_set_mode(rtc_timer_mode_t timer_mode); + +/** + * @brief Set RTC timer clock frequency + * + * @param frequency Frequency + * + * @return result + * - 0 Success + * - Other Fail + */ +int rtc_timer_set_clock_frequency(unsigned int frequency); + +/** + * @brief Set RTC timer clock count value + * + * @param count Count + * + * @return result + * - 0 Success + * - Other Fail + */ +int rtc_timer_set_clock_count_value(unsigned int count); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRIVER_RTC_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wdt.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wdt.h new file mode 100644 index 000000000..cd7fc49eb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wdt.h @@ -0,0 +1,180 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed 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. + */ + +/** +* @file wdt.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef __WDT_H__ +#define __WDT_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +typedef struct _wdt +{ + /* WDT Control Register (0x00) */ + volatile uint32_t cr; + /* WDT Timeout Range Register (0x04) */ + volatile uint32_t torr; + /* WDT Current Counter Value Register (0x08) */ + volatile uint32_t ccvr; + /* WDT Counter Restart Register (0x0c) */ + volatile uint32_t crr; + /* WDT Interrupt Status Register (0x10) */ + volatile uint32_t stat; + /* WDT Interrupt Clear Register (0x14) */ + volatile uint32_t eoi; + /* reserverd (0x18) */ + volatile uint32_t resv1; + /* WDT Protection level Register (0x1c) */ + volatile uint32_t prot_level; + /* reserved (0x20-0xe0) */ + volatile uint32_t resv4[49]; + /* WDT Component Parameters Register 5 (0xe4) */ + volatile uint32_t comp_param_5; + /* WDT Component Parameters Register 4 (0xe8) */ + volatile uint32_t comp_param_4; + /* WDT Component Parameters Register 3 (0xec) */ + volatile uint32_t comp_param_3; + /* WDT Component Parameters Register 2 (0xf0) */ + volatile uint32_t comp_param_2; + /* WDT Component Parameters Register 1 (0xf4) */ + volatile uint32_t comp_param_1; + /* WDT Component Version Register (0xf8) */ + volatile uint32_t comp_version; + /* WDT Component Type Register (0xfc) */ + volatile uint32_t comp_type; +} __attribute__((packed, aligned(4))) wdt_t; + +typedef enum _wdt_device_number +{ + WDT_DEVICE_0, + WDT_DEVICE_1, + WDT_DEVICE_MAX, +} wdt_device_number_t; + + +#define WDT_RESET_ALL 0x00000000U +#define WDT_RESET_CPU 0x00000001U + +/* WDT Control Register */ +#define WDT_CR_ENABLE 0x00000001U +#define WDT_CR_RMOD_MASK 0x00000002U +#define WDT_CR_RMOD_RESET 0x00000000U +#define WDT_CR_RMOD_INTERRUPT 0x00000002U +#define WDT_CR_RPL_MASK 0x0000001CU +#define WDT_CR_RPL(x) ((x) << 2) +/* WDT Timeout Range Register */ +#define WDT_TORR_TOP_MASK 0x000000FFU +#define WDT_TORR_TOP(x) ((x) << 4 | (x) << 0) +/* WDT Current Counter Value Register */ +#define WDT_CCVR_MASK 0xFFFFFFFFU +/* WDT Counter Restart Register */ +#define WDT_CRR_MASK 0x00000076U +/* WDT Interrupt Status Register */ +#define WDT_STAT_MASK 0x00000001U +/* WDT Interrupt Clear Register */ +#define WDT_EOI_MASK 0x00000001U +/* WDT Protection level Register */ +#define WDT_PROT_LEVEL_MASK 0x00000007U +/* WDT Component Parameter Register 5 */ +#define WDT_COMP_PARAM_5_CP_WDT_USER_TOP_MAX_MASK 0xFFFFFFFFU +/* WDT Component Parameter Register 4 */ +#define WDT_COMP_PARAM_4_CP_WDT_USER_TOP_INIT_MAX_MASK 0xFFFFFFFFU +/* WDT Component Parameter Register 3 */ +#define WDT_COMP_PARAM_3_CD_WDT_TOP_RST_MASK 0xFFFFFFFFU +/* WDT Component Parameter Register 2 */ +#define WDT_COMP_PARAM_3_CP_WDT_CNT_RST_MASK 0xFFFFFFFFU +/* WDT Component Parameter Register 1 */ +#define WDT_COMP_PARAM_1_WDT_ALWAYS_EN_MASK 0x00000001U +#define WDT_COMP_PARAM_1_WDT_DFLT_RMOD_MASK 0x00000002U +#define WDT_COMP_PARAM_1_WDT_DUAL_TOP_MASK 0x00000004U +#define WDT_COMP_PARAM_1_WDT_HC_RMOD_MASK 0x00000008U +#define WDT_COMP_PARAM_1_WDT_HC_RPL_MASK 0x00000010U +#define WDT_COMP_PARAM_1_WDT_HC_TOP_MASK 0x00000020U +#define WDT_COMP_PARAM_1_WDT_USE_FIX_TOP_MASK 0x00000040U +#define WDT_COMP_PARAM_1_WDT_PAUSE_MASK 0x00000080U +#define WDT_COMP_PARAM_1_APB_DATA_WIDTH_MASK 0x00000300U +#define WDT_COMP_PARAM_1_WDT_DFLT_RPL_MASK 0x00001C00U +#define WDT_COMP_PARAM_1_WDT_DFLT_TOP_MASK 0x000F0000U +#define WDT_COMP_PARAM_1_WDT_DFLT_TOP_INIT_MASK 0x00F00000U +#define WDT_COMP_PARAM_1_WDT_CNT_WIDTH_MASK 0x1F000000U +/* WDT Component Version Register */ +#define WDT_COMP_VERSION_MASK 0xFFFFFFFFU +/* WDT Component Type Register */ +#define WDT_COMP_TYPE_MASK 0xFFFFFFFFU +/* clang-format on */ + +/** + * @brief Feed wdt + */ +void wdt_feed(wdt_device_number_t id); + +/** + * @brief Start wdt + * + * @param[in] id Wdt id 0 or 1 + * @param[in] time_out_ms Wdt trigger time + * @param[in] on_irq Wdt interrupt callback + * + */ +void wdt_start(wdt_device_number_t id, uint64_t time_out_ms, plic_irq_callback_t on_irq); + +/** + * @brief Start wdt + * + * @param[in] id Wdt id 0 or 1 + * @param[in] time_out_ms Wdt trigger time + * @param[in] on_irq Wdt interrupt callback + * @param[in] ctx Param of callback + * + * @return Wdt time + * + */ +uint32_t wdt_init(wdt_device_number_t id, uint64_t time_out_ms, plic_irq_callback_t on_irq, void *ctx); + +/** + * @brief Stop wdt + * + * @param[in] id Wdt id 0 or 1 + * + */ +void wdt_stop(wdt_device_number_t id); + +/** + * @brief Clear wdt interrupt + * + * @param[in] id Wdt id 0 or 1 + * + */ +void wdt_clear_interrupt(wdt_device_number_t id); + +#ifdef __cplusplus +} +#endif + +#endif /* __WDT_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Kconfig new file mode 100644 index 000000000..e853dd40a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Kconfig @@ -0,0 +1,11 @@ +if BSP_USING_RTC + config RTC_BUS_NAME + string "rtc bus name" + default "rtc" + config RTC_DRV_NAME + string "rtc bus driver name" + default "rtc_drv" + config RTC_DEVICE_NAME + string "rtc bus device name" + default "rtc_dev" +endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Makefile new file mode 100644 index 000000000..23575e62e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_rtc.c hardware_rtc.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/connect_rtc.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/connect_rtc.c new file mode 100644 index 000000000..fc512b865 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/connect_rtc.c @@ -0,0 +1,183 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_rtc.c +* @brief support aiit-riscv64-board rtc function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include + +static int GetWeekDay(int year, int month, int day) +{ + /* Magic method to get weekday */ + int weekday = (day += month < 3 ? year-- : year - 2, + 23 * month / 9 + day + 4 + year / 4 - year / 100 + year / 400) % 7; + return weekday; +} + +static uint32 RtcConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + + struct RtcDriver *rtc_drv = (struct RtcDriver *)drv; + struct RtcDrvConfigureParam *drv_param = (struct RtcDrvConfigureParam *)configure_info->private_data; + + int cmd = drv_param->rtc_operation_cmd; + time_t *time = drv_param->time; + + switch (cmd) + { + case OPER_RTC_GET_TIME: + { + struct tm ct; + int year,month,day,hour,minute,second; + memset(&ct,0,sizeof(struct tm)); + + rtc_timer_get(&year, &month, &day, &hour, &minute, &second); + + ct.tm_year = year - 1900; + ct.tm_mon = month - 1; + ct.tm_mday = day; + ct.tm_wday = GetWeekDay(year, month, day); + + ct.tm_hour = hour; + ct.tm_min = minute; + ct.tm_sec = second; + + *time = mktime(&ct); + } + break; + case OPER_RTC_SET_TIME: + { + struct tm *ct; + struct tm tm_new; + x_base lock; + + lock = CriticalAreaLock(); + ct = localtime(time); + memcpy(&tm_new, ct, sizeof(struct tm)); + CriticalAreaUnLock(lock); + + sysctl_reset(SYSCTL_RESET_RTC); + sysctl_clock_enable(SYSCTL_CLOCK_RTC); + rtc_protect_set(0); + rtc_timer_set_clock_frequency(SysctlClockGetFreq(SYSCTL_CLOCK_IN0)); + rtc_timer_set_clock_count_value(1); + rtc_timer_set_mode(RTC_TIMER_RUNNING); + + if (rtc_timer_set(tm_new.tm_year+1900,tm_new.tm_mon+1,tm_new.tm_mday, + tm_new.tm_hour,tm_new.tm_min,tm_new.tm_sec)==-1) + return ERROR; + } + break; + } + return EOK; +} + +/*manage the rtc device operations*/ +static const struct RtcDevDone dev_done = +{ + .open = NONE, + .close = NONE, + .write = NONE, + .read = NONE, +}; + +static int BoardRtcBusInit(struct RtcBus *rtc_bus, struct RtcDriver *rtc_driver) +{ + x_err_t ret = EOK; + + /*Init the rtc bus */ + ret = RtcBusInit(rtc_bus, RTC_BUS_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcBusInit error %d\n", ret); + return ERROR; + } + + /*Init the rtc driver*/ + ret = RtcDriverInit(rtc_driver, RTC_DRV_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the rtc driver to the rtc bus*/ + ret = RtcDriverAttachToBus(RTC_DRV_NAME, RTC_BUS_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the rtc device to the rtc bus*/ +static int BoardRtcDevBend(void) +{ + x_err_t ret = EOK; + + static struct RtcHardwareDevice rtc_device; + memset(&rtc_device, 0, sizeof(struct RtcHardwareDevice)); + + rtc_device.dev_done = &(dev_done); + + ret = RtcDeviceRegister(&rtc_device, NONE, RTC_DEVICE_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDeviceInit device %s error %d\n", RTC_DEVICE_NAME, ret); + return ERROR; + } + + ret = RtcDeviceAttachToBus(RTC_DEVICE_NAME, RTC_BUS_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDeviceAttachToBus device %s error %d\n", RTC_DEVICE_NAME, ret); + return ERROR; + } + + return ret; +} + +int HwRtcInit(void) +{ + x_err_t ret = EOK; + + static struct RtcBus rtc_bus; + memset(&rtc_bus, 0, sizeof(struct RtcBus)); + + static struct RtcDriver rtc_driver; + memset(&rtc_driver, 0, sizeof(struct RtcDriver)); + + rtc_driver.configure = &(RtcConfigure); + + ret = BoardRtcBusInit(&rtc_bus, &rtc_driver); + if (EOK != ret) { + KPrintf("HwRtcInit error ret %u\n", ret); + return ERROR; + } + + ret = BoardRtcDevBend(); + if (EOK != ret) { + KPrintf("HwRtcInit error ret %u\n", ret); + } + + rtc_init(); + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/hardware_rtc.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/hardware_rtc.c new file mode 100644 index 000000000..3f168dbf6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/hardware_rtc.c @@ -0,0 +1,597 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed 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. + */ + +/** +* @file hardware_rtc.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include + +volatile rtc_t *const rtc = (volatile rtc_t *)RTC_BASE_ADDR; + +struct tm rtc_date_time; + +void rtc_timer_set_mode(rtc_timer_mode_t timer_mode) +{ + rtc_register_ctrl_t register_ctrl = rtc->register_ctrl; + + switch (timer_mode) + { + case RTC_TIMER_PAUSE: + register_ctrl.read_enable = 0; + register_ctrl.write_enable = 0; + break; + case RTC_TIMER_RUNNING: + register_ctrl.read_enable = 1; + register_ctrl.write_enable = 0; + break; + case RTC_TIMER_SETTING: + register_ctrl.read_enable = 0; + register_ctrl.write_enable = 1; + break; + default: + register_ctrl.read_enable = 0; + register_ctrl.write_enable = 0; + break; + } + rtc->register_ctrl = register_ctrl; +} + +rtc_timer_mode_t rtc_timer_get_mode(void) +{ + rtc_register_ctrl_t register_ctrl = rtc->register_ctrl; + rtc_timer_mode_t timer_mode = RTC_TIMER_PAUSE; + + if ((!register_ctrl.read_enable) && (!register_ctrl.write_enable)) + { + /* RTC_TIMER_PAUSE */ + timer_mode = RTC_TIMER_PAUSE; + } + else if ((register_ctrl.read_enable) && (!register_ctrl.write_enable)) + { + /* RTC_TIMER_RUNNING */ + timer_mode = RTC_TIMER_RUNNING; + } + else if ((!register_ctrl.read_enable) && (register_ctrl.write_enable)) { + /* RTC_TIMER_SETTING */ + timer_mode = RTC_TIMER_SETTING; + } + else + { + /* Something is error, reset timer mode */ + rtc_timer_set_mode(timer_mode); + } + + return timer_mode; +} + +static inline int rtc_in_range(int value, int min, int max) +{ + return ((value >= min) && (value <= max)); +} + +int rtc_timer_set_tm(const struct tm *tm) +{ + rtc_date_t timer_date; + rtc_time_t timer_time; + rtc_extended_t timer_extended; + + if (tm) + { + /* + * Range of tm->tm_sec could be [0,61] + * + * Range of tm->tm_sec allows for a positive leap second. Two + * leap seconds in the same minute are not allowed (the C90 + * range 0..61 was a defect) + */ + if (rtc_in_range(tm->tm_sec, 0, 59)) + timer_time.second = tm->tm_sec; + else + return -1; + + /* Range of tm->tm_min could be [0,59] */ + if (rtc_in_range(tm->tm_min, 0, 59)) + timer_time.minute = tm->tm_min; + else + return -1; + + /* Range of tm->tm_hour could be [0, 23] */ + if (rtc_in_range(tm->tm_hour, 0, 23)) + timer_time.hour = tm->tm_hour; + else + return -1; + + /* Range of tm->tm_mday could be [1, 31] */ + if (rtc_in_range(tm->tm_mday, 1, 31)) + timer_date.day = tm->tm_mday; + else + return -1; + + /* + * Range of tm->tm_mon could be [0, 11] + * But in this RTC, date.month should be [1, 12] + */ + if (rtc_in_range(tm->tm_mon, 0, 11)) + timer_date.month = tm->tm_mon + 1; + else + return -1; + + /* + * Range of tm->tm_year is the years since 1900 + * But in this RTC, year is split into year and century + * In this RTC, century range is [0,31], year range is [0,99] + */ + int human_year = tm->tm_year + 1900; + int rtc_year = human_year % 100; + int rtc_century = human_year / 100; + + if (rtc_in_range(rtc_year, 0, 99) && + rtc_in_range(rtc_century, 0, 31)) + { + timer_date.year = rtc_year; + timer_extended.century = rtc_century; + } + else + return -1; + + /* Range of tm->tm_wday could be [0, 6] */ + if (rtc_in_range(tm->tm_wday, 0, 6)) + timer_date.week = tm->tm_wday; + else + return -1; + + /* Set RTC mode to timer setting mode */ + rtc_timer_set_mode(RTC_TIMER_SETTING); + /* Write value to RTC */ + rtc->date = timer_date; + rtc->time = timer_time; + rtc->extended = timer_extended; + /* Get CPU current freq */ + unsigned long freq = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); + /* Set threshold to 1/26000000 s */ + freq = freq / 26000000; + /* Get current CPU cycle */ + unsigned long start_cycle = read_cycle(); + /* Wait for 1/26000000 s to sync data */ + while (read_cycle() - start_cycle < freq) + continue; + /* Set RTC mode to timer running mode */ + rtc_timer_set_mode(RTC_TIMER_RUNNING); + } + + return 0; +} + +int rtc_timer_set_alarm_tm(const struct tm *tm) +{ + rtc_alarm_date_t alarm_date; + rtc_alarm_time_t alarm_time; + + if (tm) { + /* + * Range of tm->tm_sec could be [0,61] + * + * Range of tm->tm_sec allows for a positive leap second. Two + * leap seconds in the same minute are not allowed (the C90 + * range 0..61 was a defect) + */ + if (rtc_in_range(tm->tm_sec, 0, 59)) + alarm_time.second = tm->tm_sec; + else + return -1; + + /* Range of tm->tm_min could be [0,59] */ + if (rtc_in_range(tm->tm_min, 0, 59)) + alarm_time.minute = tm->tm_min; + else + return -1; + + /* Range of tm->tm_hour could be [0, 23] */ + if (rtc_in_range(tm->tm_hour, 0, 23)) + alarm_time.hour = tm->tm_hour; + else + return -1; + + /* Range of tm->tm_mday could be [1, 31] */ + if (rtc_in_range(tm->tm_mday, 1, 31)) + alarm_date.day = tm->tm_mday; + else + return -1; + + /* + * Range of tm->tm_mon could be [0, 11] + * But in this RTC, date.month should be [1, 12] + */ + if (rtc_in_range(tm->tm_mon, 0, 11)) + alarm_date.month = tm->tm_mon + 1; + else + return -1; + + /* + * Range of tm->tm_year is the years since 1900 + * But in this RTC, year is split into year and century + * In this RTC, century range is [0,31], year range is [0,99] + */ + int human_year = tm->tm_year + 1900; + int rtc_year = human_year % 100; + int rtc_century = human_year / 100; + + if (rtc_in_range(rtc_year, 0, 99) && + rtc_in_range(rtc_century, 0, 31)) + { + alarm_date.year = rtc_year; + } else + return -1; + + /* Range of tm->tm_wday could be [0, 6] */ + if (rtc_in_range(tm->tm_wday, 0, 6)) + alarm_date.week = tm->tm_wday; + else + return -1; + + /* Write value to RTC */ + rtc->alarm_date = alarm_date; + rtc->alarm_time = alarm_time; + } + + return 0; +} + +static int rtc_year_is_leap(int year) +{ + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); +} + +static int rtc_get_yday(int year, int month, int day) +{ + static const int days[2][13] = + { + {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, + {0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} + }; + int leap = rtc_year_is_leap(year); + + return days[leap][month] + day; +} + +static int rtc_get_wday(int year, int month, int day) +{ + /* Magic method to get weekday */ + int weekday = (day += month < 3 ? year-- : year - 2, 23 * month / 9 + day + 4 + year / 4 - year / 100 + year / 400) % 7; + return weekday; +} + +struct tm *rtc_timer_get_tm(void) +{ + if (rtc_timer_get_mode() != RTC_TIMER_RUNNING) + return NULL; + + rtc_date_t timer_date = rtc->date; + rtc_time_t timer_time = rtc->time; + rtc_extended_t timer_extended = rtc->extended; + + struct tm *tm = &rtc_date_time; + + tm->tm_sec = timer_time.second % 60; + tm->tm_min = timer_time.minute % 60; + tm->tm_hour = timer_time.hour % 24; + tm->tm_mday = (timer_date.day - 1) % 31 + 1; + tm->tm_mon = (timer_date.month - 1)% 12; + tm->tm_year = (timer_date.year % 100) + (timer_extended.century * 100) - 1900; + tm->tm_wday = timer_date.week; + tm->tm_yday = rtc_get_yday(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); + tm->tm_isdst = -1; + + return tm; +} + +struct tm *rtc_timer_get_alarm_tm(void) +{ + if (rtc_timer_get_mode() != RTC_TIMER_RUNNING) + return NULL; + + rtc_alarm_date_t alarm_date = rtc->alarm_date; + rtc_alarm_time_t alarm_time = rtc->alarm_time; + rtc_extended_t timer_extended = rtc->extended; + + struct tm *tm = &rtc_date_time; + + tm->tm_sec = alarm_time.second % 60; + tm->tm_min = alarm_time.minute % 60; + tm->tm_hour = alarm_time.hour % 24; + tm->tm_mday = alarm_date.day % 31; + tm->tm_mon = (alarm_date.month % 12) - 1; + /* Alarm and Timer use same timer_extended.century */ + tm->tm_year = (alarm_date.year % 100) + (timer_extended.century * 100) - 1900; + tm->tm_wday = alarm_date.week; + tm->tm_yday = rtc_get_yday(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); + tm->tm_isdst = -1; + + return tm; +} + +int rtc_timer_set(int year, int month, int day, int hour, int minute, int second) +{ + struct tm date_time = + { + .tm_sec = second, + .tm_min = minute, + .tm_hour = hour, + .tm_mday = day, + .tm_mon = month - 1, + .tm_year = year - 1900, + .tm_wday = rtc_get_wday(year, month, day), + .tm_yday = rtc_get_yday(year, month, day), + .tm_isdst = -1, + }; + return rtc_timer_set_tm(&date_time); +} + +int rtc_timer_get(int *year, int *month, int *day, int *hour, int *minute, int *second) +{ + struct tm *tm = rtc_timer_get_tm(); + + if (tm) + { + if (year) + *year = tm->tm_year + 1900; + if (month) + *month = tm->tm_mon + 1; + if (day) + *day = tm->tm_mday; + if (hour) + *hour = tm->tm_hour; + if (minute) + *minute = tm->tm_min; + if (second) + *second = tm->tm_sec; + } else + return -1; + + return 0; +} + +int rtc_timer_set_alarm(int year, int month, int day, int hour, int minute, int second) +{ + struct tm date_time = { + .tm_sec = second, + .tm_min = minute, + .tm_hour = hour, + .tm_mday = day, + .tm_mon = month - 1, + .tm_year = year - 1900, + .tm_wday = rtc_get_wday(year, month, day), + .tm_yday = rtc_get_yday(year, month, day), + .tm_isdst = -1, + }; + + return rtc_timer_set_alarm_tm(&date_time); +} + +int rtc_timer_get_alarm(int *year, int *month, int *day, int *hour, int *minute, int *second) +{ + struct tm *tm = rtc_timer_get_alarm_tm(); + + if (tm) { + if (year) + *year = tm->tm_year + 1900; + if (month) + *month = tm->tm_mon + 1; + if (day) + *day = tm->tm_mday; + if (hour) + *hour = tm->tm_hour; + if (minute) + *minute = tm->tm_min; + if (second) + *second = tm->tm_sec; + } else + return -1; + + return 0; +} + +int rtc_timer_set_clock_frequency(unsigned int frequency) +{ + + rtc_initial_count_t initial_count; + + initial_count.count = frequency; + rtc_timer_set_mode(RTC_TIMER_SETTING); + rtc->initial_count = initial_count; + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} + +unsigned int rtc_timer_get_clock_frequency(void) +{ + return rtc->initial_count.count; +} + +int rtc_timer_set_clock_count_value(unsigned int count) +{ + + rtc_current_count_t current_count; + + current_count.count = count; + rtc_timer_set_mode(RTC_TIMER_SETTING); + rtc->current_count = current_count; + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} + +unsigned int rtc_timer_get_clock_count_value(void) +{ + return rtc->current_count.count; +} + +int rtc_tick_interrupt_set(int enable) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + interrupt_ctrl.tick_enable = enable; + rtc_timer_set_mode(RTC_TIMER_SETTING); + rtc->interrupt_ctrl = interrupt_ctrl; + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} + +int rtc_tick_interrupt_get(void) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + return interrupt_ctrl.tick_enable; +} + +int rtc_tick_interrupt_mode_set(rtc_tick_interrupt_mode_t mode) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + interrupt_ctrl.tick_int_mode = mode; + rtc_timer_set_mode(RTC_TIMER_SETTING); + rtc->interrupt_ctrl = interrupt_ctrl; + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} + +rtc_tick_interrupt_mode_t rtc_tick_interrupt_mode_get(void) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + return interrupt_ctrl.tick_int_mode; +} + +int rtc_alarm_interrupt_set(int enable) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + interrupt_ctrl.alarm_enable = enable; + rtc->interrupt_ctrl = interrupt_ctrl; + return 0; +} + +int rtc_alarm_interrupt_get(void) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + return interrupt_ctrl.alarm_enable; +} + +int rtc_alarm_interrupt_mask_set(rtc_mask_t mask) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + interrupt_ctrl.alarm_compare_mask = *(uint8_t *)&mask; + rtc->interrupt_ctrl = interrupt_ctrl; + return 0; +} + +rtc_mask_t rtc_alarm_interrupt_mask_get(void) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + uint8_t compare_mask = interrupt_ctrl.alarm_compare_mask; + + return *(rtc_mask_t *)&compare_mask; +} + +int rtc_protect_set(int enable) +{ + rtc_register_ctrl_t register_ctrl = rtc->register_ctrl; + + rtc_mask_t mask = + { + .second = 1, + /* Second mask */ + .minute = 1, + /* Minute mask */ + .hour = 1, + /* Hour mask */ + .week = 1, + /* Week mask */ + .day = 1, + /* Day mask */ + .month = 1, + /* Month mask */ + .year = 1, + }; + + rtc_mask_t unmask = + { + .second = 0, + /* Second mask */ + .minute = 0, + /* Minute mask */ + .hour = 0, + /* Hour mask */ + .week = 0, + /* Week mask */ + .day = 0, + /* Day mask */ + .month = 0, + /* Month mask */ + .year = 0, + }; + + if (enable) + { + /* Turn RTC in protect mode, no one can write time */ + register_ctrl.TimerMask = *(uint8_t *)&unmask; + register_ctrl.alarm_mask = *(uint8_t *)&unmask; + register_ctrl.initial_count_mask = 0; + register_ctrl.interrupt_register_mask = 0; + } + else + { + /* Turn RTC in unprotect mode, everyone can write time */ + register_ctrl.TimerMask = *(uint8_t *)&mask; + register_ctrl.alarm_mask = *(uint8_t *)&mask; + register_ctrl.initial_count_mask = 1; + register_ctrl.interrupt_register_mask = 1; + } + rtc_timer_set_mode(RTC_TIMER_SETTING); + rtc->register_ctrl = register_ctrl; + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} + +int rtc_init(void) +{ + /* Reset RTC */ + sysctl_reset(SYSCTL_RESET_RTC); + /* Enable RTC */ + sysctl_clock_enable(SYSCTL_CLOCK_RTC); + /* Unprotect RTC */ + rtc_protect_set(0); + /* Set RTC clock frequency */ + rtc_timer_set_clock_frequency( + SysctlClockGetFreq(SYSCTL_CLOCK_IN0) + ); + rtc_timer_set_clock_count_value(1); + + /* Set RTC mode to timer running mode */ + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Kconfig new file mode 100644 index 000000000..73b7f7c4f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Kconfig @@ -0,0 +1,43 @@ +if BSP_USING_SOFT_SPI + config SOFT_SPI_BUS_NAME + string "soft spi bus 1 name" + default "soft_spi1_bus1" + + config SOFT_SPI_DEVICE_NAME + string "soft spi dev 1 name" + default "soft_spi1_dev1" + + config SOFT_SPI_DRV_NAME + string "soft spi drv 1 name" + default "soft_spi1_drv1" + + config SOFT_SPI_SCK + int "soft spi sck pin" + default 26 + + config SOFT_SPI_MOSI + int "soft spi mosi pin" + default 27 + + config SOFT_SPI_MISO + int "soft spi miso pin" + default 25 + + config SOFT_SPI_CS0_PIN + int "soft spi cs pin" + default 28 + + config SOFT_SPI_DEVICE_SLAVE_ID + int "soft spi slave id" + default 0 + + config SOFT_SPI_CHIP_SELECT + int "soft spi chip selected" + default 0 + + config SOFT_SPI_CLK_DELAY + int "clk in microsecond" + default 0 + +endif + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Makefile new file mode 100644 index 000000000..8ccf2895c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_soft_spi.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c new file mode 100644 index 000000000..9cf961d40 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c @@ -0,0 +1,295 @@ +#include +#include +#include +#include +#include "drv_io_config.h" +#include +#include +#include +#include + +#include +#include +#include + +static x_err_t softSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *cfg) +{ + NULL_PARAM_CHECK(spi_drv); + NULL_PARAM_CHECK(cfg); + + // mode CPOL = 0 CPHA = 0 + gpiohs_set_drive_mode(SOFT_SPI_CS0_PIN, GPIO_DM_OUTPUT); + gpiohs_set_pin(SOFT_SPI_CS0_PIN, GPIO_PV_HIGH); // set the cs gpio high + gpiohs_set_drive_mode(SOFT_SPI_SCK, GPIO_DM_OUTPUT); + gpiohs_set_drive_mode(SOFT_SPI_MOSI, GPIO_DM_OUTPUT); + gpiohs_set_drive_mode(SOFT_SPI_MISO, GPIO_DM_INPUT); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); + KPrintf("%s init done\n", SOFT_SPI_BUS_NAME); + + return EOK; +} + +static uint32 softSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct SpiDriver *spi_drv = (struct SpiDriver *)drv; + struct SpiMasterParam *spi_param; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + softSPIinit(spi_drv, configure_info); + break; + + case OPE_CFG: + break; + default: + + break; + } + + return ret; +} + +static void soft_spi_writebyte(struct SpiHardwareDevice *spi_dev, uint8_t data) +{ + int8_t i = 0; + uint8_t temp = 0; + for (i = 0; i < 8; i++) + { + temp = ((data & 0x80) == 0x80) ? 1 : 0; + data = data << 1; + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); + usleep(SOFT_SPI_CLK_DELAY); + if (0 == temp) + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_LOW); + } + else + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_HIGH); + } + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH); + usleep(SOFT_SPI_CLK_DELAY); + } + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); +} + +/* 读一个字节 */ +static uint8_t soft_spi_readbyte(struct SpiHardwareDevice *spi_dev) +{ + uint8_t i = 0; + uint8_t read_data = 0xFF; + for (i = 0; i < 8; i++) + { + read_data = read_data << 1; + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); + usleep(SOFT_SPI_CLK_DELAY); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH); + usleep(SOFT_SPI_CLK_DELAY); + if (1 == gpiohs_get_pin(SOFT_SPI_MISO)) + { + read_data = read_data | 0x01; + } + } + return read_data; +} + +/* 读写一个字节 */ +// this funcition is unverify until now! +static uint8_t soft_spi_readwritebyte(struct SpiHardwareDevice *spi_dev, uint8_t data) +{ + uint8_t i = 0; + uint8_t temp = 0; + uint8_t read_data = 0xFF; + for (i = 0; i < 8; i++) + { + temp = ((data & 0x80) == 0x80) ? 1 : 0; + data = data << 1; + read_data = read_data << 1; + if (temp == 0) + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_LOW); + } + else + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_HIGH); + } + usleep(SOFT_SPI_CLK_DELAY); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH); + usleep(SOFT_SPI_CLK_DELAY); + if (gpiohs_get_pin(SOFT_SPI_MISO) == 1) + { + read_data = read_data + 1; + } + } + return read_data; +} + +static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + const uint8_t *data_buff = spi_datacfg->tx_buff; + int data_length = spi_datacfg->length; + if (NONE == spi_datacfg->tx_buff) + { + data_length = 0; + } + + if (spi_datacfg->spi_chip_select) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + + for (size_t i = 0; i < data_length; i++) + { + soft_spi_writebyte(spi_dev, data_buff[i]); + } + + if (spi_datacfg->spi_cs_release) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + spi_datacfg = spi_datacfg->next; + + return EOK; +} + +static uint32 softSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + uint8_t *recv_buff = spi_datacfg->rx_buff; + int recv_length = spi_datacfg->length; + + if (NONE == spi_datacfg->rx_buff) + { + recv_length = 0; + } + + if (spi_datacfg->spi_chip_select) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + + for (size_t i = 0; i < recv_length; i++) + { + recv_buff[i] = soft_spi_readbyte(spi_dev); + } + + if (spi_datacfg->spi_cs_release) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + + spi_datacfg = spi_datacfg->next; + + return spi_datacfg->length; +} + +const struct SpiDevDone soft_spi_dev_done = { + .dev_close = NONE, + .dev_open = NONE, + .dev_read = softSpiReadData, + .dev_write = softSpiWriteData}; + +static int BoardSoftSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver) +{ + x_err_t ret = EOK; + + /*Init the spi bus */ + ret = SpiBusInit(spi_bus, SOFT_SPI_BUS_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiBusInit error %d\n", ret); + return ERROR; + } + + /*Init the spi driver*/ + ret = SpiDriverInit(spi_driver, SOFT_SPI_DRV_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the spi driver to the spi bus*/ + ret = SpiDriverAttachToBus(SOFT_SPI_DRV_NAME, SOFT_SPI_BUS_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +static int BoardSoftSpiDevBend(void) +{ + x_err_t ret = EOK; + + static struct SpiHardwareDevice spi_device0; + memset(&spi_device0, 0, sizeof(struct SpiHardwareDevice)); + + static struct SpiSlaveParam spi_slaveparam0; + memset(&spi_slaveparam0, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam0.spi_slave_id = SOFT_SPI_DEVICE_SLAVE_ID; + spi_slaveparam0.spi_cs_gpio_pin = SOFT_SPI_CS0_PIN; + spi_slaveparam0.spi_cs_select_id = SOFT_SPI_CHIP_SELECT; + + spi_device0.spi_param.spi_dma_param = NONE; + spi_device0.spi_param.spi_slave_param = &spi_slaveparam0; + + spi_device0.spi_dev_done = &(soft_spi_dev_done); + + ret = SpiDeviceRegister(&spi_device0, (void *)(&spi_device0.spi_param), SOFT_SPI_DEVICE_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SOFT_SPI_DEVICE_NAME, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SOFT_SPI_DEVICE_NAME, SOFT_SPI_BUS_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SOFT_SPI_DEVICE_NAME, ret); + return ERROR; + } + + return ret; +} + +int HwSoftSPIInit(void) +{ + x_err_t ret = EOK; + + static struct SpiBus spi_bus; + memset(&spi_bus, 0, sizeof(struct SpiBus)); + + static struct SpiDriver spi_driver; + memset(&spi_driver, 0, sizeof(struct SpiDriver)); + + spi_driver.configure = &(softSpiDrvConfigure); + + ret = BoardSoftSpiBusInit(&spi_bus, &spi_driver); + if (EOK != ret) + { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardSoftSpiDevBend(); + if (EOK != ret) + { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/Kconfig index de61c1ef5..d1ebdeb3c 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/Kconfig @@ -100,26 +100,3 @@ if BSP_USING_SPI1 endif endif -config BSP_USING_TP -bool "Using LCD touch " -default n - -if BSP_USING_TP - config BSP_TP_SCK_PIN - int "TP SCK pin number" - default 42 - config BSP_TP_NCS_PIN - int "TP NCS pin number" - default 43 - config BSP_TP_MISO_PIN - int "TP MISO pin number" - default 44 - config BSP_TP_IRQ_PIN - int "TP IRQ pin number" - default 45 - config BSP_TP_MOSI_PIN - int "TP MOSI pin number" - default 46 - -endif - diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Kconfig new file mode 100644 index 000000000..fdc67b1ac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Kconfig @@ -0,0 +1,19 @@ +if BSP_USING_HWTIMER + config HWTIMER_BUS_NAME_1 + string "hwtimer bus name" + default "hwtim1" + + menuconfig ENABLE_TIM1 + bool "enable TIM1" + default y + + if ENABLE_TIM1 + config HWTIMER_1_DEVICE_NAME_1 + string "TIM1 dev name" + default "hwtim1_dev1" + + config HWTIMER_DRIVER_NAME_1 + string "TIM1 drv name" + default "hwtim1_drv" + endif +endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Makefile new file mode 100644 index 000000000..24d4ccfac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Makefile @@ -0,0 +1,5 @@ +SRC_FILES := hardware_hwtimer.c connect_hwtimer.c + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/connect_hwtimer.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/connect_hwtimer.c new file mode 100644 index 000000000..7a7d23c08 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/connect_hwtimer.c @@ -0,0 +1,153 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_hwtimer.c +* @brief support aiit-riscv64-board hwtimer function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include +#include + +static struct HwtimerCallBackInfo *ptim2_cb_info = NULL; + +int timer_callback(void *ctx) +{ + if (ptim2_cb_info) { + if (ptim2_cb_info->timeout_callback) { + ptim2_cb_info->timeout_callback(ptim2_cb_info->param); + } + } + return 0; +} + +uint32 HwtimerOpen(void *dev) +{ + struct HwtimerHardwareDevice *hwtimer_dev = dev; + + ptim2_cb_info = &hwtimer_dev->hwtimer_param.cb_info; + + plic_init(); + sysctl_enable_irq(); + timer_init(TIMER_DEVICE_1); + + size_t real_time = timer_set_interval(TIMER_DEVICE_1, TIMER_CHANNEL_1, hwtimer_dev->hwtimer_param.period_millisecond *1000); + KPrintf("timer_set_interval -- real_time : %ld\n", real_time); + timer_irq_register(TIMER_DEVICE_1, TIMER_CHANNEL_1, !hwtimer_dev->hwtimer_param.repeat, 1, timer_callback, NULL); + + timer_set_enable(TIMER_DEVICE_1, TIMER_CHANNEL_1, 1); + + return EOK; +} + +uint32 HwtimerClose(void *dev) +{ + timer_set_enable(TIMER_DEVICE_1, TIMER_CHANNEL_1, 0); + + return EOK; +} + +/*manage the hwtimer device operations*/ +static const struct HwtimerDevDone dev_done = +{ + .open = HwtimerOpen, + .close = HwtimerClose, + .write = NONE, + .read = NONE, +}; + +/*Init hwtimer bus*/ +static int BoardHwtimerBusInit(struct HwtimerBus *hwtimer_bus, struct HwtimerDriver *hwtimer_driver) +{ + x_err_t ret = EOK; + + /*Init the hwtimer bus */ + ret = HwtimerBusInit(hwtimer_bus, HWTIMER_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_hwtimer_init HwtimerBusInit error %d\n", ret); + return ERROR; + } + + /*Init the hwtimer driver*/ + hwtimer_driver->configure = NONE; + ret = HwtimerDriverInit(hwtimer_driver, HWTIMER_DRIVER_NAME_1); + if (EOK != ret) { + KPrintf("board_hwtimer_init HwtimerDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the hwtimer driver to the hwtimer bus*/ + ret = HwtimerDriverAttachToBus(HWTIMER_DRIVER_NAME_1, HWTIMER_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_hwtimer_init USEDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the hwtimer device to the hwtimer bus*/ +static int BoardHwtimerDevBend(void) +{ + x_err_t ret = EOK; + static struct HwtimerHardwareDevice hwtimer_device_0; + memset(&hwtimer_device_0, 0, sizeof(struct HwtimerHardwareDevice)); + + hwtimer_device_0.dev_done = &dev_done; + + ret = HwtimerDeviceRegister(&hwtimer_device_0, NONE, HWTIMER_1_DEVICE_NAME_1); + if (EOK != ret) { + KPrintf("BoardHwtimerDevBend HwtimerDeviceRegister device %s error %d\n", HWTIMER_1_DEVICE_NAME_1, ret); + return ERROR; + } + + ret = HwtimerDeviceAttachToBus(HWTIMER_1_DEVICE_NAME_1, HWTIMER_BUS_NAME_1); + if (EOK != ret) { + KPrintf("BoardHwtimerDevBend HwtimerDeviceAttachToBus device %s error %d\n", HWTIMER_1_DEVICE_NAME_1, ret); + return ERROR; + } + + return ret; +} + +/*K210 BOARD HWTIMER INIT*/ +int HwTimerInit(void) +{ + x_err_t ret = EOK; + static struct HwtimerBus hwtimer_bus; + memset(&hwtimer_bus, 0, sizeof(struct HwtimerBus)); + + static struct HwtimerDriver hwtimer_driver; + memset(&hwtimer_driver, 0, sizeof(struct HwtimerDriver)); + + ret = BoardHwtimerBusInit(&hwtimer_bus, &hwtimer_driver); + if (EOK != ret) { + KPrintf("board_hwtimer_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardHwtimerDevBend(); + if (EOK != ret) { + KPrintf("board_hwtimer_Init error ret %u\n", ret); + return ERROR; + } + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/hardware_hwtimer.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/hardware_hwtimer.c new file mode 100644 index 000000000..62fcd84ac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/hardware_hwtimer.c @@ -0,0 +1,407 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed 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. + */ + +/** +* @file hardware_hwtimer.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @brief Private definitions for the timer instance + */ +typedef struct timer_instance +{ + timer_callback_t callback; + void *ctx; + bool single_shot; +} timer_instance_t; + +typedef void(*irq_manager_callback_t)(int irq, void* arg); + +volatile timer_instance_t timer_instance[TIMER_DEVICE_MAX][TIMER_CHANNEL_MAX]; + +volatile kendryte_timer_t *const timer[3] = +{ + (volatile kendryte_timer_t *)TIMER0_BASE_ADDR, + (volatile kendryte_timer_t *)TIMER1_BASE_ADDR, + (volatile kendryte_timer_t *)TIMER2_BASE_ADDR +}; + +void timer_init(timer_device_number_t timer_number) +{ + for(size_t i = 0; i < TIMER_CHANNEL_MAX; i++) + timer_instance[timer_number][i] = (const timer_instance_t) { + .callback = NULL, + .ctx = NULL, + .single_shot = 0, + }; + + sysctl_clock_enable(SYSCTL_CLOCK_TIMER0 + timer_number); +} + +void timer_set_clock_div(timer_device_number_t timer_number, uint32_t div) +{ + sysctl_clock_set_threshold(timer_number == 0 ? SYSCTL_THRESHOLD_TIMER0 : + timer_number == 1 ? SYSCTL_THRESHOLD_TIMER1 : + SYSCTL_THRESHOLD_TIMER2, div); +} + +void timer_enable(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control |= TIMER_CR_ENABLE; +} + +void timer_disable(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control &= (~TIMER_CR_ENABLE); +} + +void timer_enable_pwm(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control |= TIMER_CR_PWM_ENABLE; +} + +void timer_disable_pwm(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control &= (~TIMER_CR_PWM_ENABLE); +} + +void timer_enable_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control &= (~TIMER_CR_INTERRUPT_MASK); +} + +void timer_disable_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control |= TIMER_CR_INTERRUPT_MASK; +} + +void timer_set_mode(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t mode) +{ + timer[timer_number]->channel[channel].control &= (~TIMER_CR_MODE_MASK); + timer[timer_number]->channel[channel].control |= mode; +} + +void timer_set_reload(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t count) +{ + timer[timer_number]->channel[channel].load_count = count; +} + +void timer_set_reload2(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t count) +{ + timer[timer_number]->load_count2[channel] = count; +} + +uint32_t timer_get_count(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + return timer[timer_number]->channel[channel].current_value; +} + +uint32_t timer_get_reload(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + return timer[timer_number]->channel[channel].load_count; +} + +uint32_t timer_get_reload2(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + return timer[timer_number]->load_count2[channel]; +} + +uint32_t timer_get_interrupt_status(timer_device_number_t timer_number) +{ + return timer[timer_number]->intr_stat; +} + +uint32_t timer_get_raw_interrupt_status(timer_device_number_t timer_number) +{ + return timer[timer_number]->raw_intr_stat; +} + +uint32_t timer_channel_get_interrupt_status(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + return timer[timer_number]->channel[channel].intr_stat; +} + +void timer_clear_interrupt(timer_device_number_t timer_number) +{ + timer[timer_number]->eoi = timer[timer_number]->eoi; +} + +void timer_channel_clear_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].eoi = timer[timer_number]->channel[channel].eoi; +} + +void timer_set_enable(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t enable) +{ + if (enable) + timer[timer_number]->channel[channel].control = TIMER_CR_USER_MODE | TIMER_CR_ENABLE; + else + timer[timer_number]->channel[channel].control = TIMER_CR_INTERRUPT_MASK; +} + +size_t timer_set_interval(timer_device_number_t timer_number, timer_channel_number_t channel, size_t useconds) +{ + uint32_t clk_freq = SysctlClockGetFreq(SYSCTL_CLOCK_TIMER0 + timer_number); + + double min_step = 1e6 / clk_freq; + size_t value = (size_t)(useconds / min_step); + configASSERT(value > 0 && value < UINT32_MAX); + timer[timer_number]->channel[channel].load_count = (uint32_t)value; + return (size_t)(min_step * value); +} + +typedef void(*timer_ontick)(); +timer_ontick time_irq[3][4] = { NULL }; + +static int timer_isr(void *parm) +{ + uint32_t timer_number; + for (timer_number = 0; timer_number < 3; timer_number++) + { + if (parm == timer[timer_number]) + break; + } + + uint32_t channel = timer[timer_number]->intr_stat; + size_t i = 0; + for (i = 0; i < 4; i++) + { + if (channel & 1) + { + if (time_irq[timer_number][i]) + (time_irq[timer_number][i])(); + break; + } + + channel >>= 1; + } + + readl(&timer[timer_number]->eoi); + return 0; +} + +void timer_set_irq(timer_device_number_t timer_number, timer_channel_number_t channel, void(*func)(), uint32_t priority) +{ + time_irq[timer_number][channel] = func; + if (channel < 2) + { + plic_set_priority(IRQN_TIMER0A_INTERRUPT + timer_number * 2, priority); + plic_irq_register(IRQN_TIMER0A_INTERRUPT + timer_number * 2, timer_isr, (void *)timer[timer_number]); + plic_irq_enable(IRQN_TIMER0A_INTERRUPT + timer_number * 2); + } + else + { + plic_set_priority(IRQN_TIMER0B_INTERRUPT + timer_number * 2, priority); + plic_irq_register(IRQN_TIMER0B_INTERRUPT + timer_number * 2, timer_isr, (void *)timer[timer_number]); + plic_irq_enable(IRQN_TIMER0B_INTERRUPT + timer_number * 2); + } +} + +/** + * @brief Get the timer irqn by device and channel object + * + * @note Internal function, not public + * @param device The device + * @param channel The channel + * @return plic_irq_t IRQ number + */ +static plic_irq_t get_timer_irqn_by_device_and_channel(timer_device_number_t device, timer_channel_number_t channel) +{ + if (device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX) { + /* + * Select timer interrupt part + * Hierarchy of Timer interrupt to PLIC + * +---------+ +-----------+ + * | 0+----+ | | + * | | +--+0A | + * | 1+----+ | | + * | TIMER0 | | | + * | 2+----+ | | + * | | +--+0B | + * | 3+----+ | | + * +---------+ | | + * | | + * +---------+ | | + * | 0+----+ | | + * | | +--+1A | + * | 1+----+ | | + * | TIMER1 | | PLIC | + * | 2+----+ | | + * | | +--+1B | + * | 3+----+ | | + * +---------+ | | + * | | + * +---------+ | | + * | 0+----+ | | + * | | +--+2A | + * | 1+----+ | | + * | TIMER2 | | | + * | 2+----+ | | + * | | +--+2B | + * | 3+----+ | | + * +---------+ +-----------+ + * + */ + if (channel < 2) { + /* It is part A interrupt, offset + 0 */ + return IRQN_TIMER0A_INTERRUPT + device * 2; + } + else { + /* It is part B interrupt, offset + 1 */ + return IRQN_TIMER0B_INTERRUPT + device * 2; + } + } + return IRQN_NO_INTERRUPT; +} + +/** + * @brief Process user callback function + * + * @note Internal function, not public + * @param device The timer device + * @param ctx The context + * @return int The callback result + */ +static int timer_interrupt_handler(timer_device_number_t device, void *ctx) +{ + uint32_t channel_int_stat = timer[device]->intr_stat; + + for (size_t i = 0; i < TIMER_CHANNEL_MAX; i++) + { + /* Check every bit for interrupt status */ + if (channel_int_stat & 1) + { + if (timer_instance[device][i].callback) { + /* Process user callback function */ + timer_instance[device][i].callback(timer_instance[device][i].ctx); + /* Check if this timer is a single shot timer */ + if (timer_instance[device][i].single_shot) { + /* Single shot timer, disable it */ + timer_set_enable(device, i, 0); + } + } + /* Clear timer interrupt flag for specific channel */ + readl(&timer[device]->channel[i].eoi); + } + channel_int_stat >>= 1; + } + + /* + * NOTE: + * Don't read timer[device]->eoi here, or you will lost some interrupt + * readl(&timer[device]->eoi); + */ + + return 0; +} + +/** + * @brief Callback function bus for timer interrupt + * + * @note Internal function, not public + * @param ctx The context + * @return int The callback result + */ +static void timer0_interrupt_callback(int irq, void *ctx) +{ + timer_interrupt_handler(TIMER_DEVICE_0, ctx); +} + +/** + * @brief Callback function bus for timer interrupt + * + * @note Internal function, not public + * @param ctx The context + * @return int The callback result + */ +static void timer1_interrupt_callback(int irq, void *ctx) +{ + timer_interrupt_handler(TIMER_DEVICE_1, ctx); +} + +/** + * @brief Callback function bus for timer interrupt + * + * @note Internal function, not public + * @param ctx The context + * @return int The callback result + */ +static void timer2_interrupt_callback(int irq, void *ctx) +{ + timer_interrupt_handler(TIMER_DEVICE_2, ctx); +} + +int timer_irq_register(timer_device_number_t device, timer_channel_number_t channel, int is_single_shot, uint32_t priority, timer_callback_t callback, void *ctx) +{ + if (device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX) { + plic_irq_t irq_number = get_timer_irqn_by_device_and_channel(device, channel); + irq_manager_callback_t plic_irq_callback[TIMER_DEVICE_MAX] = { + timer0_interrupt_callback, + timer1_interrupt_callback, + timer2_interrupt_callback, + }; + + timer_instance[device][channel] = (const timer_instance_t) { + .callback = callback, + .ctx = ctx, + .single_shot = is_single_shot, + }; + + // plic_set_priority(irq_number, priority); + // plic_irq_register(irq_number, plic_irq_callback[device], (void *)&timer_instance[device]); + // plic_irq_enable(irq_number); + + isrManager.done->registerIrq(irq_number, plic_irq_callback[device], NULL); + isrManager.done->enableIrq(irq_number); + return 0; + } + return -1; +} + +int timer_irq_unregister(timer_device_number_t device, timer_channel_number_t channel) +{ + if (device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX) { + timer_instance[device][channel] = (const timer_instance_t) { + .callback = NULL, + .ctx = NULL, + .single_shot = 0, + }; + + /* Combine 0 and 1 to A interrupt, 2 and 3 to B interrupt */ + if ((!(timer_instance[device][TIMER_CHANNEL_0].callback || + timer_instance[device][TIMER_CHANNEL_1].callback)) || + (!(timer_instance[device][TIMER_CHANNEL_2].callback || + timer_instance[device][TIMER_CHANNEL_3].callback))) { + plic_irq_t irq_number = get_timer_irqn_by_device_and_channel(device, channel); + plic_irq_unregister(irq_number); + } + return 0; + } + return -1; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/Kconfig index e669ed7e6..c2b9193a0 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/Kconfig @@ -10,8 +10,8 @@ if BSP_USING_TOUCH default "touch_dev" config BSP_TOUCH_TP_INT int "touch int pin" - default 36 + default 30 config FPIOA_TOUCH_TP_INT int "fpioa touch int pin" - default 12 + default 30 endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/connect_touch.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/connect_touch.c index c97b68dc8..2f95c371e 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/connect_touch.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/connect_touch.c @@ -24,21 +24,33 @@ #include #include #include +#include "gsl2038firmware.h" + + +struct Finger { + uint8_t fingerID; + uint32_t x; + uint32_t y; +}; +struct Touch_event { + uint8_t NBfingers; + struct Finger fingers[5]; +}; -// #define LCD_HEIGHT BSP_LCD_X_MAX -// #define LCD_WIDTH BSP_LCD_Y_MAX #define DEFAULT_NUM 0x0D - +#define TOUCH_ADDRESS 0x44 volatile bool SemReleaseFlag = 0; static struct Bus* i2c_bus = NONE; static struct Bus* pin_bus = NONE; int touch_sem = 0; -POINT Pre_Touch_Point; + +#define DATA_REG 0x80 +#define STATUS_REG 0xE0 /* HERE WE IMPLEMENT I2C READING AND WRITING FROM SENSOR */ /* write sensor register data */ -static x_err_t WriteReg(struct HardwareDev* dev, uint8 len, uint8* buf) +static x_err_t WriteReg(struct HardwareDev* dev, char* buf, int len) { struct BusBlockWriteParam write_param; write_param.pos = 0; @@ -62,150 +74,10 @@ static x_err_t ReadRegs(struct HardwareDev* dev, uint8 len, uint8* buf) return BusDevReadData(dev, &read_param); } -/** - * i2c_transfer - execute a single I2C message - * @msgs: One or more messages to execute before STOP is issued to - * terminate the operation; each message begins with a START. - */ -int I2C_Transfer(struct i2c_msg* msg) -{ - int16 ret = 0; - - if (msg->flags & I2C_M_RD) //根据flag判断是读数据还是写数据 - { - ret = ReadRegs(i2c_bus->owner_haldev, msg->len, msg->buf); //IIC读取数据 - } - else - { - ret = WriteReg(i2c_bus->owner_haldev, msg->len, msg->buf); //IIC写入数据 - } //正常完成的传输结构个数 - - return ret; -} - -static int32_t GtpI2cWrite(uint8_t* buf, int32_t len) -{ - struct i2c_msg msg; - int32_t ret = -1; - int32_t retries = 0; - - msg.flags = !I2C_M_RD; - msg.len = len; - msg.buf = buf; - //msg.scl_rate = 300 * 1000; // for Rockchip, etc - while (retries < 5) - { - ret = I2C_Transfer(&msg); - if (ret == 1) { break; } - retries++; - } - if (retries >= 5) - { - KPrintf("I2C Write: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((uint16_t)(buf[0] << 8)) | buf[1]), len - 2, ret); - ret = -1; - } - return ret; -} -static int32_t GtpI2cRead(uint8_t* buf, int32_t len) -{ - struct i2c_msg msgs[2]; - int32_t ret = -1; - int32_t retries = 0; - - // write reading addr. - msgs[0].flags = !I2C_M_RD; - msgs[0].len = GTP_ADDR_LENGTH; - msgs[0].buf = buf; - - // read data at addr sended. - msgs[1].flags = I2C_M_RD; - msgs[1].len = len - GTP_ADDR_LENGTH; - msgs[1].buf = &buf[GTP_ADDR_LENGTH]; - - while (retries < 5) - { - ret = I2C_Transfer(&msgs[0]); - ret += I2C_Transfer(&msgs[1]); - if (ret == 2)break; - retries++; - } - if (retries >= 5) - { - KPrintf("I2C Read: 0x%04X, %d bytes %d times failed, errcode: %d! Process reset.\n", (((uint16_t)(buf[0] << 8)) | buf[1]), len - 2, retries, ret); - ret = -1; - } - return ret; -} - -/* HERE WE IMPLEMENT TOUCH INIT */ -int32_t GtpReadVersion(void) -{ - int32_t ret = -1; - uint8_t buf[8] = { GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff }; - - ret = GtpI2cRead(buf, sizeof(buf)); - if (ret < 0) - { - KPrintf("GTP read version failed.\n"); - return ret; - } - - if (buf[5] == 0x00) - { - KPrintf("IC1 Version: %c%c%c_%02x%02x\n", buf[2], buf[3], buf[4], buf[7], buf[6]); - } - else - { - KPrintf("IC2 Version: %c%c%c%c_%02x%02x\n", buf[2], buf[3], buf[4], buf[5], buf[7], buf[6]); - } - return ret; -} - -static int32_t GtpGetInfo(void) -{ - uint8_t end_cmd[3] = { GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0 }; - uint8_t opr_buf[6] = { 0 }; - int32_t ret = 0; - - uint16_t abs_x_max = GTP_MAX_WIDTH; - uint16_t abs_y_max = GTP_MAX_HEIGHT; - uint8_t int_trigger_type = GTP_INT_TRIGGER; - - opr_buf[0] = (uint8_t)((GTP_REG_CONFIG_DATA + 1) >> 8); - opr_buf[1] = (uint8_t)((GTP_REG_CONFIG_DATA + 1) & 0xFF); - - if (GtpI2cRead(opr_buf, 6) < 0) - { - return -1; - } - - abs_x_max = (opr_buf[3] << 8) + opr_buf[2]; - abs_y_max = (opr_buf[5] << 8) + opr_buf[4]; - - opr_buf[0] = (uint8_t)((GTP_REG_CONFIG_DATA + 6) >> 8); - opr_buf[1] = (uint8_t)((GTP_REG_CONFIG_DATA + 6) & 0xFF); - - if (GtpI2cRead(opr_buf, 3) < 0) - { - return 0; - } - - int_trigger_type = opr_buf[2] & 0x03; - KPrintf("X_MAX = %d, Y_MAX = %d, TRIGGER = 0x%02x\n", - abs_x_max, abs_y_max, int_trigger_type); - - if (GtpI2cWrite(end_cmd, 3) < 0) - { - KPrintf("I2C write end_cmd error!\n"); - ret = 0; - } - return 0; ; -} - // not used in polling mode -static void GT9xx_PEN_IRQHandler(void* arg) +static void touch_pin_irqhandler(void* arg) { - KPrintf("int hdr working.\n"); + // KPrintf("int hdr working.\n"); if (!SemReleaseFlag) { KSemaphoreAbandon(touch_sem); @@ -213,20 +85,20 @@ static void GT9xx_PEN_IRQHandler(void* arg) } } -int32_t GT9xx_INT_INIT() { +int32_t touch_irq_init() +{ int32_t ret = -ERROR; - - pin_bus = PinBusInitGet(); - struct PinParam pin_param; struct BusConfigureInfo pin_configure_info; + pin_bus = PinBusInitGet(); + pin_configure_info.configure_cmd = OPE_CFG; pin_configure_info.private_data = (void*)&pin_param; pin_param.cmd = GPIO_CONFIG_MODE; pin_param.pin = BSP_TOUCH_TP_INT; - pin_param.mode = GPIO_CFG_INPUT_PULLUP; + pin_param.mode = GPIO_CFG_INPUT; ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); if (ret != EOK) { KPrintf("config pin_param %d input failed!\n", pin_param.pin); @@ -235,8 +107,8 @@ int32_t GT9xx_INT_INIT() { pin_param.cmd = GPIO_IRQ_REGISTER; pin_param.pin = BSP_TOUCH_TP_INT; - pin_param.irq_set.irq_mode = GPIO_IRQ_EDGE_FALLING; - pin_param.irq_set.hdr = GT9xx_PEN_IRQHandler; + pin_param.irq_set.irq_mode = GPIO_IRQ_EDGE_BOTH; + pin_param.irq_set.hdr = touch_pin_irqhandler; pin_param.irq_set.args = NONE; ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); if (ret != EOK) { @@ -264,7 +136,7 @@ int32_t GT9xx_INT_INIT() { return EOK; } -int32_t I2C_Touch_Init() { +int32_t I2cTouchInit() { // using static bus information int32_t ret = -1; /* find I2C device and get I2C handle */ @@ -294,116 +166,68 @@ int32_t I2C_Touch_Init() { // memset(&i2c_configure_info, 0, sizeof(struct BusConfigureInfo)); i2c_configure_info.configure_cmd = OPE_INT; - uint16 i2c_address = GTP_ADDRESS >> 1; + uint16 i2c_address = TOUCH_ADDRESS; i2c_configure_info.private_data = (void*)&i2c_address; BusDrvConfigure(i2c_bus->owner_driver, &i2c_configure_info); // 3. init interruption - return GT9xx_INT_INIT(); + return touch_irq_init(); } - -/* HERE WE IMPLEMENT GET COORDINATE FUNCTION */ -/** - * @brief 触屏处理函数,轮询或者在触摸中断调用 - * @param 无 - * @retval 无 - */ -bool GetTouchEvent(POINT* touch_point, touch_event_t* touch_event) +void loadfw(struct HardwareDev *dev) { + uint8_t addr; + uint8_t Wrbuf[5]; + size_t source_len = sizeof(GSL2038_FW) / sizeof(struct fw_data); + + for (size_t source_line = 0; source_line < source_len; source_line++) { + // addr = GSL2038_FW[source_line].offset; + memset(Wrbuf, 0 , 5); + Wrbuf[0] = GSL2038_FW[source_line].offset; + Wrbuf[1] = (char)(GSL2038_FW[source_line].val & 0x000000ff); + Wrbuf[2] = (char)((GSL2038_FW[source_line].val & 0x0000ff00) >> 8); + Wrbuf[3] = (char)((GSL2038_FW[source_line].val & 0x00ff0000) >> 16); + Wrbuf[4] = (char)((GSL2038_FW[source_line].val & 0xff000000) >> 24); - uint8_t end_cmd[3] = { GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0 }; - uint8_t point_data[2 + 1 + 8 * GTP_MAX_TOUCH + 1] = { GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF }; - uint8_t touch_num = 0; - uint8_t finger = 0; - static uint16_t pre_touch = 0; - - uint8_t* coor_data = NULL; - int32_t input_x = 0; - int32_t input_y = 0; - int32_t input_w = 0; - - int32_t ret = -1; - - ret = GtpI2cRead(point_data, 12);//10字节寄存器加2字节地址 - if (ret < 0) - { - KPrintf("I2C transfer error. errno:%d\n ", ret); - return 0; + WriteReg(dev, Wrbuf,5); } +} - finger = point_data[GTP_ADDR_LENGTH];//状态寄存器数据 +void reset() +{ + uint8_t REG[6] = {STATUS_REG, 0xE4, 0xbc, 0xbd, 0xbe, 0xbf}; + uint8_t DATA[6] = {0x88, 0x04, 0x00, 0x00, 0x00, 0x00}; + char reg_data[2]; - if (finger == 0x00) //没有数据,退出 + int i; + for (i = 0; i < sizeof(REG); ++i) { - ret = 0; - goto exit_work_func; + // WriteReg(i2c_bus->owner_haldev, ®[i],1); + // WriteReg(i2c_bus->owner_haldev, &DATA[i],1); + reg_data[0] = REG[i]; + reg_data[1] = DATA[i]; + WriteReg(i2c_bus->owner_haldev, reg_data,2); + MdelayKTask(10); } +} - if ((finger & 0x80) == 0)//判断buffer status位 - { - ret = 0; - goto exit_work_func;//坐标未就绪,数据无效 - } +void startchip() +{ + char reg_data[] = {0xE0, 0x00}; - touch_num = finger & 0x0f;//坐标点数 - if (touch_num > GTP_MAX_TOUCH) - { - ret = 0; - goto exit_work_func;//大于最大支持点数,错误退出 - } - - if (touch_num) - { - coor_data = &point_data[0 * 8 + 3]; - input_x = coor_data[1] | (coor_data[2] << 8); //x坐标 - input_y = coor_data[3] | (coor_data[4] << 8); //y坐标 - input_w = coor_data[5] | (coor_data[6] << 8); //size - touch_point->X = input_x; - touch_point->Y = input_y; - *touch_event = kTouch_Down; - Pre_Touch_Point = *touch_point; - - } - else if (pre_touch) //touch_ num=0 且pre_touch!=0 - { - *touch_point = Pre_Touch_Point; - *touch_event = kTouch_Up; - Pre_Touch_Point.X = -1; - Pre_Touch_Point.Y = -1; - } - pre_touch = touch_num; - -exit_work_func: - { - ret = GtpI2cWrite(end_cmd, 3); - if (ret < 0) - { - KPrintf("I2C write end_cmd error!\n"); - ret = 0; - } - } - return ret; + WriteReg(i2c_bus->owner_haldev, reg_data,2); // Registre } static uint32 TouchOpen(void* dev) { - int32_t ret = -1; + int32_t ret = 0; - I2C_Touch_Init(); - ret = GtpReadVersion(); - if (ret < 0) - { - KPrintf("gtp read version error\n"); - return ret; - } + I2cTouchInit(); - ret = GtpGetInfo(); - if (ret < 0) - { - KPrintf("gtp read info error\n"); - return ret; - } + reset(); + loadfw(i2c_bus->owner_haldev); + reset(); + startchip(); touch_sem = KSemaphoreCreate(0); if (touch_sem < 0) { @@ -415,8 +239,32 @@ static uint32 TouchOpen(void* dev) } static uint32 TouchClose(void* dev) -{ +{ + int32_t ret = -ERROR; + struct PinParam pin_param; + struct BusConfigureInfo pin_configure_info; + + pin_configure_info.configure_cmd = OPE_CFG; + pin_configure_info.private_data = (void*)&pin_param; + + pin_param.cmd = GPIO_IRQ_DISABLE; + pin_param.pin = BSP_TOUCH_TP_INT; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("disable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_FREE; + pin_param.pin = BSP_TOUCH_TP_INT; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("register pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + KSemaphoreDelete(touch_sem); + return 0; } @@ -424,23 +272,35 @@ static uint32 TouchRead(void* dev, struct BusBlockReadParam* read_param) { uint32 ret = -1; x_err_t result; - POINT touch_point; - touch_point.X = -1; - touch_point.Y = -1; - touch_event_t touch_event; + uint8_t TOUCHRECDATA[24] = {0}; + struct Touch_event ts_event; + char status_reg = 0x80; struct TouchDataStandard* data = (struct TouchDataStandard*)read_param->buffer; read_param->read_length = 0; - result = KSemaphoreObtain(touch_sem, 100); - if (GetTouchEvent(&touch_point, &touch_event)) - { - data->x = touch_point.X; - data->y = touch_point.Y; + result = KSemaphoreObtain(touch_sem, 1000); + // if (EOK == result) + // { + memset(TOUCHRECDATA, 0, 24); + memset(&ts_event, 0, sizeof(struct Touch_event)); - read_param->read_length = read_param->size; - ret = EOK; - } - SemReleaseFlag = 0; + WriteReg(i2c_bus->owner_haldev, &status_reg, 1); + ReadRegs(i2c_bus->owner_haldev, 24, TOUCHRECDATA); + ts_event.NBfingers = TOUCHRECDATA[0]; + + for (int i = 0; i < ts_event.NBfingers; i++) + { + ts_event.fingers[i].x = ((((uint32_t)TOUCHRECDATA[(i * 4) + 5]) << 8) | (uint32_t)TOUCHRECDATA[(i * 4) + 4]) & 0x00000FFF; // 12 bits of X coord + ts_event.fingers[i].y = ((((uint32_t)TOUCHRECDATA[(i * 4) + 7]) << 8) | (uint32_t)TOUCHRECDATA[(i * 4) + 6]) & 0x00000FFF; + ts_event.fingers[i].fingerID = (uint32_t)TOUCHRECDATA[(i * 4) + 7] >> 4; // finger that did the touch + printf("fingers[%d] x %d y %d id %d\n",i,ts_event.fingers[i].x,ts_event.fingers[i].y,ts_event.fingers[i].fingerID); + } + + data->x = ts_event.fingers[ts_event.NBfingers - 1].x; + data->y = ts_event.fingers[ts_event.NBfingers - 1].y; + + SemReleaseFlag = 0; + // } return ret; } diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/gsl2038firmware.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/gsl2038firmware.h new file mode 100644 index 000000000..d21c2e295 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/gsl2038firmware.h @@ -0,0 +1,5009 @@ +/**************************************************************************/ +/*! + @file gsl2038firmware.h + + @thanks to wireless-tag-com for the source code this firmware : https://github.com/wireless-tag-com/8ms-esp32 +*/ + +#ifndef _GSL2038_H_ +#define _GSL2038_H_ + +struct fw_data +{ + uint8_t offset; + uint32_t val; +}; + + +const struct fw_data GSL2038_FW[] = { +//GSL_2038 +{0xf0,0x2}, +{0x00,0x00000000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00000000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00000000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00000000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x000f000f}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0xf801000a}, +{0x68,0x04066414}, +{0x6c,0x1001020c}, +{0x70,0x00000fff}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x0c020c02}, +{0xf0,0x3}, +{0x00,0xb5cbfdad}, +{0x04,0x00000000}, +{0x08,0x00400000}, +{0x0c,0x00800000}, +{0x10,0x40020000}, +{0x14,0x00000000}, +{0x18,0xff380801}, +{0x1c,0x00000000}, +{0x20,0x00000000}, +{0x24,0x00005100}, +{0x28,0x00008e00}, +{0x2c,0x00000000}, +{0x30,0x0001005d}, +{0x34,0x007d00c6}, +{0x38,0x00e60140}, +{0x3c,0x00000000}, +{0x40,0x00010001}, +{0x44,0x0035010a}, +{0x48,0x01400140}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00000080}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0x1a0ac00a}, +{0x68,0x00000002}, +{0x6c,0x0000000f}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0xffffffec}, +{0x7c,0x00000000}, +{0xf0,0x4}, +{0x00,0x00000000}, +{0x04,0x0000b306}, +{0x08,0x00000064}, +{0x0c,0x00000fff}, +{0x10,0xfe0cff06}, +{0x14,0x00020008}, +{0x18,0x0000008c}, +{0x1c,0x03030800}, +{0x20,0x000800c0}, +{0x24,0x00000000}, +{0x28,0x80808080}, +{0x2c,0x00000000}, +{0x30,0x00010000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00007fff}, +{0x44,0x0040002d}, +{0x48,0x00007fff}, +{0x4c,0x0040002d}, +{0x50,0x0c182430}, +{0x54,0x0c182430}, +{0x58,0x0c182430}, +{0x5c,0x0c182430}, +{0x60,0x0005000c}, +{0x64,0x00190037}, +{0x68,0x00020004}, +{0x6c,0x0008000c}, +{0x70,0x0005000c}, +{0x74,0x00190037}, +{0x78,0x0005000c}, +{0x7c,0x00190044}, +{0xf0,0x5}, +{0x00,0x0000000a}, +{0x04,0x00000001}, +{0x08,0x0000012c}, +{0x0c,0x00000000}, +{0x10,0x0000000a}, +{0x14,0x00000000}, +{0x18,0x00000fff}, +{0x1c,0x10000000}, +{0x20,0x13520042}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000400}, +{0x30,0x00000200}, +{0x34,0x1234c878}, +{0x38,0x00000001}, +{0x3c,0x00000000}, +{0x40,0x00000000}, +{0x44,0x1f808014}, +{0x48,0x03000200}, +{0x4c,0x012c044c}, +{0x50,0x00000000}, +{0x54,0x10000050}, +{0x58,0x00010002}, +{0x5c,0x00000000}, +{0x60,0x80808080}, +{0x64,0x00000000}, +{0x68,0x00000080}, +{0x6c,0x00000080}, +{0x70,0x00000011}, +{0x74,0x00000220}, +{0x78,0x00000002}, +{0x7c,0x0000000c}, +{0xf0,0x6}, +{0x00,0x0000000b}, +{0x04,0x00000000}, +{0x08,0x00000002}, +{0x0c,0x07030203}, +{0x10,0x00000032}, +{0x14,0x01080008}, +{0x18,0x00000000}, +{0x1c,0x00000001}, +{0x20,0x00002904}, +{0x24,0x00000140}, +{0x28,0x00000140}, +{0x2c,0xf801000a}, +{0x30,0xf8010008}, +{0x34,0x0000001f}, +{0x38,0x00000003}, +{0x3c,0x00000fff}, +{0x40,0x80000000}, +{0x44,0x00190019}, +{0x48,0x00000fff}, +{0x4c,0x05030203}, +{0x50,0x00000000}, +{0x54,0x000002a4}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x20100804}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00000000}, +{0x74,0x000000fa}, +{0x78,0x000a003c}, +{0x7c,0x00000000}, +{0xf0,0x7}, +{0x00,0x27292819}, +{0x04,0x03090208}, +{0x08,0x050b040a}, +{0x0c,0x07110610}, +{0x10,0x09130812}, +{0x14,0x00123456}, +{0x18,0x00000000}, +{0x1c,0x000a0078}, +{0x20,0x00001081}, +{0x24,0xff080010}, +{0x28,0xff080120}, +{0x2c,0xff080140}, +{0x30,0xff080160}, +{0x34,0x000002bc}, +{0x38,0x0000017d}, +{0x3c,0x00000142}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000001}, +{0x4c,0x320f0f03}, +{0x50,0x00000000}, +{0x54,0x00000002}, +{0x58,0x00040000}, +{0x5c,0x00090005}, +{0x60,0x000e000a}, +{0x64,0x0013000f}, +{0x68,0x00001000}, +{0x6c,0x0004003c}, +{0x70,0x00040000}, +{0x74,0x00040000}, +{0x78,0x00012345}, +{0x7c,0x00012345}, +{0xf0,0x8}, +{0x00,0x02090c13}, +{0x04,0x10170601}, +{0x08,0x0a0e15ff}, +{0x0c,0xffffffff}, +{0x10,0xffffffff}, +{0x14,0xffffffff}, +{0x18,0xffffffff}, +{0x1c,0xffffffff}, +{0x20,0x03081116}, +{0x24,0x0d120b04}, +{0x28,0x070f14ff}, +{0x2c,0xffffffff}, +{0x30,0xffffffff}, +{0x34,0xffffffff}, +{0x38,0xffffffff}, +{0x3c,0xffffffff}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00050004}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00000073}, +{0x74,0x000a0019}, +{0x78,0x10000001}, +{0x7c,0x0000000c}, +{0xf0,0x9}, +{0x00,0xff080078}, +{0x04,0x00ff0011}, +{0x08,0xff08007c}, +{0x0c,0xffc00000}, +{0x10,0xfffffff0}, +{0x14,0x00000000}, +{0x18,0xfffffff0}, +{0x1c,0x00000000}, +{0x20,0xfffffff0}, +{0x24,0x00000000}, +{0x28,0xfffffff0}, +{0x2c,0x00000000}, +{0x30,0xfffffff0}, +{0x34,0x00000000}, +{0x38,0xfffffff0}, +{0x3c,0x00000000}, +{0x40,0xfffffff0}, +{0x44,0x00000000}, +{0x48,0xfffffff0}, +{0x4c,0x00000000}, +{0x50,0xfffffff0}, +{0x54,0x00000000}, +{0x58,0xfffffff0}, +{0x5c,0x00000000}, +{0x60,0xfffffff0}, +{0x64,0x00000000}, +{0x68,0xfffffff0}, +{0x6c,0x00000000}, +{0x70,0xfffffff0}, +{0x74,0x00000000}, +{0x78,0xfffffff0}, +{0x7c,0x00000000}, +{0xf0,0x1a}, +{0x00,0x00000000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00000000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00020000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00020000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00020000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00020000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00020000}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00020000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x00000000}, +{0xf0,0x1b}, +{0x00,0x00020000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00020000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00020000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00020000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00020000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00020000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00020000}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00020000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x00000000}, +{0xf0,0x1c}, +{0x00,0x00009249}, +{0x04,0x02412492}, +{0x08,0x0481b6db}, +{0x0c,0x06c24924}, +{0x10,0x0902db6d}, +{0x14,0x0b436db6}, +{0x18,0x0d93ffff}, +{0x1c,0x00000000}, +{0x20,0x0000003f}, +{0x24,0x0000003f}, +{0x28,0x0000003f}, +{0x2c,0x0000003f}, +{0x30,0x0000003f}, +{0x34,0x0000003f}, +{0x38,0x0000003f}, +{0x3c,0x00000000}, +{0x40,0x7e7e7e7e}, +{0x44,0x7d7d7e7e}, +{0x48,0x7d7d7d7d}, +{0x4c,0x7b7b7b7b}, +{0x50,0x77777b7b}, +{0x54,0x77777777}, +{0x58,0x6f6f6f6f}, +{0x5c,0x5f5f6f6f}, +{0x60,0x5f5f5f5f}, +{0x64,0x3f3f3f3f}, +{0x68,0x00003f3f}, +{0x6c,0x00000000}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x5a5a5a5a}, +{0xf0,0x1d}, +{0x00,0x00013c4d}, +{0x04,0x024223ab}, +{0x08,0x048298f2}, +{0x0c,0x06c0d716}, +{0x10,0x0901c499}, +{0x14,0x0b436b64}, +{0x18,0x0d93ffff}, +{0x1c,0x00000000}, +{0x20,0x0000002d}, +{0x24,0x0000003f}, +{0x28,0x0000003f}, +{0x2c,0x0000003f}, +{0x30,0x00000000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x5f7e7e6f}, +{0x44,0x6f7b7d7b}, +{0x48,0x777d7e5f}, +{0x4c,0x777b5f7d}, +{0x50,0x7d5f6f7e}, +{0x54,0x7e6f7b77}, +{0x58,0x7d7d7b7e}, +{0x5c,0x77777b77}, +{0x60,0x5f5f6f6f}, +{0x64,0x3f3f3f3f}, +{0x68,0x00003f3f}, +{0x6c,0x00000000}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x5a5a5a5a}, + +/* +{0xf0,0xe0}, +{0x00,0x00000000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00000000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00000000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00000000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00780226}, +{0x44,0x00780078}, +{0x48,0x01b80078}, +{0x4c,0x007801b8}, +{0x50,0x00780078}, +{0x54,0x014a0078}, +{0x58,0x014a014a}, +{0x5c,0x0050014a}, +{0x60,0x00640000}, +{0x64,0x00640064}, +{0x68,0x0000003c}, +{0x6c,0x005a0000}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x00000000}, +*/ +{0xf0,0x1e}, +{0x00,0x5a5a0f00}, +{0x04,0x00003a24}, +{0x08,0x00003a94}, +{0x0c,0x00003c88}, +{0x10,0x00003e2c}, +{0x14,0x00003e60}, +{0x18,0x00004014}, +{0x1c,0x00004198}, +{0x20,0x00004384}, +{0x24,0x00004614}, +{0x28,0x00004754}, +{0x2c,0x00004810}, +{0x30,0x00004894}, +{0x34,0x0000498c}, +{0x38,0x00004c5c}, +{0x3c,0x00004d00}, +{0x40,0x00004eb4}, +{0x44,0x00005060}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x00000000}, +{0xf0,0x1f}, +{0x00,0x00000000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00000000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00000000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00000000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00002d70}, +{0x60,0x00003068}, +{0x64,0x000036e0}, +{0x68,0x00000000}, +{0x6c,0x0000374c}, +{0x70,0x00000000}, +{0x74,0x0000396c}, +{0x78,0x00005204}, +{0x7c,0x5a5a0ffc}, +{0xf0,0x0}, +{0x00,0x01000000}, +{0x04,0x01000000}, +{0x08,0x01000000}, +{0x0c,0x233fc0c0}, +{0x10,0xa2146004}, +{0x14,0xa4102000}, +{0x18,0xe4244000}, +{0x1c,0x233fc0c0}, +{0x20,0xa2146010}, +{0x24,0x2500003f}, +{0x28,0xa414a3ff}, +{0x2c,0xe4244000}, +{0x30,0x01000000}, +{0x34,0x821020e0}, +{0x38,0x81880001}, +{0x3c,0x01000000}, +{0x40,0x01000000}, +{0x44,0xa410200f}, +{0x48,0xe4a00040}, +{0x4c,0x01000000}, +{0x50,0xa0100000}, +{0x54,0xa2100000}, +{0x58,0xa4100000}, +{0x5c,0xa6100000}, +{0x60,0xa8100000}, +{0x64,0xaa100000}, +{0x68,0xac100000}, +{0x6c,0xae100000}, +{0x70,0x90100000}, +{0x74,0x92100000}, +{0x78,0x94100000}, +{0x7c,0x96100000}, +{0xf0,0x1}, +{0x00,0x98100000}, +{0x04,0x9a100000}, +{0x08,0x9c100000}, +{0x0c,0x9e100000}, +{0x10,0x84100000}, +{0x14,0x01000000}, +{0x18,0x01000000}, +{0x1c,0x82100000}, +{0x20,0x81900001}, +{0x24,0x82100000}, +{0x28,0x81980001}, +{0x2c,0x81800000}, +{0x30,0x01000000}, +{0x34,0x01000000}, +{0x38,0x01000000}, +{0x3c,0xbc102cfc}, +{0x40,0x9c102cf8}, +{0x44,0x01000000}, +{0x48,0x01000000}, +{0x4c,0x27001040}, +{0x50,0xa614e00f}, +{0x54,0xe6a00040}, +{0x58,0x01000000}, +{0x5c,0x400006ca}, +{0x60,0x01000000}, +{0x64,0x01000000}, +{0x68,0x10bfffff}, +{0x6c,0x01000000}, +{0x70,0x03169684}, +{0x74,0x82106053}, +{0x78,0x03296948}, +{0x7c,0x82106133}, +{0xf0,0x20}, +{0x00,0x83580000}, +{0x04,0x82086ff0}, +{0x08,0x83306004}, +{0x0c,0x80a06005}, +{0x10,0x02800027}, +{0x14,0x01000000}, +{0x18,0x80a06006}, +{0x1c,0x0280003c}, +{0x20,0x01000000}, +{0x24,0x80a06015}, +{0x28,0x02800054}, +{0x2c,0x01000000}, +{0x30,0x80a0602a}, +{0x34,0x02800090}, +{0x38,0x01000000}, +{0x3c,0x80a06018}, +{0x40,0x02800085}, +{0x44,0x01000000}, +{0x48,0x073fc180}, +{0x4c,0x8610e03c}, +{0x50,0x05169680}, +{0x54,0x84004002}, +{0x58,0xc420c000}, +{0x5c,0x073fc000}, +{0x60,0x8610e020}, +{0x64,0x84102001}, +{0x68,0xc420c000}, +{0x6c,0x0500000c}, +{0x70,0x01000000}, +{0x74,0x01000000}, +{0x78,0x8480bfff}, +{0x7c,0x12bffffe}, +{0xf0,0x21}, +{0x00,0x01000000}, +{0x04,0x01000000}, +{0x08,0x073fc000}, +{0x0c,0x8610e020}, +{0x10,0x84102000}, +{0x14,0xc420c000}, +{0x18,0x01000000}, +{0x1c,0x01000000}, +{0x20,0x81c44000}, +{0x24,0x81cc8000}, +{0x28,0x01000000}, +{0x2c,0xa7500000}, +{0x30,0xa92ce002}, +{0x34,0xa734e001}, +{0x38,0xa614c014}, +{0x3c,0xa60ce007}, +{0x40,0x81900000}, +{0x44,0x01000000}, +{0x48,0x01000000}, +{0x4c,0x81e00000}, +{0x50,0xe03ba000}, +{0x54,0xe43ba008}, +{0x58,0xe83ba010}, +{0x5c,0xec3ba018}, +{0x60,0xf03ba020}, +{0x64,0xf43ba028}, +{0x68,0xf83ba030}, +{0x6c,0xfc3ba038}, +{0x70,0x81e80000}, +{0x74,0x8194c000}, +{0x78,0x01000000}, +{0x7c,0x01000000}, +{0xf0,0x22}, +{0x00,0x81c44000}, +{0x04,0x81cc8000}, +{0x08,0x01000000}, +{0x0c,0xa7500000}, +{0x10,0xa934e002}, +{0x14,0xa72ce001}, +{0x18,0xa614c014}, +{0x1c,0xa60ce007}, +{0x20,0x81900000}, +{0x24,0x01000000}, +{0x28,0x01000000}, +{0x2c,0x81e80000}, +{0x30,0x81e80000}, +{0x34,0xe01ba000}, +{0x38,0xe41ba008}, +{0x3c,0xe81ba010}, +{0x40,0xec1ba018}, +{0x44,0xf01ba020}, +{0x48,0xf41ba028}, +{0x4c,0xf81ba030}, +{0x50,0xfc1ba038}, +{0x54,0x81e00000}, +{0x58,0x81e00000}, +{0x5c,0x8194c000}, +{0x60,0x01000000}, +{0x64,0x01000000}, +{0x68,0x81c44000}, +{0x6c,0x81cc8000}, +{0x70,0x01000000}, +{0x74,0x01000000}, +{0x78,0x82102010}, +{0x7c,0x273fc0c0}, +{0xf0,0x23}, +{0x00,0xa614e010}, +{0x04,0xc224c000}, +{0x08,0x01000000}, +{0x0c,0x033fc0c0}, +{0x10,0x82106004}, +{0x14,0xa6102000}, +{0x18,0xe6204000}, +{0x1c,0x01000000}, +{0x20,0x01000000}, +{0x24,0x01000000}, +{0x28,0xa6102020}, +{0x2c,0x83480000}, +{0x30,0x82104013}, +{0x34,0x81884000}, +{0x38,0x01000000}, +{0x3c,0x40000656}, +{0x40,0x01000000}, +{0x44,0x01000000}, +{0x48,0x01000000}, +{0x4c,0xa7500000}, +{0x50,0xa934e002}, +{0x54,0xa72ce001}, +{0x58,0xa614c014}, +{0x5c,0xa60ce007}, +{0x60,0x81900000}, +{0x64,0x01000000}, +{0x68,0x81e80000}, +{0x6c,0xe01ba000}, +{0x70,0xe41ba008}, +{0x74,0xe81ba010}, +{0x78,0xec1ba018}, +{0x7c,0xf01ba020}, +{0xf0,0x24}, +{0x00,0xf41ba028}, +{0x04,0xf81ba030}, +{0x08,0xfc1ba038}, +{0x0c,0x81e00000}, +{0x10,0x8194c000}, +{0x14,0x01000000}, +{0x18,0xa6102020}, +{0x1c,0x83480000}, +{0x20,0x82284013}, +{0x24,0x81884000}, +{0x28,0x01000000}, +{0x2c,0x033fc0c0}, +{0x30,0x82106004}, +{0x34,0xa6103fff}, +{0x38,0xe6204000}, +{0x3c,0x01000000}, +{0x40,0x01000000}, +{0x44,0x01000000}, +{0x48,0x81c44000}, +{0x4c,0x81cc8000}, +{0x50,0x01000000}, +{0x54,0x82102080}, +{0x58,0x273fc0c0}, +{0x5c,0xa614e010}, +{0x60,0xc224c000}, +{0x64,0x01000000}, +{0x68,0x81c44000}, +{0x6c,0x81cc8000}, +{0x70,0x01000000}, +{0x74,0x81c48000}, +{0x78,0x81cca004}, +{0x7c,0x01000000}, +{0xf0,0x25}, +{0x00,0x1b3fc140}, +{0x04,0x82136048}, +{0x08,0xc2104000}, +{0x0c,0x82006003}, +{0x10,0x82086003}, +{0x14,0x83286002}, +{0x18,0x9a136080}, +{0x1c,0x81c3e008}, +{0x20,0xd000400d}, +{0x24,0x9de3bf98}, +{0x28,0x9e100018}, +{0x2c,0xb4102000}, +{0x30,0xb2102000}, +{0x34,0x832ea002}, +{0x38,0xf00063a4}, +{0x3c,0xb6102000}, +{0x40,0xb806400f}, +{0x44,0xbb2ee002}, +{0x48,0xc2070000}, +{0x4c,0xb606e001}, +{0x50,0xc226001d}, +{0x54,0x80a6e002}, +{0x58,0x04bffffb}, +{0x5c,0xb8072004}, +{0x60,0xb406a001}, +{0x64,0x80a6a003}, +{0x68,0x04bffff3}, +{0x6c,0xb2066018}, +{0x70,0x81c7e008}, +{0x74,0x81e80000}, +{0x78,0x82020008}, +{0x7c,0x82004008}, +{0xf0,0x26}, +{0x00,0x9b326002}, +{0x04,0x82004001}, +{0x08,0x8200400d}, +{0x0c,0x83286002}, +{0x10,0x920a6003}, +{0x14,0x932a6003}, +{0x18,0xd00065b0}, +{0x1c,0x91320009}, +{0x20,0x81c3e008}, +{0x24,0x900a20ff}, +{0x28,0x9a020008}, +{0x2c,0x9a034008}, +{0x30,0x83326002}, +{0x34,0x9a03400d}, +{0x38,0x9a034001}, +{0x3c,0x920a6003}, +{0x40,0x932a6003}, +{0x44,0x9b2b6002}, +{0x48,0x821020ff}, +{0x4c,0xd80365b0}, +{0x50,0x83284009}, +{0x54,0x822b0001}, +{0x58,0x952a8009}, +{0x5c,0x8210400a}, +{0x60,0x81c3e008}, +{0x64,0xc22365b0}, +{0x68,0x9a020008}, +{0x6c,0x9a034008}, +{0x70,0x97326002}, +{0x74,0x9a03400d}, +{0x78,0x9a03400b}, +{0x7c,0x920a6003}, +{0xf0,0x27}, +{0x00,0x9b2b6002}, +{0x04,0x932a6003}, +{0x08,0x821020ff}, +{0x0c,0xd80365b0}, +{0x10,0x83284009}, +{0x14,0x822b0001}, +{0x18,0x952a8009}, +{0x1c,0x8210400a}, +{0x20,0xc22365b0}, +{0x24,0x912a2002}, +{0x28,0xda0223a4}, +{0x2c,0x972ae002}, +{0x30,0x81c3e008}, +{0x34,0xc223400b}, +{0x38,0x82102005}, +{0x3c,0x1b3fc200}, +{0x40,0x82204008}, +{0x44,0x9a136008}, +{0x48,0x83286002}, +{0x4c,0xd0034000}, +{0x50,0x91320001}, +{0x54,0x81c3e008}, +{0x58,0x900a200f}, +{0x5c,0xc200247c}, +{0x60,0x905a0001}, +{0x64,0x921a6001}, +{0x68,0x92024008}, +{0x6c,0x92024009}, +{0x70,0x81c3e008}, +{0x74,0xd0128009}, +{0x78,0x9de3bf98}, +{0x7c,0xc200247c}, +{0xf0,0x28}, +{0x00,0x83306001}, +{0x04,0x80a60001}, +{0x08,0x1a800006}, +{0x0c,0x90100018}, +{0x10,0x7fffffea}, +{0x14,0x01000000}, +{0x18,0x10800006}, +{0x1c,0xb0020008}, +{0x20,0x7fffffe6}, +{0x24,0x90260001}, +{0x28,0x90020008}, +{0x2c,0xb0022001}, +{0x30,0x81c7e008}, +{0x34,0x81e80000}, +{0x38,0x9de3bf90}, +{0x3c,0x03008060}, +{0x40,0xe8002348}, +{0x44,0x82106040}, +{0x48,0xc227bff0}, +{0x4c,0x03080402}, +{0x50,0x82106004}, +{0x54,0xc227bff4}, +{0x58,0xa2102000}, +{0x5c,0xc20023d4}, +{0x60,0x80a44001}, +{0x64,0x1a80002f}, +{0x68,0xa4102000}, +{0x6c,0xc200247c}, +{0x70,0x80a48001}, +{0x74,0x3a800027}, +{0x78,0xa2046001}, +{0x7c,0x7fffffdf}, +{0xf0,0x29}, +{0x00,0x90100012}, +{0x04,0xa6100008}, +{0x08,0x90100011}, +{0x0c,0x7fffff9b}, +{0x10,0x92100013}, +{0x14,0x80a62000}, +{0x18,0x12800004}, +{0x1c,0xa0100008}, +{0x20,0x10800013}, +{0x24,0xa0102000}, +{0x28,0x80a62008}, +{0x2c,0x1880000e}, +{0x30,0x80a62007}, +{0x34,0x7fffff73}, +{0x38,0x01000000}, +{0x3c,0x94100008}, +{0x40,0x90100011}, +{0x44,0x7fffffc6}, +{0x48,0x92100012}, +{0x4c,0x80a20014}, +{0x50,0x04800004}, +{0x54,0x8206001e}, +{0x58,0xc2087fef}, +{0x5c,0xa02c0001}, +{0x60,0x80a62007}, +{0x64,0x18800006}, +{0x68,0x92100013}, +{0x6c,0x8206001e}, +{0x70,0xc2087ff0}, +{0x74,0xa0140001}, +{0x78,0x92100013}, +{0x7c,0x94100010}, +{0xf0,0x2a}, +{0x00,0x7fffff9a}, +{0x04,0x90100011}, +{0x08,0x10bfffd9}, +{0x0c,0xa404a001}, +{0x10,0xc20023d4}, +{0x14,0x80a44001}, +{0x18,0x0abfffd5}, +{0x1c,0xa4102000}, +{0x20,0x81c7e008}, +{0x24,0x81e80000}, +{0x28,0x98102000}, +{0x2c,0x9610201e}, +{0x30,0x80a22000}, +{0x34,0x12800003}, +{0x38,0x8210000c}, +{0x3c,0x8222c00c}, +{0x40,0x83286002}, +{0x44,0xda006480}, +{0x48,0x80a37ff0}, +{0x4c,0x02800006}, +{0x50,0x98032002}, +{0x54,0xc2006484}, +{0x58,0x80a3201f}, +{0x5c,0x04bffff5}, +{0x60,0xc2234000}, +{0x64,0x81c3e008}, +{0x68,0x01000000}, +{0x6c,0x9de3bf98}, +{0x70,0xfa002508}, +{0x74,0x033fc000}, +{0x78,0xba0f4001}, +{0x7c,0x373fc180}, +{0xf0,0x2b}, +{0x00,0x03202020}, +{0x04,0x82106080}, +{0x08,0xb816e038}, +{0x0c,0xc2270000}, +{0x10,0x03168000}, +{0x14,0x80a74001}, +{0x18,0xc026c000}, +{0x1c,0x1280000b}, +{0x20,0x98102000}, +{0x24,0x0300003f}, +{0x28,0xfa002548}, +{0x2c,0x821063ff}, +{0x30,0xba0f4001}, +{0x34,0xf8002508}, +{0x38,0x033fffc0}, +{0x3c,0xb80f0001}, +{0x40,0xba17401c}, +{0x44,0xfa202548}, +{0x48,0x80a62000}, +{0x4c,0x1680000a}, +{0x50,0x82380018}, +{0x54,0x3b3fc040}, +{0x58,0xc2002548}, +{0x5c,0x8208401d}, +{0x60,0x3b168040}, +{0x64,0x80a0401d}, +{0x68,0x22800002}, +{0x6c,0x98102001}, +{0x70,0x82380018}, +{0x74,0x8330601f}, +{0x78,0xb410400c}, +{0x7c,0xf200254c}, +{0xf0,0x2c}, +{0x00,0xd6002548}, +{0x04,0xb8102500}, +{0x08,0x82073a50}, +{0x0c,0x80a32000}, +{0x10,0x02800009}, +{0x14,0xb61f250c}, +{0x18,0x80a060f0}, +{0x1c,0xba402000}, +{0x20,0x80a0001b}, +{0x24,0x82603fff}, +{0x28,0x80974001}, +{0x2c,0x3280000a}, +{0x30,0xb8072004}, +{0x34,0x80a6a000}, +{0x38,0x02800005}, +{0x3c,0x82073960}, +{0x40,0x80a0603f}, +{0x44,0x28800004}, +{0x48,0xb8072004}, +{0x4c,0xc0270000}, +{0x50,0xb8072004}, +{0x54,0x80a7286f}, +{0x58,0x08bfffed}, +{0x5c,0x82073a50}, +{0x60,0x80a62000}, +{0x64,0x06800005}, +{0x68,0x0300003f}, +{0x6c,0x821063ff}, +{0x70,0x820e4001}, +{0x74,0xc220254c}, +{0x78,0xc2002548}, +{0x7c,0xf6002334}, +{0xf0,0x2d}, +{0x00,0xfa0023c8}, +{0x04,0xb606e001}, +{0x08,0x9e087dff}, +{0x0c,0xbb376012}, +{0x10,0xc200254c}, +{0x14,0xba0f6200}, +{0x18,0xb936e001}, +{0x1c,0x1b3fc200}, +{0x20,0x9e13c01d}, +{0x24,0xb806c01c}, +{0x28,0x82087ffd}, +{0x2c,0xfa002344}, +{0x30,0xc220254c}, +{0x34,0xf820258c}, +{0x38,0xb4136030}, +{0x3c,0xfa268000}, +{0x40,0xb2136038}, +{0x44,0xfa264000}, +{0x48,0xb132e018}, +{0x4c,0xfa20257c}, +{0x50,0x80a6205a}, +{0x54,0xf6202554}, +{0x58,0xf6202588}, +{0x5c,0xde202548}, +{0x60,0x12800009}, +{0x64,0xfa202570}, +{0x68,0x0300003f}, +{0x6c,0x821063ff}, +{0x70,0x3b3fffc0}, +{0x74,0x820bc001}, +{0x78,0xba0ac01d}, +{0x7c,0x8210401d}, +{0xf0,0x2e}, +{0x00,0xc2202548}, +{0x04,0x80a32001}, +{0x08,0x1280000e}, +{0x0c,0x01000000}, +{0x10,0xc2002548}, +{0x14,0x83306011}, +{0x18,0x80886001}, +{0x1c,0x02800006}, +{0x20,0x82102059}, +{0x24,0xba136074}, +{0x28,0xc2002330}, +{0x2c,0xc2274000}, +{0x30,0x82102059}, +{0x34,0xc2202500}, +{0x38,0x7ffffedb}, +{0x3c,0x91e825b0}, +{0x40,0x01000000}, +{0x44,0x81c7e008}, +{0x48,0x81e80000}, +{0x4c,0x033fc200}, +{0x50,0x961060a0}, +{0x54,0x98102000}, +{0x58,0x9b2b2002}, +{0x5c,0x98032001}, +{0x60,0xc2036e80}, +{0x64,0x80a32006}, +{0x68,0x04bffffc}, +{0x6c,0xc223400b}, +{0x70,0x81c3e008}, +{0x74,0x01000000}, +{0x78,0x9de3bf98}, +{0x7c,0x3b3fc200}, +{0xf0,0x2f}, +{0x00,0x03000017}, +{0x04,0xb410001d}, +{0x08,0x9e106324}, +{0x0c,0xb817612c}, +{0x10,0xb6102000}, +{0x14,0xb0176140}, +{0x18,0xb2176160}, +{0x1c,0x80a70018}, +{0x20,0x12800004}, +{0x24,0x80a70019}, +{0x28,0x10800004}, +{0x2c,0xb816a14c}, +{0x30,0x22800002}, +{0x34,0xb816a16c}, +{0x38,0xc203c000}, +{0x3c,0x80a00001}, +{0x40,0x832ee002}, +{0x44,0xc2006ec0}, +{0x48,0xba403fff}, +{0x4c,0x8208401d}, +{0x50,0xc2270000}, +{0x54,0xb606e001}, +{0x58,0x80a6e00a}, +{0x5c,0x08bffff0}, +{0x60,0xb8072004}, +{0x64,0x81c7e008}, +{0x68,0x81e80000}, +{0x6c,0x9de3bf98}, +{0x70,0x3b3fc200}, +{0x74,0x030001c0}, +{0x78,0xb8176094}, +{0x7c,0x82106011}, +{0xf0,0x30}, +{0x00,0xc2270000}, +{0x04,0xb4176090}, +{0x08,0x03000100}, +{0x0c,0xc2268000}, +{0x10,0xb2176068}, +{0x14,0x030000c0}, +{0x18,0xc2264000}, +{0x1c,0x03004009}, +{0x20,0xb0176064}, +{0x24,0x82106182}, +{0x28,0xc2260000}, +{0x2c,0x0300065f}, +{0x30,0x9e17604c}, +{0x34,0x821063ff}, +{0x38,0xc223c000}, +{0x3c,0x033fc1c0}, +{0x40,0xb8102002}, +{0x44,0xf8204000}, +{0x48,0x96176024}, +{0x4c,0x9a176060}, +{0x50,0x03000811}, +{0x54,0xba176058}, +{0x58,0xc2274000}, +{0x5c,0x373fc140}, +{0x60,0x9816e040}, +{0x64,0x82102015}, +{0x68,0xc2230000}, +{0x6c,0x821020ff}, +{0x70,0xc222c000}, +{0x74,0xb616e020}, +{0x78,0xc0234000}, +{0x7c,0xc026c000}, +{0xf0,0x31}, +{0x00,0x81c7e008}, +{0x04,0x81e80000}, +{0x08,0x832a2008}, +{0x0c,0x1b000040}, +{0x10,0x82004008}, +{0x14,0x9a136101}, +{0x18,0x9a234001}, +{0x1c,0x033fc200}, +{0x20,0x81c3e008}, +{0x24,0xda204000}, +{0x28,0x9de3bf98}, +{0x2c,0x4000022b}, +{0x30,0x01000000}, +{0x34,0x9a102000}, +{0x38,0xc2002300}, +{0x3c,0x80a34001}, +{0x40,0x1a80000d}, +{0x44,0x03000019}, +{0x48,0x9610632c}, +{0x4c,0x98106328}, +{0x50,0x832b6003}, +{0x54,0xc020400b}, +{0x58,0xc020400c}, +{0x5c,0x9a036001}, +{0x60,0xc2002300}, +{0x64,0x80a34001}, +{0x68,0x0abffffb}, +{0x6c,0x832b6003}, +{0x70,0x9a102000}, +{0x74,0xc2002304}, +{0x78,0x80a34001}, +{0x7c,0x1a80000a}, +{0xf0,0x32}, +{0x00,0x03000019}, +{0x04,0x981063c0}, +{0x08,0x832b6002}, +{0x0c,0xc020400c}, +{0x10,0x9a036001}, +{0x14,0xc2002304}, +{0x18,0x80a34001}, +{0x1c,0x0abffffc}, +{0x20,0x832b6002}, +{0x24,0x40000460}, +{0x28,0x90102000}, +{0x2c,0x7fffffd7}, +{0x30,0x90102000}, +{0x34,0x193fc200}, +{0x38,0xa2132074}, +{0x3c,0xea0021fc}, +{0x40,0xc2002298}, +{0x44,0x98132070}, +{0x48,0xc2230000}, +{0x4c,0x033fc000}, +{0x50,0xd8002338}, +{0x54,0x82106030}, +{0x58,0xd8204000}, +{0x5c,0xc200232c}, +{0x60,0xc2244000}, +{0x64,0x1b3fc140}, +{0x68,0x0300003f}, +{0x6c,0x17000019}, +{0x70,0xa0136058}, +{0x74,0x821063ff}, +{0x78,0xc2240000}, +{0x7c,0x9e136080}, +{0xf0,0x33}, +{0x00,0x9212e0e8}, +{0x04,0xd223c000}, +{0x08,0x9412e148}, +{0x0c,0xa613608c}, +{0x10,0xa412e208}, +{0x14,0xa813605c}, +{0x18,0x90136084}, +{0x1c,0xd4220000}, +{0x20,0x9a136088}, +{0x24,0x9612e1a8}, +{0x28,0xd6234000}, +{0x2c,0x033fc0c0}, +{0x30,0xe424c000}, +{0x34,0x82106004}, +{0x38,0xc0204000}, +{0x3c,0xc0250000}, +{0x40,0x80a56000}, +{0x44,0xc2002374}, +{0x48,0xd800247c}, +{0x4c,0xd40023d4}, +{0x50,0xec0023f8}, +{0x54,0x02800006}, +{0x58,0xee002340}, +{0x5c,0x82584015}, +{0x60,0x82006800}, +{0x64,0x10800003}, +{0x68,0xab30600c}, +{0x6c,0xaa100001}, +{0x70,0x1b3fc140}, +{0x74,0x96136040}, +{0x78,0xe602c000}, +{0x7c,0x99332001}, +{0xf0,0x34}, +{0x00,0x825b000a}, +{0x04,0xa60cf800}, +{0x08,0xa614c001}, +{0x0c,0xe622c000}, +{0x10,0x82136004}, +{0x14,0xe6004000}, +{0x18,0xa60cffe0}, +{0x1c,0xa614c00c}, +{0x20,0xe6204000}, +{0x24,0x293fc200}, +{0x28,0x82152080}, +{0x2c,0xe6004000}, +{0x30,0xa60cffe0}, +{0x34,0xa614c00c}, +{0x38,0xe6204000}, +{0x3c,0x9215207c}, +{0x40,0xe6024000}, +{0x44,0x033ff000}, +{0x48,0xa62cc001}, +{0x4c,0x82102114}, +{0x50,0x96152054}, +{0x54,0xc222c000}, +{0x58,0x98152008}, +{0x5c,0xec230000}, +{0x60,0x253fc1c0}, +{0x64,0xe6224000}, +{0x68,0x9014a064}, +{0x6c,0x0300007f}, +{0x70,0xee220000}, +{0x74,0x94136010}, +{0x78,0x821063ff}, +{0x7c,0xc2228000}, +{0xf0,0x35}, +{0x00,0xa2136030}, +{0x04,0x1f07ffc0}, +{0x08,0xde244000}, +{0x0c,0xa015200c}, +{0x10,0xec240000}, +{0x14,0x82102003}, +{0x18,0x9a136014}, +{0x1c,0xc2248000}, +{0x20,0x80a56000}, +{0x24,0x0280000f}, +{0x28,0xde234000}, +{0x2c,0x952d6010}, +{0x30,0x82056001}, +{0x34,0x9b2d6004}, +{0x38,0x83286010}, +{0x3c,0x9a02800d}, +{0x40,0x98152084}, +{0x44,0xda230000}, +{0x48,0x82004015}, +{0x4c,0x96152088}, +{0x50,0x9215208c}, +{0x54,0x82006002}, +{0x58,0xd422c000}, +{0x5c,0xc2224000}, +{0x60,0xc2002174}, +{0x64,0x80a06000}, +{0x68,0x02800008}, +{0x6c,0x21000017}, +{0x70,0x173fc080}, +{0x74,0xc2082174}, +{0x78,0xda082177}, +{0x7c,0x9812e008}, +{0xf0,0x36}, +{0x00,0xc2230000}, +{0x04,0xda22c000}, +{0x08,0x8214231c}, +{0x0c,0xc0204000}, +{0x10,0x9a142318}, +{0x14,0xc0234000}, +{0x18,0x98142328}, +{0x1c,0xc0230000}, +{0x20,0x9614232c}, +{0x24,0xc022c000}, +{0x28,0x94142330}, +{0x2c,0xc0228000}, +{0x30,0x92142344}, +{0x34,0x90142334}, +{0x38,0xc0224000}, +{0x3c,0xc0222004}, +{0x40,0xc0220000}, +{0x44,0x7ffffe8a}, +{0x48,0x90103fff}, +{0x4c,0xc2002fe8}, +{0x50,0x80a06000}, +{0x54,0x12800010}, +{0x58,0x03000017}, +{0x5c,0xc20822b4}, +{0x60,0x80a06000}, +{0x64,0x0280000c}, +{0x68,0x03000017}, +{0x6c,0xc2102548}, +{0x70,0x80886001}, +{0x74,0x12800008}, +{0x78,0x03000017}, +{0x7c,0x9a142324}, +{0xf0,0x37}, +{0x00,0x82102001}, +{0x04,0x98142320}, +{0x08,0xc2234000}, +{0x0c,0x10800004}, +{0x10,0xc0230000}, +{0x14,0x82106324}, +{0x18,0xc0204000}, +{0x1c,0x7fffff14}, +{0x20,0x01000000}, +{0x24,0x7ffffe61}, +{0x28,0x90102001}, +{0x2c,0x7ffffee8}, +{0x30,0x01000000}, +{0x34,0x7ffffef1}, +{0x38,0x01000000}, +{0x3c,0xc2002fd8}, +{0x40,0x80a06000}, +{0x44,0x02800005}, +{0x48,0x1b3fc0c0}, +{0x4c,0x9fc04000}, +{0x50,0x01000000}, +{0x54,0x1b3fc0c0}, +{0x58,0x82103fff}, +{0x5c,0x9a136004}, +{0x60,0xc2234000}, +{0x64,0x03000017}, +{0x68,0x82106348}, +{0x6c,0xc0204000}, +{0x70,0x7fffff26}, +{0x74,0x90102001}, +{0x78,0xc02026f8}, +{0x7c,0x81c7e008}, +{0xf0,0x38}, +{0x00,0x81e80000}, +{0x04,0x9de3bf98}, +{0x08,0x40000010}, +{0x0c,0x01000000}, +{0x10,0x40000007}, +{0x14,0x01000000}, +{0x18,0x7fffff24}, +{0x1c,0x01000000}, +{0x20,0x40000015}, +{0x24,0x01000000}, +{0x28,0x30bffffe}, +{0x2c,0x82102001}, +{0x30,0x81904000}, +{0x34,0x01000000}, +{0x38,0x01000000}, +{0x3c,0x01000000}, +{0x40,0x81c3e008}, +{0x44,0x01000000}, +{0x48,0x03000008}, +{0x4c,0x82106342}, +{0x50,0xa3804000}, +{0x54,0x03000004}, +{0x58,0x82106000}, +{0x5c,0x81984000}, +{0x60,0x01000000}, +{0x64,0x01000000}, +{0x68,0x01000000}, +{0x6c,0x81c3e008}, +{0x70,0x01000000}, +{0x74,0x01000000}, +{0x78,0x01000000}, +{0x7c,0x01000000}, +{0xf0,0x39}, +{0x00,0xa7800000}, +{0x04,0x01000000}, +{0x08,0x01000000}, +{0x0c,0x01000000}, +{0x10,0x81c3e008}, +{0x14,0x01000000}, +{0x18,0x80a22000}, +{0x1c,0x02800006}, +{0x20,0x01000000}, +{0x24,0x01000000}, +{0x28,0x90823fff}, +{0x2c,0x12bffffe}, +{0x30,0x01000000}, +{0x34,0x81c3e008}, +{0x38,0x01000000}, +{0x3c,0x01000000}, +{0x40,0x05001040}, +{0x44,0x8410a00f}, +{0x48,0xc4a00040}, +{0x4c,0x01000000}, +{0x50,0x81c3e008}, +{0x54,0x01000000}, +{0x58,0x9de3bf98}, +{0x5c,0x82102000}, +{0x60,0x80a04019}, +{0x64,0x16800015}, +{0x68,0x9e100019}, +{0x6c,0xb6006001}, +{0x70,0x80a6c00f}, +{0x74,0x1680000f}, +{0x78,0xba10001b}, +{0x7c,0xb3286002}, +{0xf0,0x3a}, +{0x00,0xb52f6002}, +{0x04,0xf8060019}, +{0x08,0xc206001a}, +{0x0c,0x80a70001}, +{0x10,0x04800004}, +{0x14,0xba076001}, +{0x18,0xc2260019}, +{0x1c,0xf826001a}, +{0x20,0x80a7400f}, +{0x24,0x06bffff8}, +{0x28,0xb52f6002}, +{0x2c,0x80a6c00f}, +{0x30,0x06bfffef}, +{0x34,0x8210001b}, +{0x38,0x81c7e008}, +{0x3c,0x81e80000}, +{0x40,0x81c3e008}, +{0x44,0x01000000}, +{0x48,0x9de3bf98}, +{0x4c,0xf8060000}, +{0x50,0x96100018}, +{0x54,0x9a100019}, +{0x58,0x80a72000}, +{0x5c,0x12800006}, +{0x60,0x9810001a}, +{0x64,0xc2064000}, +{0x68,0x80a06000}, +{0x6c,0x0280002b}, +{0x70,0xb010001a}, +{0x74,0xb006ffff}, +{0x78,0x80a3001c}, +{0x7c,0x16800012}, +{0xf0,0x3b}, +{0x00,0xba102000}, +{0x04,0x10800024}, +{0x08,0xde034000}, +{0x0c,0x8207000d}, +{0x10,0xc2006004}, +{0x14,0xba23001b}, +{0x18,0x82204019}, +{0x1c,0x8258401d}, +{0x20,0xba26801b}, +{0x24,0x9b38601f}, +{0x28,0x81836000}, +{0x2c,0x01000000}, +{0x30,0x01000000}, +{0x34,0x01000000}, +{0x38,0x8278401d}, +{0x3c,0x10800016}, +{0x40,0x9e004019}, +{0x44,0x80a74018}, +{0x48,0x16800013}, +{0x4c,0xb92f6002}, +{0x50,0x8207000b}, +{0x54,0xf4006004}, +{0x58,0xf602c01c}, +{0x5c,0xb207000d}, +{0x60,0x80a6801b}, +{0x64,0x0680000c}, +{0x68,0xba076001}, +{0x6c,0x80a3001b}, +{0x70,0x26bffff5}, +{0x74,0xde066004}, +{0x78,0x80a3001a}, +{0x7c,0x36bffff2}, +{0xf0,0x3c}, +{0x00,0xde066004}, +{0x04,0x80a6801b}, +{0x08,0x12bfffe1}, +{0x0c,0xf203401c}, +{0x10,0x9e100019}, +{0x14,0xb010000f}, +{0x18,0x81c7e008}, +{0x1c,0x81e80000}, +{0x20,0x9de3bf98}, +{0x24,0xfa002300}, +{0x28,0x832f6002}, +{0x2c,0x82006007}, +{0x30,0x82087ff8}, +{0x34,0x9810000e}, +{0x38,0x9c238001}, +{0x3c,0x9e102000}, +{0x40,0x80a3c01d}, +{0x44,0xb003a060}, +{0x48,0x1a80001e}, +{0x4c,0xb8102000}, +{0x50,0x832f2002}, +{0x54,0xc0260001}, +{0x58,0xb8072001}, +{0x5c,0xc2002300}, +{0x60,0x80a70001}, +{0x64,0x2abffffc}, +{0x68,0x832f2002}, +{0x6c,0xb8102000}, +{0x70,0x80a70001}, +{0x74,0x1a800014}, +{0x78,0x03000019}, +{0x7c,0x9a106328}, +{0xf0,0x3d}, +{0x00,0x832f2003}, +{0x04,0xb600400d}, +{0x08,0xb32f2002}, +{0x0c,0xb4102001}, +{0x10,0xfa06c000}, +{0x14,0xc2060019}, +{0x18,0x8200401d}, +{0x1c,0xc2260019}, +{0x20,0xb486bfff}, +{0x24,0x1cbffffb}, +{0x28,0xb606e004}, +{0x2c,0xb8072001}, +{0x30,0xc2002300}, +{0x34,0x80a70001}, +{0x38,0x0abffff3}, +{0x3c,0x832f2003}, +{0x40,0xb8102000}, +{0x44,0xfa002300}, +{0x48,0x80a7001d}, +{0x4c,0x3a80000d}, +{0x50,0xc210228c}, +{0x54,0xf610228e}, +{0x58,0x832f2002}, +{0x5c,0xc2060001}, +{0x60,0x80a0401b}, +{0x64,0x04800003}, +{0x68,0xb8072001}, +{0x6c,0x9e03e001}, +{0x70,0x80a7001d}, +{0x74,0x0abffffa}, +{0x78,0x832f2002}, +{0x7c,0xc210228c}, +{0xf0,0x3e}, +{0x00,0x80a3c001}, +{0x04,0x04800006}, +{0x08,0x9c10000c}, +{0x0c,0xc200254c}, +{0x10,0x3b000200}, +{0x14,0x8210401d}, +{0x18,0xc220254c}, +{0x1c,0x81c7e008}, +{0x20,0x81e80000}, +{0x24,0x81c3e008}, +{0x28,0x01000000}, +{0x2c,0x9c03bf88}, +{0x30,0x96102000}, +{0x34,0x8203a060}, +{0x38,0x98102003}, +{0x3c,0xc0204000}, +{0x40,0x98833fff}, +{0x44,0x1cbffffe}, +{0x48,0x82006004}, +{0x4c,0x98102000}, +{0x50,0xda002514}, +{0x54,0x80a3000d}, +{0x58,0x1a800008}, +{0x5c,0x832b2002}, +{0x60,0xc2106730}, +{0x64,0x80a0400b}, +{0x68,0x04bffffb}, +{0x6c,0x98032001}, +{0x70,0x10bffff9}, +{0x74,0x96100001}, +{0x78,0xda1022cc}, +{0x7c,0xc20026e0}, +{0xf0,0x3f}, +{0x00,0x80a0400d}, +{0x04,0x04800006}, +{0x08,0x03000017}, +{0x0c,0xda0822c7}, +{0x10,0x82106348}, +{0x14,0x10800008}, +{0x18,0xda204000}, +{0x1c,0x9a106348}, +{0x20,0xc2034000}, +{0x24,0x80a06000}, +{0x28,0x04800003}, +{0x2c,0x82007fff}, +{0x30,0xc2234000}, +{0x34,0x1b000017}, +{0x38,0x82136348}, +{0x3c,0xc2004000}, +{0x40,0x80a06000}, +{0x44,0x0480002f}, +{0x48,0x8213631c}, +{0x4c,0xc2004000}, +{0x50,0x80a06002}, +{0x54,0x2280002c}, +{0x58,0xc2002514}, +{0x5c,0xc20022d4}, +{0x60,0x80886010}, +{0x64,0x02800015}, +{0x68,0x03000017}, +{0x6c,0x82136328}, +{0x70,0xda004000}, +{0x74,0xc2002514}, +{0x78,0x80a0400d}, +{0x7c,0x0280000e}, +{0xf0,0x40}, +{0x00,0x03000018}, +{0x04,0x96106058}, +{0x08,0x98102000}, +{0x0c,0x9b2b2002}, +{0x10,0x98032001}, +{0x14,0xc2036720}, +{0x18,0x80a32003}, +{0x1c,0x04bffffc}, +{0x20,0xc223400b}, +{0x24,0x03000017}, +{0x28,0xda002514}, +{0x2c,0x82106328}, +{0x30,0xda204000}, +{0x34,0x03000017}, +{0x38,0x82106328}, +{0x3c,0xc2004000}, +{0x40,0x80a06000}, +{0x44,0x0480001b}, +{0x48,0x03000018}, +{0x4c,0x96106058}, +{0x50,0x98102000}, +{0x54,0x9b2b2002}, +{0x58,0x98032001}, +{0x5c,0xc203400b}, +{0x60,0x80a32003}, +{0x64,0x04bffffc}, +{0x68,0xc2236720}, +{0x6c,0x03000017}, +{0x70,0x82106328}, +{0x74,0xc2004000}, +{0x78,0x1080000e}, +{0x7c,0xc2202514}, +{0xf0,0x41}, +{0x00,0xc2002514}, +{0x04,0x9a136328}, +{0x08,0xc2234000}, +{0x0c,0x03000018}, +{0x10,0x96106058}, +{0x14,0x98102000}, +{0x18,0x9b2b2002}, +{0x1c,0x98032001}, +{0x20,0xc2036720}, +{0x24,0x80a32003}, +{0x28,0x04bffffc}, +{0x2c,0xc223400b}, +{0x30,0x03000017}, +{0x34,0xda002514}, +{0x38,0x82106328}, +{0x3c,0xda204000}, +{0x40,0x81c3e008}, +{0x44,0x9c23bf88}, +{0x48,0x98102000}, +{0x4c,0x80a3000a}, +{0x50,0x16800008}, +{0x54,0x01000000}, +{0x58,0x9b2b2002}, +{0x5c,0x98032001}, +{0x60,0xc202400d}, +{0x64,0x80a3000a}, +{0x68,0x06bffffc}, +{0x6c,0xc222000d}, +{0x70,0x81c3e008}, +{0x74,0x01000000}, +{0x78,0x9de3bf98}, +{0x7c,0x7ffffde3}, +{0xf0,0x42}, +{0x00,0x90102000}, +{0x04,0x1b000017}, +{0x08,0x98136324}, +{0x0c,0xc2030000}, +{0x10,0x80a00001}, +{0x14,0x82603fff}, +{0x18,0x92004001}, +{0x1c,0x92024001}, +{0x20,0x9a13638c}, +{0x24,0x932a6005}, +{0x28,0x9202400d}, +{0x2c,0xc2230000}, +{0x30,0x94102018}, +{0x34,0x7fffffe5}, +{0x38,0x901025b0}, +{0x3c,0x7ffffc5a}, +{0x40,0x901025b0}, +{0x44,0x7ffffd8d}, +{0x48,0xb0102001}, +{0x4c,0x7ffffdcf}, +{0x50,0x81e80000}, +{0x54,0x01000000}, +{0x58,0x03000018}, +{0x5c,0x96106054}, +{0x60,0x9810604c}, +{0x64,0x82106050}, +{0x68,0x9a103fe0}, +{0x6c,0xda204000}, +{0x70,0xc0230000}, +{0x74,0x81c3e008}, +{0x78,0xc022c000}, +{0x7c,0xda002548}, +{0xf0,0x43}, +{0x00,0x83336010}, +{0x04,0x80886001}, +{0x08,0x0280000b}, +{0x0c,0x90102001}, +{0x10,0xc2002558}, +{0x14,0x9b336011}, +{0x18,0x80a06000}, +{0x1c,0x12800005}, +{0x20,0x90102000}, +{0x24,0x808b6001}, +{0x28,0x12800003}, +{0x2c,0x01000000}, +{0x30,0x90102001}, +{0x34,0x81c3e008}, +{0x38,0x01000000}, +{0x3c,0x94102000}, +{0x40,0xc2002514}, +{0x44,0x80a28001}, +{0x48,0x96102000}, +{0x4c,0x1a800010}, +{0x50,0x9b2ae002}, +{0x54,0xc2036720}, +{0x58,0x992aa002}, +{0x5c,0x80a06000}, +{0x60,0x02800008}, +{0x64,0x9602e001}, +{0x68,0xc2232720}, +{0x6c,0xc2036730}, +{0x70,0xc2232730}, +{0x74,0xc20367e0}, +{0x78,0x9402a001}, +{0x7c,0xc22327e0}, +{0xf0,0x44}, +{0x00,0xc2002514}, +{0x04,0x10bffff2}, +{0x08,0x80a2c001}, +{0x0c,0x81c3e008}, +{0x10,0xd4202514}, +{0x14,0x9de3bf98}, +{0x18,0xb0102000}, +{0x1c,0xf6002514}, +{0x20,0x80a6001b}, +{0x24,0x1a800012}, +{0x28,0xbb2e2002}, +{0x2c,0xc2076720}, +{0x30,0x80a06000}, +{0x34,0x02bffffb}, +{0x38,0xb0062001}, +{0x3c,0xf8176732}, +{0x40,0xc200271c}, +{0x44,0x80a70001}, +{0x48,0x34800002}, +{0x4c,0xf820271c}, +{0x50,0xfa176730}, +{0x54,0xc2002718}, +{0x58,0x80a74001}, +{0x5c,0x34bffff1}, +{0x60,0xfa202718}, +{0x64,0x10bffff0}, +{0x68,0x80a6001b}, +{0x6c,0x3b333333}, +{0x70,0xc2002500}, +{0x74,0xba1760cd}, +{0x78,0x8050401d}, +{0x7c,0xbb400000}, +{0xf0,0x45}, +{0x00,0xbb376003}, +{0x04,0xb92f6002}, +{0x08,0xb807001d}, +{0x0c,0xb807001c}, +{0x10,0x80a0401c}, +{0x14,0x1280000d}, +{0x18,0xb0102000}, +{0x1c,0xc200271c}, +{0x20,0x80a06000}, +{0x24,0x04800003}, +{0x28,0x82007fff}, +{0x2c,0xc220271c}, +{0x30,0xc2002718}, +{0x34,0x80a06000}, +{0x38,0x04800003}, +{0x3c,0x82007fff}, +{0x40,0xc2202718}, +{0x44,0xb0102000}, +{0x48,0xc2002514}, +{0x4c,0x80a60001}, +{0x50,0x1a80003e}, +{0x54,0x01000000}, +{0x58,0xb4102000}, +{0x5c,0xc20022d4}, +{0x60,0x80886010}, +{0x64,0x02800006}, +{0x68,0xfa002300}, +{0x6c,0xf616a720}, +{0x70,0xb60eefff}, +{0x74,0x10800005}, +{0x78,0x9810001d}, +{0x7c,0xc206a720}, +{0xf0,0x46}, +{0x00,0xb6086fff}, +{0x04,0x99376001}, +{0x08,0x9e102000}, +{0x0c,0xc206a720}, +{0x10,0x80a06000}, +{0x14,0x22800025}, +{0x18,0x9e03e001}, +{0x1c,0x80a3e000}, +{0x20,0x32800005}, +{0x24,0xda16a730}, +{0x28,0xda16a732}, +{0x2c,0x10800003}, +{0x30,0xf200271c}, +{0x34,0xf2002718}, +{0x38,0xb92be003}, +{0x3c,0xfa572244}, +{0x40,0x80a6c01d}, +{0x44,0x26800008}, +{0x48,0xfa572246}, +{0x4c,0x832b2006}, +{0x50,0x8220401d}, +{0x54,0x80a6c001}, +{0x58,0x24800014}, +{0x5c,0x9e03e001}, +{0x60,0xfa572246}, +{0x64,0xba5e401d}, +{0x68,0x833f601f}, +{0x6c,0x83306018}, +{0x70,0xba074001}, +{0x74,0xbb3f6008}, +{0x78,0xc2572242}, +{0x7c,0x80a74001}, +{0xf0,0x47}, +{0x00,0x34800002}, +{0x04,0xba100001}, +{0x08,0xc2572240}, +{0x0c,0x80a74001}, +{0x10,0x26800002}, +{0x14,0xba100001}, +{0x18,0x80a3401d}, +{0x1c,0x26800002}, +{0x20,0xc026a720}, +{0x24,0x9e03e001}, +{0x28,0x80a3e001}, +{0x2c,0x24bfffd9}, +{0x30,0xc206a720}, +{0x34,0xb0062001}, +{0x38,0xc2002514}, +{0x3c,0x80a60001}, +{0x40,0x0abfffc7}, +{0x44,0xb406a004}, +{0x48,0x7fffff7d}, +{0x4c,0x81e80000}, +{0x50,0x01000000}, +{0x54,0x81c3e008}, +{0x58,0x01000000}, +{0x5c,0x9de3bf78}, +{0x60,0xc20022d4}, +{0x64,0x80886010}, +{0x68,0x96100018}, +{0x6c,0xa0102000}, +{0x70,0x9a102000}, +{0x74,0x94102000}, +{0x78,0x02800004}, +{0x7c,0xc2002300}, +{0xf0,0x48}, +{0x00,0x10800003}, +{0x04,0x98100001}, +{0x08,0x99306001}, +{0x0c,0x80a2e05f}, +{0x10,0x14800006}, +{0x14,0xb12b2006}, +{0x18,0x82102060}, +{0x1c,0x9420400b}, +{0x20,0x9a102000}, +{0x24,0xa0103fff}, +{0x28,0x82063fa0}, +{0x2c,0x80a2c001}, +{0x30,0x04800006}, +{0x34,0x80a66000}, +{0x38,0x8222c018}, +{0x3c,0x94006060}, +{0x40,0x9a102001}, +{0x44,0xa0102001}, +{0x48,0x32800002}, +{0x4c,0x9a036002}, +{0x50,0x80a2a000}, +{0x54,0x16800004}, +{0x58,0x80a2a03f}, +{0x5c,0x10800004}, +{0x60,0x94102000}, +{0x64,0x34800002}, +{0x68,0x9410203f}, +{0x6c,0x912b6002}, +{0x70,0x92102000}, +{0x74,0x9607bff8}, +{0x78,0x9a020009}, +{0x7c,0x8203400d}, +{0xf0,0x49}, +{0x00,0xd8506260}, +{0x04,0xc20b6250}, +{0x08,0xc222fff0}, +{0x0c,0xd822ffe0}, +{0x10,0x92026001}, +{0x14,0x80a26003}, +{0x18,0x04bffff8}, +{0x1c,0x9602e004}, +{0x20,0x9007bfe8}, +{0x24,0x9207bfd8}, +{0x28,0x7ffffe28}, +{0x2c,0x96102004}, +{0x30,0xc20022d4}, +{0x34,0x80886020}, +{0x38,0x22800002}, +{0x3c,0xa0200010}, +{0x40,0xb05c0008}, +{0x44,0x81c7e008}, +{0x48,0x81e80000}, +{0x4c,0x90020009}, +{0x50,0x932a600a}, +{0x54,0x833a601f}, +{0x58,0x81806000}, +{0x5c,0x01000000}, +{0x60,0x01000000}, +{0x64,0x01000000}, +{0x68,0x907a4008}, +{0x6c,0x033fffaa}, +{0x70,0x9b2a2008}, +{0x74,0x82106300}, +{0x78,0x9a034001}, +{0x7c,0x030c0300}, +{0xf0,0x4a}, +{0x00,0x82106301}, +{0x04,0x805b4001}, +{0x08,0x83400000}, +{0x0c,0x83386006}, +{0x10,0x9b3b601f}, +{0x14,0x80a2a001}, +{0x18,0x12800008}, +{0x1c,0x9020400d}, +{0x20,0x90020008}, +{0x24,0x80a22100}, +{0x28,0x04800005}, +{0x2c,0x80a22000}, +{0x30,0x82102200}, +{0x34,0x90204008}, +{0x38,0x80a22000}, +{0x3c,0x16800004}, +{0x40,0x80a22100}, +{0x44,0x10800004}, +{0x48,0x90102000}, +{0x4c,0x34800002}, +{0x50,0x90102100}, +{0x54,0x81c3e008}, +{0x58,0x01000000}, +{0x5c,0x9de3bf98}, +{0x60,0x03000019}, +{0x64,0x9a100018}, +{0x68,0x9e100019}, +{0x6c,0x9610632c}, +{0x70,0xb4102000}, +{0x74,0x98106328}, +{0x78,0xc24ea400}, +{0x7c,0xb12ea003}, +{0xf0,0x4b}, +{0x00,0xb9286002}, +{0x04,0x80a06000}, +{0x08,0x06800010}, +{0x0c,0xb2004001}, +{0x10,0xc24ea420}, +{0x14,0xbb286002}, +{0x18,0x82004001}, +{0x1c,0xf603401d}, +{0x20,0xc213c001}, +{0x24,0xf803401c}, +{0x28,0xfa13c019}, +{0x2c,0x8220401b}, +{0x30,0xba27401c}, +{0x34,0xb406a001}, +{0x38,0xc226000b}, +{0x3c,0x80a6a014}, +{0x40,0x08bfffee}, +{0x44,0xfa26000c}, +{0x48,0xb4102000}, +{0x4c,0xc2002304}, +{0x50,0x80a68001}, +{0x54,0x1a800010}, +{0x58,0x03000019}, +{0x5c,0xb81063c0}, +{0x60,0xc24ea380}, +{0x64,0xbb286002}, +{0x68,0x82004001}, +{0x6c,0xfa03401d}, +{0x70,0xc213c001}, +{0x74,0x8220401d}, +{0x78,0xbb2ea002}, +{0x7c,0xc227401c}, +{0xf0,0x4c}, +{0x00,0xb406a001}, +{0x04,0xc2002304}, +{0x08,0x80a68001}, +{0x0c,0x2abffff6}, +{0x10,0xc24ea380}, +{0x14,0x81c7e008}, +{0x18,0x81e80000}, +{0x1c,0x9de3bf98}, +{0x20,0xc2002508}, +{0x24,0x808860ff}, +{0x28,0x02800015}, +{0x2c,0x1b3fc180}, +{0x30,0x82102001}, +{0x34,0x9a13603c}, +{0x38,0xc2234000}, +{0x3c,0xc2002508}, +{0x40,0x820860ff}, +{0x44,0x80a04018}, +{0x48,0x1280000b}, +{0x4c,0x033fc180}, +{0x50,0x7ffffd9b}, +{0x54,0x01000000}, +{0x58,0xda002508}, +{0x5c,0x033fc040}, +{0x60,0x9a0b60ff}, +{0x64,0x8210600c}, +{0x68,0xc0204000}, +{0x6c,0x10bffff7}, +{0x70,0x80a34018}, +{0x74,0x8210603c}, +{0x78,0xc0204000}, +{0x7c,0x81c7e008}, +{0xf0,0x4d}, +{0x00,0x81e80000}, +{0x04,0x9a102000}, +{0x08,0x832b6002}, +{0x0c,0x9a036001}, +{0x10,0x80a3602f}, +{0x14,0x08bffffd}, +{0x18,0xc0220001}, +{0x1c,0x81c3e008}, +{0x20,0x01000000}, +{0x24,0x9de3bf98}, +{0x28,0x3b000019}, +{0x2c,0x98100019}, +{0x30,0x03000017}, +{0x34,0x9a106324}, +{0x38,0x94176028}, +{0x3c,0xb2102000}, +{0x40,0x9e176268}, +{0x44,0x96176088}, +{0x48,0xb92e6003}, +{0x4c,0x81800000}, +{0x50,0xc206001c}, +{0x54,0x01000000}, +{0x58,0x01000000}, +{0x5c,0x8270400c}, +{0x60,0xc226001c}, +{0x64,0x82070018}, +{0x68,0x81800000}, +{0x6c,0xf6006004}, +{0x70,0x01000000}, +{0x74,0x01000000}, +{0x78,0xb676c00c}, +{0x7c,0xf6206004}, +{0xf0,0x4e}, +{0x00,0xfa034000}, +{0x04,0x8207401d}, +{0x08,0x8200401d}, +{0x0c,0xfa06001c}, +{0x10,0x83286003}, +{0x14,0x82004019}, +{0x18,0xbb2f6010}, +{0x1c,0x83286002}, +{0x20,0xba07401b}, +{0x24,0xfa20400f}, +{0x28,0xc2034000}, +{0x2c,0x80a06000}, +{0x30,0x1280000c}, +{0x34,0xb52e6002}, +{0x38,0xc206800f}, +{0x3c,0xc226800b}, +{0x40,0xfa034000}, +{0x44,0x8207401d}, +{0x48,0x8200401d}, +{0x4c,0x83286003}, +{0x50,0x82004019}, +{0x54,0x83286002}, +{0x58,0xc200400f}, +{0x5c,0xc226800a}, +{0x60,0xb2066001}, +{0x64,0x80a66017}, +{0x68,0x08bfffd9}, +{0x6c,0xb92e6003}, +{0x70,0x81c7e008}, +{0x74,0x81e80000}, +{0x78,0x81c3e008}, +{0x7c,0x01000000}, +{0xf0,0x4f}, +{0x00,0x9de3bf98}, +{0x04,0xf8060000}, +{0x08,0xfa064000}, +{0x0c,0x83372010}, +{0x10,0xb5376010}, +{0x14,0x82086fff}, +{0x18,0xb40eafff}, +{0x1c,0xb620401a}, +{0x20,0x03000007}, +{0x24,0x821063ff}, +{0x28,0xb40f4001}, +{0x2c,0x820f0001}, +{0x30,0xb820401a}, +{0x34,0xc2002328}, +{0x38,0xb65ec001}, +{0x3c,0xc2002324}, +{0x40,0xb05f0001}, +{0x44,0x833e201f}, +{0x48,0x83306016}, +{0x4c,0xb4060001}, +{0x50,0xc20022d4}, +{0x54,0xbb3ee01f}, +{0x58,0xbb376015}, +{0x5c,0x80886010}, +{0x60,0xc2002300}, +{0x64,0xb806c01d}, +{0x68,0xbb286006}, +{0x6c,0x0280000a}, +{0x70,0x83286005}, +{0x74,0x833ee01f}, +{0x78,0x81806000}, +{0x7c,0x01000000}, +{0xf0,0x50}, +{0x00,0x01000000}, +{0x04,0x01000000}, +{0x08,0xb67ec01d}, +{0x0c,0x10800009}, +{0x10,0xb13ea00a}, +{0x14,0x9b3e201f}, +{0x18,0x81836000}, +{0x1c,0x01000000}, +{0x20,0x01000000}, +{0x24,0x01000000}, +{0x28,0xb07e0001}, +{0x2c,0xb73f200b}, +{0x30,0x825ec01b}, +{0x34,0xb05e0018}, +{0x38,0x81c7e008}, +{0x3c,0x91e84018}, +{0x40,0x9de3bf98}, +{0x44,0x03000017}, +{0x48,0x82106324}, +{0x4c,0xfa004000}, +{0x50,0x03000019}, +{0x54,0xb2106028}, +{0x58,0x80a76000}, +{0x5c,0x02800004}, +{0x60,0x9e100019}, +{0x64,0xb21062c8}, +{0x68,0x9e100019}, +{0x6c,0xf4060000}, +{0x70,0x03000018}, +{0x74,0x82106368}, +{0x78,0xbb2ea002}, +{0x7c,0xfa074001}, +{0xf0,0x51}, +{0x00,0xb806801a}, +{0x04,0xc213c01c}, +{0x08,0xb6a74001}, +{0x0c,0x02800016}, +{0x10,0x8206801a}, +{0x14,0x80a6e000}, +{0x18,0x04800009}, +{0x1c,0x82102001}, +{0x20,0xf0062004}, +{0x24,0x83284018}, +{0x28,0x80a6c001}, +{0x2c,0x3480000d}, +{0x30,0xb73ec018}, +{0x34,0x1080000b}, +{0x38,0xb6102001}, +{0x3c,0x1680000a}, +{0x40,0x8206801a}, +{0x44,0xf0062008}, +{0x48,0x82103fff}, +{0x4c,0x83284018}, +{0x50,0x80a6c001}, +{0x54,0x36800003}, +{0x58,0xb6103fff}, +{0x5c,0xb73ec018}, +{0x60,0x8206801a}, +{0x64,0xc213c001}, +{0x68,0xb606c001}, +{0x6c,0x808ea001}, +{0x70,0x0280000d}, +{0x74,0xbb3ea01f}, +{0x78,0xbb37601f}, +{0x7c,0xba06801d}, +{0xf0,0x52}, +{0x00,0xbb3f6001}, +{0x04,0xbb2f6002}, +{0x08,0x033fffc0}, +{0x0c,0xf806401d}, +{0x10,0xb80f0001}, +{0x14,0x0300003f}, +{0x18,0x821063ff}, +{0x1c,0x1080000b}, +{0x20,0x820ec001}, +{0x24,0xbb37601f}, +{0x28,0xba06801d}, +{0x2c,0xbb3f6001}, +{0x30,0xbb2f6002}, +{0x34,0x0300003f}, +{0x38,0x821063ff}, +{0x3c,0xf806401d}, +{0x40,0xb80f0001}, +{0x44,0x832ee010}, +{0x48,0xb8170001}, +{0x4c,0xf826401d}, +{0x50,0x81c7e008}, +{0x54,0x81e80000}, +{0x58,0x9de3bf68}, +{0x5c,0x7ffffa49}, +{0x60,0xb0102001}, +{0x64,0xa4100008}, +{0x68,0xa2102000}, +{0x6c,0xa0102003}, +{0x70,0x11000016}, +{0x74,0x921223e8}, +{0x78,0x90122388}, +{0x7c,0x90044008}, +{0xf0,0x53}, +{0x00,0x92044009}, +{0x04,0x7ffffdd1}, +{0x08,0x94102018}, +{0x0c,0xa0843fff}, +{0x10,0x1cbffff8}, +{0x14,0xa2046060}, +{0x18,0x11000017}, +{0x1c,0x90122108}, +{0x20,0x92100012}, +{0x24,0x7ffffdc9}, +{0x28,0x94102018}, +{0x2c,0x8207bfe0}, +{0x30,0xa0102004}, +{0x34,0xc0204000}, +{0x38,0xa0843fff}, +{0x3c,0x1cbffffe}, +{0x40,0x82006004}, +{0x44,0xa0102000}, +{0x48,0x03000016}, +{0x4c,0x9a040010}, +{0x50,0x82106388}, +{0x54,0x9a034001}, +{0x58,0xa207bff8}, +{0x5c,0x9807bfc8}, +{0x60,0x96102004}, +{0x64,0xc2134000}, +{0x68,0xc2230000}, +{0x6c,0x9a036060}, +{0x70,0x9682ffff}, +{0x74,0x1cbffffc}, +{0x78,0x98032004}, +{0x7c,0x92102005}, +{0xf0,0x54}, +{0x00,0x7ffffcb6}, +{0x04,0x9007bfc8}, +{0x08,0x03000016}, +{0x0c,0x9a040010}, +{0x10,0x82106388}, +{0x14,0x94034001}, +{0x18,0xd207bfd0}, +{0x1c,0x98100011}, +{0x20,0x96102004}, +{0x24,0xc2128000}, +{0x28,0x82224001}, +{0x2c,0x9b38601f}, +{0x30,0x8218400d}, +{0x34,0x8220400d}, +{0x38,0xda033fe8}, +{0x3c,0x9a034001}, +{0x40,0xda233fe8}, +{0x44,0x9402a060}, +{0x48,0x9682ffff}, +{0x4c,0x1cbffff6}, +{0x50,0x98032004}, +{0x54,0xa0042001}, +{0x58,0x80a42023}, +{0x5c,0x04bfffdc}, +{0x60,0x03000016}, +{0x64,0x03001fff}, +{0x68,0x821063ff}, +{0x6c,0x9a047fe8}, +{0x70,0xa0102000}, +{0x74,0xd8034000}, +{0x78,0x80a30001}, +{0x7c,0x16800004}, +{0xf0,0x55}, +{0x00,0x9a036004}, +{0x04,0x8210000c}, +{0x08,0xb0100010}, +{0x0c,0xa0042001}, +{0x10,0x80a42004}, +{0x14,0x24bffff9}, +{0x18,0xd8034000}, +{0x1c,0x81c7e008}, +{0x20,0x81e80000}, +{0x24,0x9de3bf98}, +{0x28,0x833e201f}, +{0x2c,0xd0002320}, +{0x30,0x82204018}, +{0x34,0x80a22000}, +{0x38,0x02800015}, +{0x3c,0x9b30601f}, +{0x40,0x033fc000}, +{0x44,0xa0106020}, +{0x48,0xc200231c}, +{0x4c,0x80a00001}, +{0x50,0x82402000}, +{0x54,0x8088400d}, +{0x58,0xc2002318}, +{0x5c,0x02800009}, +{0x60,0xb01e0001}, +{0x64,0x80a00001}, +{0x68,0x82603fff}, +{0x6c,0x7ffffc6b}, +{0x70,0xc2240000}, +{0x74,0xc2002318}, +{0x78,0x10800005}, +{0x7c,0xc2240000}, +{0xf0,0x56}, +{0x00,0x033fc000}, +{0x04,0x82106020}, +{0x08,0xf0204000}, +{0x0c,0x81c7e008}, +{0x10,0x81e80000}, +{0x14,0x9de3bf98}, +{0x18,0x7ffffc69}, +{0x1c,0x01000000}, +{0x20,0x033fc040}, +{0x24,0xe2002500}, +{0x28,0x8210600c}, +{0x2c,0x80a46058}, +{0x30,0x08800013}, +{0x34,0xc0204000}, +{0x38,0xc0202584}, +{0x3c,0xa0102000}, +{0x40,0x832c2002}, +{0x44,0xc2006f04}, +{0x48,0x80a06000}, +{0x4c,0x02800074}, +{0x50,0xa0042001}, +{0x54,0x9fc04000}, +{0x58,0x01000000}, +{0x5c,0xc2002584}, +{0x60,0x80a06000}, +{0x64,0x1280006e}, +{0x68,0x80a4203b}, +{0x6c,0x24bffff6}, +{0x70,0x832c2002}, +{0x74,0x1080006b}, +{0x78,0xc2002500}, +{0x7c,0x80a46000}, +{0xf0,0x57}, +{0x00,0x1280000f}, +{0x04,0x80a46014}, +{0x08,0xc2002ff4}, +{0x0c,0x9fc04000}, +{0x10,0x01000000}, +{0x14,0x7ffffa76}, +{0x18,0x90102000}, +{0x1c,0xc24822e5}, +{0x20,0x80a06000}, +{0x24,0x3280005f}, +{0x28,0xc2002500}, +{0x2c,0x7ffffa5f}, +{0x30,0x90102001}, +{0x34,0x1080005b}, +{0x38,0xc2002500}, +{0x3c,0x1880000a}, +{0x40,0x80a46015}, +{0x44,0x808c6001}, +{0x48,0x32800056}, +{0x4c,0xc2002500}, +{0x50,0x90047ffe}, +{0x54,0x7ffffa19}, +{0x58,0x91322001}, +{0x5c,0x10800051}, +{0x60,0xc2002500}, +{0x64,0x18800011}, +{0x68,0x80a46018}, +{0x6c,0x033fc180}, +{0x70,0xda0025b0}, +{0x74,0x82106038}, +{0x78,0xda204000}, +{0x7c,0x033fc200}, +{0xf0,0x58}, +{0x00,0xda00232c}, +{0x04,0x82106074}, +{0x08,0xda204000}, +{0x0c,0x7ffffa47}, +{0x10,0x90102000}, +{0x14,0xc2002ff4}, +{0x18,0x9fc04000}, +{0x1c,0x01000000}, +{0x20,0x10800040}, +{0x24,0xc2002500}, +{0x28,0x1880000b}, +{0x2c,0x80a46058}, +{0x30,0x11000018}, +{0x34,0x7ffffe94}, +{0x38,0x90122368}, +{0x3c,0x1b000017}, +{0x40,0x033fc200}, +{0x44,0x9a1363ff}, +{0x48,0x82106070}, +{0x4c,0x10800034}, +{0x50,0xda204000}, +{0x54,0x38800033}, +{0x58,0xc2002500}, +{0x5c,0xc2002fe8}, +{0x60,0x80a06000}, +{0x64,0x02800004}, +{0x68,0x01000000}, +{0x6c,0x9fc04000}, +{0x70,0x01000000}, +{0x74,0x7ffff983}, +{0x78,0xa0102000}, +{0x7c,0x15000018}, +{0xf0,0x59}, +{0x00,0x9612a368}, +{0x04,0x82040010}, +{0x08,0x992c2002}, +{0x0c,0xda120001}, +{0x10,0xc203000b}, +{0x14,0x8200400d}, +{0x18,0xa0042001}, +{0x1c,0x80a4202f}, +{0x20,0x04bffff9}, +{0x24,0xc223000b}, +{0x28,0x80a46058}, +{0x2c,0x3280001d}, +{0x30,0xc2002500}, +{0x34,0x9012a368}, +{0x38,0x7ffffe7b}, +{0x3c,0x92102040}, +{0x40,0x1b000017}, +{0x44,0xa0136324}, +{0x48,0xc2040000}, +{0x4c,0x90004001}, +{0x50,0x90020001}, +{0x54,0x033fc200}, +{0x58,0x82106070}, +{0x5c,0x9a13638c}, +{0x60,0xd8002298}, +{0x64,0x912a2005}, +{0x68,0xd8204000}, +{0x6c,0x9002000d}, +{0x70,0x921025b0}, +{0x74,0x7ffffcf5}, +{0x78,0x94102018}, +{0x7c,0xc2040000}, +{0xf0,0x5a}, +{0x00,0x80a06001}, +{0x04,0x32800007}, +{0x08,0xc2002500}, +{0x0c,0xa2103fff}, +{0x10,0xc0240000}, +{0x14,0x7ffffa99}, +{0x18,0xe2202500}, +{0x1c,0xc2002500}, +{0x20,0x80a44001}, +{0x24,0x1280000f}, +{0x28,0x80a47fff}, +{0x2c,0x12800004}, +{0x30,0x031fffff}, +{0x34,0x10800007}, +{0x38,0xa2102000}, +{0x3c,0x821063f0}, +{0x40,0x80a44001}, +{0x44,0x38800003}, +{0x48,0x23040000}, +{0x4c,0xa2046001}, +{0x50,0x033fc180}, +{0x54,0x82106034}, +{0x58,0xe2204000}, +{0x5c,0xe2202500}, +{0x60,0x81c7e008}, +{0x64,0x81e80000}, +{0x68,0x81c3e008}, +{0x6c,0x01000000}, +{0x70,0x9de3bf98}, +{0x74,0x94100018}, +{0x78,0xb0063fff}, +{0x7c,0x9802a001}, +{0xf0,0x5b}, +{0x00,0x9210001a}, +{0x04,0x80a6000c}, +{0x08,0x1480001d}, +{0x0c,0x9e102000}, +{0x10,0x03000019}, +{0x14,0x96106328}, +{0x18,0xb72be002}, +{0x1c,0x80a62000}, +{0x20,0x06800013}, +{0x24,0xc026401b}, +{0x28,0xc2002300}, +{0x2c,0x80a60001}, +{0x30,0x3a800010}, +{0x34,0xb0062001}, +{0x38,0x832e2003}, +{0x3c,0xb800400b}, +{0x40,0xb4102001}, +{0x44,0xc2070000}, +{0x48,0xba380001}, +{0x4c,0xbb3f601f}, +{0x50,0x8208401d}, +{0x54,0xfa06401b}, +{0x58,0xba074001}, +{0x5c,0xfa26401b}, +{0x60,0xb486bfff}, +{0x64,0x1cbffff8}, +{0x68,0xb8072004}, +{0x6c,0xb0062001}, +{0x70,0x80a6000c}, +{0x74,0x04bfffe9}, +{0x78,0x9e03e001}, +{0x7c,0xf6066004}, +{0xf0,0x5c}, +{0x00,0xf8064000}, +{0x04,0x80a6c01c}, +{0x08,0x24800096}, +{0x0c,0xb0102000}, +{0x10,0xf2066008}, +{0x14,0x80a6c019}, +{0x18,0x26800092}, +{0x1c,0xb0102000}, +{0x20,0x03000017}, +{0x24,0x8210632c}, +{0x28,0xc2004000}, +{0x2c,0x80a06000}, +{0x30,0x02800004}, +{0x34,0xde1023b6}, +{0x38,0xc20822b6}, +{0x3c,0x9e03c001}, +{0x40,0xba5bc009}, +{0x44,0x833f601f}, +{0x48,0x83306019}, +{0x4c,0xba074001}, +{0x50,0x9f3f6007}, +{0x54,0xd8002470}, +{0x58,0xba5bc00c}, +{0x5c,0x833f601f}, +{0x60,0x83306018}, +{0x64,0xba074001}, +{0x68,0xbb3f6008}, +{0x6c,0x80a6c01d}, +{0x70,0x0680007c}, +{0x74,0xb0102000}, +{0x78,0x80a2a000}, +{0x7c,0x32800008}, +{0xf0,0x5d}, +{0x00,0xc2002300}, +{0x04,0x8226c019}, +{0x08,0x80a64001}, +{0x0c,0x16800011}, +{0x10,0xb4100019}, +{0x14,0x1080000f}, +{0x18,0xb4100001}, +{0x1c,0x82007fff}, +{0x20,0x80a28001}, +{0x24,0x12800008}, +{0x28,0x80a70019}, +{0x2c,0xb426c01c}, +{0x30,0x80a6801c}, +{0x34,0x16800008}, +{0x38,0x80a70019}, +{0x3c,0x10800006}, +{0x40,0xb410001c}, +{0x44,0x06800003}, +{0x48,0xb4100019}, +{0x4c,0xb410001c}, +{0x50,0x80a70019}, +{0x54,0xb406801b}, +{0x58,0x14800003}, +{0x5c,0x9626c019}, +{0x60,0x9626c01c}, +{0x64,0xba5bc00c}, +{0x68,0x833f601f}, +{0x6c,0x83306019}, +{0x70,0xba074001}, +{0x74,0xb0102003}, +{0x78,0x80a62003}, +{0x7c,0x12800004}, +{0xf0,0x5e}, +{0x00,0x80a62002}, +{0x04,0x10800004}, +{0x08,0x9a10000f}, +{0x0c,0x22800002}, +{0x10,0x9b3f6007}, +{0x14,0x8333601f}, +{0x18,0x82034001}, +{0x1c,0x80a6800d}, +{0x20,0x04800005}, +{0x24,0x83386001}, +{0x28,0x80a2c001}, +{0x2c,0x34800006}, +{0x30,0xc2002300}, +{0x34,0xb0863fff}, +{0x38,0x1cbffff1}, +{0x3c,0x80a62003}, +{0x40,0xc2002300}, +{0x44,0x82007fff}, +{0x48,0x80a28001}, +{0x4c,0x12800042}, +{0x50,0x80a62001}, +{0x54,0xb8102000}, +{0x58,0xf2002304}, +{0x5c,0x80a70019}, +{0x60,0x1a80000e}, +{0x64,0xb6102000}, +{0x68,0x03000019}, +{0x6c,0x981063c0}, +{0x70,0xbb2f2002}, +{0x74,0xc207400c}, +{0x78,0x80a06000}, +{0x7c,0x04800004}, +{0xf0,0x5f}, +{0x00,0xb8072001}, +{0x04,0xc207400c}, +{0x08,0xb606c001}, +{0x0c,0x80a70019}, +{0x10,0x0abffff9}, +{0x14,0xbb2f2002}, +{0x18,0xc20021d8}, +{0x1c,0x825ec001}, +{0x20,0xbb38601f}, +{0x24,0xbb376019}, +{0x28,0x8200401d}, +{0x2c,0x83386007}, +{0x30,0x9e03c001}, +{0x34,0xb8102003}, +{0x38,0x80a72003}, +{0x3c,0x12800004}, +{0x40,0x80a72002}, +{0x44,0x1080000a}, +{0x48,0x9a10000f}, +{0x4c,0x32800009}, +{0x50,0x8333601f}, +{0x54,0xfa002470}, +{0x58,0xba5bc01d}, +{0x5c,0x833f601f}, +{0x60,0x83306019}, +{0x64,0xba074001}, +{0x68,0x9b3f6007}, +{0x6c,0x8333601f}, +{0x70,0x82034001}, +{0x74,0x80a6800d}, +{0x78,0x04800005}, +{0x7c,0x83386001}, +{0xf0,0x60}, +{0x00,0x80a2c001}, +{0x04,0x14800006}, +{0x08,0x80a62001}, +{0x0c,0xb8873fff}, +{0x10,0x1cbfffeb}, +{0x14,0x80a72003}, +{0x18,0x80a62001}, +{0x1c,0x14800003}, +{0x20,0xba102001}, +{0x24,0xba102000}, +{0x28,0x80a72001}, +{0x2c,0x04800003}, +{0x30,0x82102001}, +{0x34,0x82102000}, +{0x38,0x808f4001}, +{0x3c,0x02800006}, +{0x40,0x80a62001}, +{0x44,0x03000048}, +{0x48,0x82106345}, +{0x4c,0x10800004}, +{0x50,0xc22026f8}, +{0x54,0x14800003}, +{0x58,0x01000000}, +{0x5c,0xb0102000}, +{0x60,0x81c7e008}, +{0x64,0x81e80000}, +{0x68,0x9de3bf88}, +{0x6c,0x821026a0}, +{0x70,0xc2202580}, +{0x74,0xc02026f8}, +{0x78,0x90102000}, +{0x7c,0x96102000}, +{0xf0,0x61}, +{0x00,0x832ae002}, +{0x04,0x9602e001}, +{0x08,0xc02067e0}, +{0x0c,0xc0206720}, +{0x10,0x80a2e003}, +{0x14,0x04bffffb}, +{0x18,0xc0206730}, +{0x1c,0x03000018}, +{0x20,0xc0202514}, +{0x24,0x9a1062a8}, +{0x28,0xa0102000}, +{0x2c,0x832c2002}, +{0x30,0xa0042001}, +{0x34,0x80a42019}, +{0x38,0x04bffffd}, +{0x3c,0xc020400d}, +{0x40,0xa0102000}, +{0x44,0xc2002300}, +{0x48,0x80a40001}, +{0x4c,0x1a800018}, +{0x50,0x03000018}, +{0x54,0x921062ac}, +{0x58,0x82006400}, +{0x5c,0x9e106328}, +{0x60,0x832c2003}, +{0x64,0x9800400f}, +{0x68,0x952c2002}, +{0x6c,0x96102001}, +{0x70,0xc2030000}, +{0x74,0x9a380001}, +{0x78,0x9b3b601f}, +{0x7c,0x8208400d}, +{0xf0,0x62}, +{0x00,0xda028009}, +{0x04,0x9a034001}, +{0x08,0xda228009}, +{0x0c,0x9682ffff}, +{0x10,0x1cbffff8}, +{0x14,0x98032004}, +{0x18,0xa0042001}, +{0x1c,0xc2002300}, +{0x20,0x80a40001}, +{0x24,0x0abffff0}, +{0x28,0x832c2003}, +{0x2c,0xa0102001}, +{0x30,0xd8002300}, +{0x34,0x80a4000c}, +{0x38,0x1a80000f}, +{0x3c,0x03000018}, +{0x40,0x941062ac}, +{0x44,0x961062a8}, +{0x48,0x832c2002}, +{0x4c,0xda00400a}, +{0x50,0xc200400b}, +{0x54,0x8200400d}, +{0x58,0x80a04008}, +{0x5c,0x04800003}, +{0x60,0xa0042001}, +{0x64,0x90100001}, +{0x68,0x80a4000c}, +{0x6c,0x0abffff8}, +{0x70,0x832c2002}, +{0x74,0x1b000017}, +{0x78,0x82136324}, +{0x7c,0xc2004000}, +{0xf0,0x63}, +{0x00,0x80a06001}, +{0x04,0x1280001f}, +{0x08,0x82136388}, +{0x0c,0x03000018}, +{0x10,0x921062ac}, +{0x14,0x98102000}, +{0x18,0x96102001}, +{0x1c,0x941062a8}, +{0x20,0x832ae002}, +{0x24,0xda004009}, +{0x28,0xc200400a}, +{0x2c,0x8200400d}, +{0x30,0x80a0400c}, +{0x34,0x04800003}, +{0x38,0x9602e001}, +{0x3c,0x98100001}, +{0x40,0x80a2e015}, +{0x44,0x04bffff8}, +{0x48,0x832ae002}, +{0x4c,0xc20022b0}, +{0x50,0x80a30001}, +{0x54,0x03000017}, +{0x58,0x8210637c}, +{0x5c,0x088000f6}, +{0x60,0xd8204000}, +{0x64,0xda002514}, +{0x68,0x03004d40}, +{0x6c,0x9a036001}, +{0x70,0x821060e3}, +{0x74,0xc2202720}, +{0x78,0x108000ef}, +{0x7c,0xda202514}, +{0xf0,0x64}, +{0x00,0xc2004000}, +{0x04,0x80a06001}, +{0x08,0x1280000e}, +{0x0c,0xa0102000}, +{0x10,0xc21022ce}, +{0x14,0x80a20001}, +{0x18,0x04800004}, +{0x1c,0x9a13632c}, +{0x20,0x10800006}, +{0x24,0x8210203c}, +{0x28,0xc2034000}, +{0x2c,0x80a06000}, +{0x30,0x04800003}, +{0x34,0x82007fff}, +{0x38,0xc2234000}, +{0x3c,0xa0102000}, +{0x40,0xc2002300}, +{0x44,0x80a40001}, +{0x48,0x1a8000b4}, +{0x4c,0xa4043fff}, +{0x50,0x92042002}, +{0x54,0x80a48009}, +{0x58,0x9a102001}, +{0x5c,0x94102001}, +{0x60,0x16800018}, +{0x64,0x98100012}, +{0x68,0x03000019}, +{0x6c,0x9e10632c}, +{0x70,0x90106328}, +{0x74,0x80a32000}, +{0x78,0x2680000f}, +{0x7c,0x98032001}, +{0xf0,0x65}, +{0x00,0xc2002300}, +{0x04,0x80a30001}, +{0x08,0x1a80000a}, +{0x0c,0x972b2003}, +{0x10,0xc202c008}, +{0x14,0x80a06000}, +{0x18,0x34800002}, +{0x1c,0x9a034001}, +{0x20,0xc202c00f}, +{0x24,0x80a06000}, +{0x28,0x34800002}, +{0x2c,0x94028001}, +{0x30,0x98032001}, +{0x34,0x80a30009}, +{0x38,0x06bffff0}, +{0x3c,0x80a32000}, +{0x40,0x9a03400a}, +{0x44,0x832aa008}, +{0x48,0x9938601f}, +{0x4c,0x81832000}, +{0x50,0x01000000}, +{0x54,0x01000000}, +{0x58,0x01000000}, +{0x5c,0x8278400d}, +{0x60,0x94007f80}, +{0x64,0x833aa01f}, +{0x68,0x941a8001}, +{0x6c,0x94228001}, +{0x70,0x82102080}, +{0x74,0x9420400a}, +{0x78,0x8238000a}, +{0x7c,0x8338601f}, +{0xf0,0x66}, +{0x00,0x940a8001}, +{0x04,0xda082479}, +{0x08,0x9a5a800d}, +{0x0c,0x833b601f}, +{0x10,0x83306019}, +{0x14,0x9a034001}, +{0x18,0x9b3b6007}, +{0x1c,0xc2102548}, +{0x20,0x80886001}, +{0x24,0x0280000a}, +{0x28,0x9403400d}, +{0x2c,0xc2002558}, +{0x30,0x80a06000}, +{0x34,0x32800007}, +{0x38,0x9402a080}, +{0x3c,0x90100010}, +{0x40,0x9207bfe8}, +{0x44,0x10800005}, +{0x48,0xd410218c}, +{0x4c,0x9402a080}, +{0x50,0x90100010}, +{0x54,0x9207bfe8}, +{0x58,0xc2002fdc}, +{0x5c,0x9fc04000}, +{0x60,0x01000000}, +{0x64,0xa2922000}, +{0x68,0x22bfffb6}, +{0x6c,0xa0042001}, +{0x70,0xda07bfec}, +{0x74,0xc207bfe8}, +{0x78,0x8200400d}, +{0x7c,0xda07bff0}, +{0xf0,0x67}, +{0x00,0xa600400d}, +{0x04,0x96102000}, +{0x08,0x9b2ae002}, +{0x0c,0x9602e001}, +{0x10,0xc2036840}, +{0x14,0x80a2e003}, +{0x18,0x04bffffc}, +{0x1c,0xc2236850}, +{0x20,0x1b000019}, +{0x24,0x992c2003}, +{0x28,0x92136328}, +{0x2c,0xc2030009}, +{0x30,0xc2202840}, +{0x34,0x9a13632c}, +{0x38,0xc203000d}, +{0x3c,0x94042001}, +{0x40,0x96100012}, +{0x44,0xc2202844}, +{0x48,0xc0202848}, +{0x4c,0x80a4800a}, +{0x50,0x14800017}, +{0x54,0xc020284c}, +{0x58,0x90100009}, +{0x5c,0x9210000d}, +{0x60,0x80a2e000}, +{0x64,0x2680000f}, +{0x68,0x9602e001}, +{0x6c,0xc2002300}, +{0x70,0x80a2c001}, +{0x74,0x1a80000a}, +{0x78,0x992ae003}, +{0x7c,0xda030008}, +{0xf0,0x68}, +{0x00,0xc2002848}, +{0x04,0x8200400d}, +{0x08,0xc2202848}, +{0x0c,0xda030009}, +{0x10,0xc200284c}, +{0x14,0x8200400d}, +{0x18,0xc220284c}, +{0x1c,0x9602e001}, +{0x20,0x80a2c00a}, +{0x24,0x04bffff0}, +{0x28,0x80a2e000}, +{0x2c,0xd0002514}, +{0x30,0x80a22004}, +{0x34,0x1280000b}, +{0x38,0x80a46001}, +{0x3c,0xc2002fe4}, +{0x40,0x80a06000}, +{0x44,0x02800007}, +{0x48,0x80a46001}, +{0x4c,0x9fc04000}, +{0x50,0x90100013}, +{0x54,0x80a23fff}, +{0x58,0x0280002e}, +{0x5c,0x80a46001}, +{0x60,0x12800007}, +{0x64,0x80a46002}, +{0x68,0x03000008}, +{0x6c,0x82040001}, +{0x70,0x9b2a2002}, +{0x74,0x10800009}, +{0x78,0xc2236720}, +{0x7c,0x12800006}, +{0xf0,0x69}, +{0x00,0x9b2a2002}, +{0x04,0x03000010}, +{0x08,0x82040001}, +{0x0c,0x10800003}, +{0x10,0xc2236720}, +{0x14,0xe0236720}, +{0x18,0xda002300}, +{0x1c,0x83336001}, +{0x20,0x80a40001}, +{0x24,0x1a800005}, +{0x28,0x03000018}, +{0x2c,0x821062b0}, +{0x30,0x10800005}, +{0x34,0xda004000}, +{0x38,0x9b2b6002}, +{0x3c,0x821062a4}, +{0x40,0xda034001}, +{0x44,0x0300003f}, +{0x48,0x821063ff}, +{0x4c,0x820b4001}, +{0x50,0x9b2ce010}, +{0x54,0x992a2002}, +{0x58,0x9a134001}, +{0x5c,0xc2032730}, +{0x60,0x8210400d}, +{0x64,0xc2232730}, +{0x68,0xe02327e0}, +{0x6c,0xc2002514}, +{0x70,0x82006001}, +{0x74,0x80a06004}, +{0x78,0x12800006}, +{0x7c,0xc2202514}, +{0xf0,0x6a}, +{0x00,0xc2002fe4}, +{0x04,0x80a06000}, +{0x08,0x22800005}, +{0x0c,0xc2002514}, +{0x10,0x10bfff4c}, +{0x14,0xa0042001}, +{0x18,0xc2002514}, +{0x1c,0x80a06000}, +{0x20,0x3280000c}, +{0x24,0xc2002520}, +{0x28,0x96102000}, +{0x2c,0x832ae002}, +{0x30,0x9602e001}, +{0x34,0xc0206850}, +{0x38,0x80a2e003}, +{0x3c,0x04bffffc}, +{0x40,0xc0206840}, +{0x44,0xc20026a0}, +{0x48,0x10800007}, +{0x4c,0x82087bff}, +{0x50,0x80a06000}, +{0x54,0x22800006}, +{0x58,0x96102000}, +{0x5c,0xc20026a0}, +{0x60,0x82106400}, +{0x64,0xc22026a0}, +{0x68,0x96102000}, +{0x6c,0xd4002350}, +{0x70,0x992ae002}, +{0x74,0xda032850}, +{0x78,0x9a5b400a}, +{0x7c,0x833b601f}, +{0xf0,0x6b}, +{0x00,0x83306019}, +{0x04,0x9a034001}, +{0x08,0xc2032840}, +{0x0c,0x9b3b6007}, +{0x10,0x80a0400d}, +{0x14,0x16800005}, +{0x18,0x9602e001}, +{0x1c,0xc20026a0}, +{0x20,0x82106400}, +{0x24,0xc22026a0}, +{0x28,0x80a2e003}, +{0x2c,0x04bffff2}, +{0x30,0x992ae002}, +{0x34,0x1b000017}, +{0x38,0x82136388}, +{0x3c,0xc2004000}, +{0x40,0x80a06001}, +{0x44,0x12800045}, +{0x48,0x82136324}, +{0x4c,0xc2004000}, +{0x50,0x80a06001}, +{0x54,0x02800041}, +{0x58,0x9e102000}, +{0x5c,0xda002514}, +{0x60,0xc02026e0}, +{0x64,0x80a3c00d}, +{0x68,0xa4102000}, +{0x6c,0xa0102000}, +{0x70,0x1a80000a}, +{0x74,0x92102000}, +{0x78,0x98102001}, +{0x7c,0x832a6002}, +{0xf0,0x6c}, +{0x00,0xc20067e0}, +{0x04,0x832b0001}, +{0x08,0x92026001}, +{0x0c,0x80a2400d}, +{0x10,0x0abffffb}, +{0x14,0xa4148001}, +{0x18,0x92102000}, +{0x1c,0xe2002514}, +{0x20,0x80a24011}, +{0x24,0x1a800026}, +{0x28,0x03000019}, +{0x2c,0xa810632c}, +{0x30,0xa6106328}, +{0x34,0x832a6002}, +{0x38,0xc20067e0}, +{0x3c,0x94007ffd}, +{0x40,0x90102001}, +{0x44,0x8238000a}, +{0x48,0x9930601f}, +{0x4c,0x833c800a}, +{0x50,0x80886001}, +{0x54,0x32800014}, +{0x58,0x90823fff}, +{0x5c,0xc2002300}, +{0x60,0x80a28001}, +{0x64,0x82402000}, +{0x68,0x8088400c}, +{0x6c,0x0280000d}, +{0x70,0x9b2aa003}, +{0x74,0xd8034013}, +{0x78,0xd6034014}, +{0x7c,0x8238000c}, +{0xf0,0x6d}, +{0x00,0x9a38000b}, +{0x04,0x8338601f}, +{0x08,0x980b0001}, +{0x0c,0x9b3b601f}, +{0x10,0x9804000c}, +{0x14,0x960ac00d}, +{0x18,0xa003000b}, +{0x1c,0x9e03e001}, +{0x20,0x90823fff}, +{0x24,0x1cbfffe8}, +{0x28,0x9402a006}, +{0x2c,0x92026001}, +{0x30,0x80a24011}, +{0x34,0x0abfffe1}, +{0x38,0x832a6002}, +{0x3c,0x9b3c201f}, +{0x40,0x81836000}, +{0x44,0x01000000}, +{0x48,0x01000000}, +{0x4c,0x01000000}, +{0x50,0x827c000f}, +{0x54,0xc22026e0}, +{0x58,0x81c7e008}, +{0x5c,0x81e80000}, +{0x60,0x031fffff}, +{0x64,0x981063ff}, +{0x68,0x9a102000}, +{0x6c,0x832b6002}, +{0x70,0xc2106730}, +{0x74,0x80a0400c}, +{0x78,0x36800005}, +{0x7c,0x9a036001}, +{0xf0,0x6e}, +{0x00,0x98100001}, +{0x04,0x9610000d}, +{0x08,0x9a036001}, +{0x0c,0x80a36003}, +{0x10,0x04bffff8}, +{0x14,0x832b6002}, +{0x18,0x80a30008}, +{0x1c,0x1680000a}, +{0x20,0x90103fff}, +{0x24,0x832ae002}, +{0x28,0xc02067e0}, +{0x2c,0xc0206720}, +{0x30,0xc0206730}, +{0x34,0xc2002514}, +{0x38,0x82007fff}, +{0x3c,0xc2202514}, +{0x40,0x9010000b}, +{0x44,0x81c3e008}, +{0x48,0x01000000}, +{0x4c,0x9de3bf50}, +{0x50,0xc20022d4}, +{0x54,0x80886010}, +{0x58,0xa0102000}, +{0x5c,0xa2102000}, +{0x60,0x02800009}, +{0x64,0x972e2002}, +{0x68,0xc202e720}, +{0x6c,0xda002324}, +{0x70,0x82086fff}, +{0x74,0x8258400d}, +{0x78,0x8330600a}, +{0x7c,0x1080000e}, +{0xf0,0x6f}, +{0x00,0xc227bff0}, +{0x04,0xc212e720}, +{0x08,0xda002328}, +{0x0c,0x82086fff}, +{0x10,0x8258400d}, +{0x14,0x8330600b}, +{0x18,0xc227bff0}, +{0x1c,0xc202e720}, +{0x20,0x82086fff}, +{0x24,0xa3306005}, +{0x28,0xa0100011}, +{0x2c,0x9b2c6005}, +{0x30,0xa220400d}, +{0x34,0xa407bff8}, +{0x38,0x96102000}, +{0x3c,0x98100012}, +{0x40,0x8202c00b}, +{0x44,0xda5061c0}, +{0x48,0xc25061b0}, +{0x4c,0xc2233fd8}, +{0x50,0xda233fb8}, +{0x54,0x9602e001}, +{0x58,0x80a2e007}, +{0x5c,0x04bffff9}, +{0x60,0x98032004}, +{0x64,0x96102008}, +{0x68,0x9007bfd0}, +{0x6c,0x9207bfb0}, +{0x70,0x7ffff956}, +{0x74,0xd407bff0}, +{0x78,0xd6502456}, +{0x7c,0x80a2e000}, +{0xf0,0x70}, +{0x00,0x02800032}, +{0x04,0x82380008}, +{0x08,0xc2002328}, +{0x0c,0x8220400b}, +{0x10,0x80a20001}, +{0x14,0x28800016}, +{0x18,0xd6502454}, +{0x1c,0xd84c2440}, +{0x20,0xc24c2441}, +{0x24,0x8220400c}, +{0x28,0x82584011}, +{0x2c,0x9b38601f}, +{0x30,0x9b33601b}, +{0x34,0x8200400d}, +{0x38,0x83386005}, +{0x3c,0x9a030001}, +{0x40,0x8222000b}, +{0x44,0x8258400b}, +{0x48,0x9a22c00d}, +{0x4c,0x9938601f}, +{0x50,0x81832000}, +{0x54,0x01000000}, +{0x58,0x01000000}, +{0x5c,0x01000000}, +{0x60,0x8278400d}, +{0x64,0x9002c001}, +{0x68,0xd6502454}, +{0x6c,0x80a2000b}, +{0x70,0x16800016}, +{0x74,0x82380008}, +{0x78,0xd84c245c}, +{0x7c,0xc24c245d}, +{0xf0,0x71}, +{0x00,0x8220400c}, +{0x04,0x82584011}, +{0x08,0x9b38601f}, +{0x0c,0x9b33601b}, +{0x10,0x8200400d}, +{0x14,0x83386005}, +{0x18,0x9a030001}, +{0x1c,0x8222c008}, +{0x20,0x8258400b}, +{0x24,0x9a22c00d}, +{0x28,0x9938601f}, +{0x2c,0x81832000}, +{0x30,0x01000000}, +{0x34,0x01000000}, +{0x38,0x01000000}, +{0x3c,0x8278400d}, +{0x40,0x9022c001}, +{0x44,0x82380008}, +{0x48,0x8338601f}, +{0x4c,0x900a0001}, +{0x50,0xc2002328}, +{0x54,0x82007fff}, +{0x58,0x80a20001}, +{0x5c,0x38800002}, +{0x60,0x90100001}, +{0x64,0xd024bff8}, +{0x68,0xc20022d4}, +{0x6c,0x80886010}, +{0x70,0x972e2002}, +{0x74,0x0280000f}, +{0x78,0xc207bff0}, +{0x7c,0x9b28600a}, +{0xf0,0x72}, +{0x00,0x81800000}, +{0x04,0xc2002324}, +{0x08,0x01000000}, +{0x0c,0x01000000}, +{0x10,0x82734001}, +{0x14,0x9a100001}, +{0x18,0xc202e720}, +{0x1c,0x9a0b6fff}, +{0x20,0x82087000}, +{0x24,0x8210400d}, +{0x28,0x1080000f}, +{0x2c,0xc222e720}, +{0x30,0x8328600b}, +{0x34,0x81800000}, +{0x38,0xd8002328}, +{0x3c,0x01000000}, +{0x40,0x01000000}, +{0x44,0x9870400c}, +{0x48,0x820b2fff}, +{0x4c,0xd802e720}, +{0x50,0x1b03ffc0}, +{0x54,0x9a2b000d}, +{0x58,0x83286010}, +{0x5c,0x9a134001}, +{0x60,0xda22e720}, +{0x64,0x81c7e008}, +{0x68,0x81e80000}, +{0x6c,0x03169696}, +{0x70,0xda002180}, +{0x74,0x8210625a}, +{0x78,0x80a34001}, +{0x7c,0x94102000}, +{0xf0,0x73}, +{0x00,0x12800006}, +{0x04,0x96102000}, +{0x08,0x033fc180}, +{0x0c,0x82106030}, +{0x10,0x10800022}, +{0x14,0xda204000}, +{0x18,0xc202c000}, +{0x1c,0x9602e004}, +{0x20,0x80a2e4ff}, +{0x24,0x08bffffd}, +{0x28,0x94028001}, +{0x2c,0x96102d00}, +{0x30,0xd2002ff8}, +{0x34,0x03000019}, +{0x38,0x80a2c009}, +{0x3c,0x1a80000b}, +{0x40,0x901063ff}, +{0x44,0xd802c000}, +{0x48,0x9602e004}, +{0x4c,0x80a2c009}, +{0x50,0x9a402000}, +{0x54,0x80a2000b}, +{0x58,0x82603fff}, +{0x5c,0x808b4001}, +{0x60,0x12bffff9}, +{0x64,0x9402800c}, +{0x68,0xc2002200}, +{0x6c,0x94228001}, +{0x70,0x03169696}, +{0x74,0x8210625a}, +{0x78,0x80a28001}, +{0x7c,0x033fc180}, +{0xf0,0x74}, +{0x00,0x82106030}, +{0x04,0x02800005}, +{0x08,0xd4204000}, +{0x0c,0x0300000a}, +{0x10,0x81c062a4}, +{0x14,0x90102001}, +{0x18,0x01000000}, +{0x1c,0x81c3e008}, +{0x20,0x01000000}, +{0x24,0x1500003f}, +{0x28,0xd8002508}, +{0x2c,0x8212a300}, +{0x30,0x808b3f00}, +{0x34,0x02800016}, +{0x38,0x9a0b0001}, +{0x3c,0xc200254c}, +{0x40,0x8210400d}, +{0x44,0xc220254c}, +{0x48,0x1b3fc000}, +{0x4c,0xc2002500}, +{0x50,0x960b000d}, +{0x54,0x80a06058}, +{0x58,0xc0202508}, +{0x5c,0x0880000c}, +{0x60,0x033fffc0}, +{0x64,0x9a0b0001}, +{0x68,0x03168000}, +{0x6c,0x80a2c001}, +{0x70,0x12800007}, +{0x74,0x9412a3ff}, +{0x78,0xc2002548}, +{0x7c,0x8208400a}, +{0xf0,0x75}, +{0x00,0x8210400d}, +{0x04,0xc2202548}, +{0x08,0xc02026e4}, +{0x0c,0x81c3e008}, +{0x10,0x01000000}, +{0x14,0x9de3bf88}, +{0x18,0x7ffff5fa}, +{0x1c,0xae102001}, +{0x20,0xaa100008}, +{0x24,0xc027bfe8}, +{0x28,0xc027bfec}, +{0x2c,0x7ffff9b4}, +{0x30,0xc027bff0}, +{0x34,0x80a22000}, +{0x38,0x0280000d}, +{0x3c,0xba102000}, +{0x40,0x03000017}, +{0x44,0x82106324}, +{0x48,0xc2004000}, +{0x4c,0x80a06000}, +{0x50,0x12800005}, +{0x54,0x82102040}, +{0x58,0xc227bfec}, +{0x5c,0x10800007}, +{0x60,0xc227bfe8}, +{0x64,0x10800005}, +{0x68,0xc227bff0}, +{0x6c,0x82102008}, +{0x70,0xc227bfe8}, +{0x74,0xba102001}, +{0x78,0xa4102000}, +{0x7c,0xa8102000}, +{0xf0,0x76}, +{0x00,0xa6102000}, +{0x04,0x23000018}, +{0x08,0xa12ca002}, +{0x0c,0x8214604c}, +{0x10,0xc2040001}, +{0x14,0x80a06000}, +{0x18,0x12800006}, +{0x1c,0xac07bff8}, +{0x20,0x90146068}, +{0x24,0x7ffffad8}, +{0x28,0x90050008}, +{0x2c,0xac07bff8}, +{0x30,0x82040016}, +{0x34,0xc2007ff0}, +{0x38,0x80a06000}, +{0x3c,0x22800014}, +{0x40,0xa404a001}, +{0x44,0x90100011}, +{0x48,0x96102000}, +{0x4c,0x94146068}, +{0x50,0x98100013}, +{0x54,0x8202c00b}, +{0x58,0xda154001}, +{0x5c,0xc203000a}, +{0x60,0x8200400d}, +{0x64,0xc223000a}, +{0x68,0x9602e001}, +{0x6c,0x80a2e02f}, +{0x70,0x04bffff9}, +{0x74,0x98032004}, +{0x78,0x9a12204c}, +{0x7c,0xc204000d}, +{0xf0,0x77}, +{0x00,0x82006001}, +{0x04,0xc224000d}, +{0x08,0xa404a001}, +{0x0c,0xa604e0c0}, +{0x10,0x80a4a002}, +{0x14,0x04bfffdc}, +{0x18,0xa80520c0}, +{0x1c,0xa4102000}, +{0x20,0xa2102000}, +{0x24,0xa12ca002}, +{0x28,0x82040016}, +{0x2c,0xda007ff0}, +{0x30,0x80a36000}, +{0x34,0x2280002f}, +{0x38,0xa404a001}, +{0x3c,0x11000018}, +{0x40,0x9812204c}, +{0x44,0xc204000c}, +{0x48,0x80a0400d}, +{0x4c,0x24800029}, +{0x50,0xa404a001}, +{0x54,0x82122068}, +{0x58,0xa610000c}, +{0x5c,0x98044001}, +{0x60,0x96102000}, +{0x64,0x94122368}, +{0x68,0xc2030000}, +{0x6c,0x9b2ae002}, +{0x70,0x9338601f}, +{0x74,0x81826000}, +{0x78,0xd2040013}, +{0x7c,0x01000000}, +{0xf0,0x78}, +{0x00,0x01000000}, +{0x04,0x82784009}, +{0x08,0x9602e001}, +{0x0c,0xc223400a}, +{0x10,0x80a2e02f}, +{0x14,0x04bffff5}, +{0x18,0x98032004}, +{0x1c,0x03000017}, +{0x20,0x82106324}, +{0x24,0xda004000}, +{0x28,0x8203400d}, +{0x2c,0x8200400d}, +{0x30,0x13000019}, +{0x34,0x83286005}, +{0x38,0x92126268}, +{0x3c,0x92004009}, +{0x40,0x7ffffa47}, +{0x44,0x90122368}, +{0x48,0xc20026e4}, +{0x4c,0x82006001}, +{0x50,0xc22026e4}, +{0x54,0xc0240013}, +{0x58,0x80a76000}, +{0x5c,0x02800004}, +{0x60,0xae102000}, +{0x64,0x7ffff93d}, +{0x68,0x01000000}, +{0x6c,0xa404a001}, +{0x70,0x80a4a002}, +{0x74,0x04bfffcc}, +{0x78,0xa20460c0}, +{0x7c,0xee202584}, +{0xf0,0x79}, +{0x00,0x81c7e008}, +{0x04,0x81e80000}, +{0x08,0x9de3bf98}, +{0x0c,0x03000017}, +{0x10,0x82106324}, +{0x14,0xc2004000}, +{0x18,0x80a06001}, +{0x1c,0x02800062}, +{0x20,0x01000000}, +{0x24,0xc2502198}, +{0x28,0x80a06000}, +{0x2c,0x0280005e}, +{0x30,0x01000000}, +{0x34,0xc2102548}, +{0x38,0x80886001}, +{0x3c,0x1280005a}, +{0x40,0x94102000}, +{0x44,0xc2002300}, +{0x48,0x80a28001}, +{0x4c,0x1a80003c}, +{0x50,0x96102000}, +{0x54,0x03000019}, +{0x58,0x90106328}, +{0x5c,0x98102000}, +{0x60,0x832ae003}, +{0x64,0xb0004008}, +{0x68,0xb2102000}, +{0x6c,0xb52b2010}, +{0x70,0xfa502198}, +{0x74,0xc2060000}, +{0x78,0x80a0401d}, +{0x7c,0x36800026}, +{0xf0,0x7a}, +{0x00,0xb2066001}, +{0x04,0xb6102000}, +{0x08,0x9a030019}, +{0x0c,0x92102001}, +{0x10,0x9e16a100}, +{0x14,0xbb2ee002}, +{0x18,0xf8076524}, +{0x1c,0x80a72000}, +{0x20,0x22800012}, +{0x24,0xc2076524}, +{0x28,0xc20f6525}, +{0x2c,0x80a0400d}, +{0x30,0x3280000e}, +{0x34,0xc2076524}, +{0x38,0x82072100}, +{0x3c,0xc2276524}, +{0x40,0xfa0f6526}, +{0x44,0xc208219a}, +{0x48,0x80a74001}, +{0x4c,0x0880000c}, +{0x50,0x832a401b}, +{0x54,0xc200254c}, +{0x58,0x3b000200}, +{0x5c,0x8210401d}, +{0x60,0x10800031}, +{0x64,0xc220254c}, +{0x68,0x80a06000}, +{0x6c,0x32800006}, +{0x70,0xb606e001}, +{0x74,0x832a401b}, +{0x78,0xde276524}, +{0x7c,0x10800005}, +{0xf0,0x7b}, +{0x00,0x94128001}, +{0x04,0x80a6e003}, +{0x08,0x04bfffe4}, +{0x0c,0xbb2ee002}, +{0x10,0xb2066001}, +{0x14,0x03000040}, +{0x18,0xb4068001}, +{0x1c,0x80a66001}, +{0x20,0x04bfffd4}, +{0x24,0xb0062004}, +{0x28,0x9602e001}, +{0x2c,0xc2002300}, +{0x30,0x80a2c001}, +{0x34,0x0abfffcb}, +{0x38,0x98032002}, +{0x3c,0xb2102000}, +{0x40,0xb6102000}, +{0x44,0xb92ee002}, +{0x48,0xc2072524}, +{0x4c,0xb4006001}, +{0x50,0xbb3a801b}, +{0x54,0x80a06000}, +{0x58,0x02800013}, +{0x5c,0xb12e6002}, +{0x60,0x808f6001}, +{0x64,0x3280000a}, +{0x68,0xc2072524}, +{0x6c,0xf4272524}, +{0x70,0xfa0f2527}, +{0x74,0xc208219b}, +{0x78,0x80a74001}, +{0x7c,0x28800004}, +{0xf0,0x7c}, +{0x00,0xc2072524}, +{0x04,0x10800004}, +{0x08,0xc0272524}, +{0x0c,0xb2066001}, +{0x10,0xc2262524}, +{0x14,0xb606e001}, +{0x18,0x80a6e003}, +{0x1c,0x04bfffeb}, +{0x20,0xb92ee002}, +{0x24,0x81c7e008}, +{0x28,0x81e80000}, +{0x2c,0x9de3bf98}, +{0x30,0x7ffff7c4}, +{0x34,0x01000000}, +{0x38,0x1b000017}, +{0x3c,0x82102001}, +{0x40,0x9a136388}, +{0x44,0xc2234000}, +{0x48,0xc2002fe0}, +{0x4c,0x9fc04000}, +{0x50,0x01000000}, +{0x54,0x01000000}, +{0x58,0x81c7e008}, +{0x5c,0x81e80000}, +{0x60,0x9de3bf98}, +{0x64,0x03000017}, +{0x68,0x82106324}, +{0x6c,0xc2004000}, +{0x70,0x80a06001}, +{0x74,0x02800066}, +{0x78,0x9a102000}, +{0x7c,0xf8002514}, +{0xf0,0x7d}, +{0x00,0xc02026e0}, +{0x04,0x80a3401c}, +{0x08,0xb0102000}, +{0x0c,0x1a80000f}, +{0x10,0xb2102000}, +{0x14,0xc2002300}, +{0x18,0xbb306001}, +{0x1c,0xb6102001}, +{0x20,0x832e6002}, +{0x24,0xc20067e0}, +{0x28,0x80a0401d}, +{0x2c,0x0a800003}, +{0x30,0xb2066001}, +{0x34,0x8220401d}, +{0x38,0x832ec001}, +{0x3c,0x80a6401c}, +{0x40,0x0abffff8}, +{0x44,0xb0160001}, +{0x48,0x3b000017}, +{0x4c,0xb4176380}, +{0x50,0xc2002300}, +{0x54,0xb93e2001}, +{0x58,0xba176384}, +{0x5c,0xb816001c}, +{0x60,0xb6060018}, +{0x64,0x83306001}, +{0x68,0xb2102000}, +{0x6c,0xc0274000}, +{0x70,0xb017001b}, +{0x74,0x80a64001}, +{0x78,0x1a80002e}, +{0x7c,0xc0268000}, +{0xf0,0x7e}, +{0x00,0x94100001}, +{0x04,0x03000019}, +{0x08,0x98106328}, +{0x0c,0x9610632c}, +{0x10,0x82007800}, +{0x14,0x9e106384}, +{0x18,0x92106380}, +{0x1c,0x833e0019}, +{0x20,0x80886001}, +{0x24,0x1280001f}, +{0x28,0xbb2e6003}, +{0x2c,0xf607400c}, +{0x30,0x8238001b}, +{0x34,0xf407400b}, +{0x38,0x8338601f}, +{0x3c,0xb60ec001}, +{0x40,0xb838001a}, +{0x44,0xfa03c000}, +{0x48,0xc2002300}, +{0x4c,0xb93f201f}, +{0x50,0xba07401b}, +{0x54,0xb40e801c}, +{0x58,0x83306001}, +{0x5c,0xba07401a}, +{0x60,0x82004019}, +{0x64,0xfa23c000}, +{0x68,0x83286003}, +{0x6c,0xf600400b}, +{0x70,0xf800400c}, +{0x74,0x8238001c}, +{0x78,0x8338601f}, +{0x7c,0xba38001b}, +{0xf0,0x7f}, +{0x00,0xb80f0001}, +{0x04,0xc2024000}, +{0x08,0xbb3f601f}, +{0x0c,0x8200401c}, +{0x10,0xb60ec01d}, +{0x14,0x8200401b}, +{0x18,0x9a036001}, +{0x1c,0xc2224000}, +{0x20,0xb2066001}, +{0x24,0x80a6400a}, +{0x28,0x0abfffd8}, +{0x2c,0x03000019}, +{0x30,0x37000017}, +{0x34,0x8216e380}, +{0x38,0xb616e384}, +{0x3c,0xf806c000}, +{0x40,0xc2004000}, +{0x44,0x82070001}, +{0x48,0x9938601f}, +{0x4c,0x81832000}, +{0x50,0x01000000}, +{0x54,0x01000000}, +{0x58,0x01000000}, +{0x5c,0x8278400d}, +{0x60,0xbb30601f}, +{0x64,0x8200401d}, +{0x68,0x993f201f}, +{0x6c,0x81832000}, +{0x70,0x01000000}, +{0x74,0x01000000}, +{0x78,0x01000000}, +{0x7c,0xb87f000d}, +{0xf0,0x80}, +{0x00,0x83386001}, +{0x04,0xf826c000}, +{0x08,0xc22026e0}, +{0x0c,0x81c7e008}, +{0x10,0x81e80000}, +{0x14,0x9de3bf98}, +{0x18,0x03000017}, +{0x1c,0x82106324}, +{0x20,0xc2004000}, +{0x24,0x80a06001}, +{0x28,0x0280005a}, +{0x2c,0x01000000}, +{0x30,0xc2002514}, +{0x34,0x80a06000}, +{0x38,0x12800056}, +{0x3c,0x01000000}, +{0x40,0xde002200}, +{0x44,0x80a3e000}, +{0x48,0x1280000a}, +{0x4c,0x03000019}, +{0x50,0xc2002548}, +{0x54,0x82087ffb}, +{0x58,0xc2202548}, +{0x5c,0x033fc180}, +{0x60,0x8210602c}, +{0x64,0xc0204000}, +{0x68,0x1080004a}, +{0x6c,0xc02026e8}, +{0x70,0xc0202504}, +{0x74,0x9a106328}, +{0x78,0xb4102000}, +{0x7c,0x10800011}, +{0xf0,0x81}, +{0x00,0xf0102214}, +{0x04,0xba00400d}, +{0x08,0xf2102216}, +{0x0c,0xb6102001}, +{0x10,0xc2074000}, +{0x14,0xba076004}, +{0x18,0x80a04019}, +{0x1c,0x04800005}, +{0x20,0xb8204019}, +{0x24,0xc2002504}, +{0x28,0x8200401c}, +{0x2c,0xc2202504}, +{0x30,0xb686ffff}, +{0x34,0x3cbffff8}, +{0x38,0xc2074000}, +{0x3c,0xb406a001}, +{0x40,0x80a62000}, +{0x44,0x32800003}, +{0x48,0x80a68018}, +{0x4c,0x80a6800f}, +{0x50,0x38800007}, +{0x54,0xfa10221a}, +{0x58,0xc2002300}, +{0x5c,0x80a68001}, +{0x60,0x08bfffe9}, +{0x64,0x832ea003}, +{0x68,0xfa10221a}, +{0x6c,0xc2002504}, +{0x70,0x80a0401d}, +{0x74,0x34800009}, +{0x78,0xc2002548}, +{0x7c,0xc2102218}, +{0xf0,0x82}, +{0x00,0x80a06000}, +{0x04,0x2280000a}, +{0x08,0xc2002548}, +{0x0c,0x80a06000}, +{0x10,0x12800007}, +{0x14,0xc2002548}, +{0x18,0x80886008}, +{0x1c,0x22800008}, +{0x20,0xc20026e8}, +{0x24,0x10800008}, +{0x28,0xc02026e8}, +{0x2c,0x80886008}, +{0x30,0x22800005}, +{0x34,0xc02026e8}, +{0x38,0xc20026e8}, +{0x3c,0x82006001}, +{0x40,0xc22026e8}, +{0x44,0xfa0026e8}, +{0x48,0xc2002290}, +{0x4c,0x80a74001}, +{0x50,0x0880000b}, +{0x54,0xfa002548}, +{0x58,0x83376003}, +{0x5c,0x82086001}, +{0x60,0x82186001}, +{0x64,0x83286002}, +{0x68,0xba0f7ffb}, +{0x6c,0xba174001}, +{0x70,0xfa202548}, +{0x74,0xc02026e8}, +{0x78,0xfa002548}, +{0x7c,0xbb376002}, +{0xf0,0x83}, +{0x00,0x033fc180}, +{0x04,0xba0f6001}, +{0x08,0x8210602c}, +{0x0c,0xfa204000}, +{0x10,0x81c7e008}, +{0x14,0x81e80000}, +{0x18,0x9de3bf60}, +{0x1c,0xc25022ba}, +{0x20,0x80a06000}, +{0x24,0x02800076}, +{0x28,0x03000017}, +{0x2c,0x82106324}, +{0x30,0xc2004000}, +{0x34,0x80a06001}, +{0x38,0x02800071}, +{0x3c,0x01000000}, +{0x40,0xc2002514}, +{0x44,0x80a06001}, +{0x48,0x1880006d}, +{0x4c,0xa0102000}, +{0x50,0xa4102000}, +{0x54,0xa32c2002}, +{0x58,0x9a07bff8}, +{0x5c,0x8204400d}, +{0x60,0xc0207fc8}, +{0x64,0x92102000}, +{0x68,0x8207bfe0}, +{0x6c,0x98102005}, +{0x70,0xc0204000}, +{0x74,0x98833fff}, +{0x78,0x1cbffffe}, +{0x7c,0x82006004}, +{0xf0,0x84}, +{0x00,0x03000019}, +{0x04,0x9e106268}, +{0x08,0x82007c00}, +{0x0c,0x90106368}, +{0x10,0x96037fe8}, +{0x14,0x98102000}, +{0x18,0x8204800c}, +{0x1c,0x82186001}, +{0x20,0x9b286002}, +{0x24,0x94004001}, +{0x28,0xc2046ea0}, +{0x2c,0x8338400c}, +{0x30,0x80886001}, +{0x34,0x02800008}, +{0x38,0x98032001}, +{0x3c,0xda034008}, +{0x40,0xc212800f}, +{0x44,0x8220400d}, +{0x48,0xc222c000}, +{0x4c,0x92026001}, +{0x50,0x9602e004}, +{0x54,0x80a32005}, +{0x58,0x04bffff1}, +{0x5c,0x8204800c}, +{0x60,0x7ffff69e}, +{0x64,0x9007bfe0}, +{0x68,0xc25022ba}, +{0x6c,0xd25022b8}, +{0x70,0x96007fff}, +{0x74,0x98100009}, +{0x78,0x80a2400b}, +{0x7c,0x1480000b}, +{0xf0,0x85}, +{0x00,0x94102000}, +{0x04,0x832a6002}, +{0x08,0x8200401e}, +{0x0c,0x9a007fe0}, +{0x10,0xc2034000}, +{0x14,0x98032001}, +{0x18,0x94028001}, +{0x1c,0x80a3000b}, +{0x20,0x04bffffc}, +{0x24,0x9a036004}, +{0x28,0x8222c009}, +{0x2c,0x82006001}, +{0x30,0x9b3aa01f}, +{0x34,0x81836000}, +{0x38,0x01000000}, +{0x3c,0x01000000}, +{0x40,0x01000000}, +{0x44,0x947a8001}, +{0x48,0xc25021ac}, +{0x4c,0x80a28001}, +{0x50,0x26800002}, +{0x54,0x94100001}, +{0x58,0x9e07bff8}, +{0x5c,0x8204400f}, +{0x60,0xa0042001}, +{0x64,0xd4207fc8}, +{0x68,0x80a42006}, +{0x6c,0x04bfffba}, +{0x70,0xa404a006}, +{0x74,0xa0102000}, +{0x78,0xc2002300}, +{0x7c,0x80a40001}, +{0xf0,0x86}, +{0x00,0x1a80001f}, +{0x04,0x03000019}, +{0x08,0x92106328}, +{0x0c,0x030aaaaa}, +{0x10,0x901062ab}, +{0x14,0x94042400}, +{0x18,0x972c2003}, +{0x1c,0x98102001}, +{0x20,0xda0a8000}, +{0x24,0x9b2b6018}, +{0x28,0x833b6018}, +{0x2c,0x9b3b601f}, +{0x30,0x80584008}, +{0x34,0x83400000}, +{0x38,0x8220400d}, +{0x3c,0x83286018}, +{0x40,0x83386016}, +{0x44,0x8200400f}, +{0x48,0xda007fc8}, +{0x4c,0xc202c009}, +{0x50,0x8220400d}, +{0x54,0xc222c009}, +{0x58,0x9602e004}, +{0x5c,0x98833fff}, +{0x60,0x1cbffff0}, +{0x64,0x9402a020}, +{0x68,0xa0042001}, +{0x6c,0xc2002300}, +{0x70,0x80a40001}, +{0x74,0x0abfffe9}, +{0x78,0x94042400}, +{0x7c,0x81c7e008}, +{0xf0,0x87}, +{0x00,0x81e80000}, +{0x04,0x9de3bf98}, +{0x08,0x1b000017}, +{0x0c,0x82102002}, +{0x10,0x9a136388}, +{0x14,0xc2234000}, +{0x18,0xc2002fe0}, +{0x1c,0x9fc04000}, +{0x20,0x01000000}, +{0x24,0x01000000}, +{0x28,0x81c7e008}, +{0x2c,0x81e80000}, +{0x30,0x9de3bf28}, +{0x34,0xb12e2002}, +{0x38,0xc2062720}, +{0x3c,0xa2086fff}, +{0x40,0x7ffff6d9}, +{0x44,0x90100011}, +{0x48,0x9a047ffe}, +{0x4c,0xa0046002}, +{0x50,0x80a34010}, +{0x54,0x14800025}, +{0x58,0x832b6003}, +{0x5c,0x90006004}, +{0x60,0x9407bff8}, +{0x64,0x25000019}, +{0x68,0xc022bfe8}, +{0x6c,0x80a36000}, +{0x70,0x06800019}, +{0x74,0xc022bfb8}, +{0x78,0xc2002300}, +{0x7c,0x80a34001}, +{0xf0,0x88}, +{0x00,0x3a800016}, +{0x04,0x9a036001}, +{0x08,0x9e14a328}, +{0x0c,0x832b6003}, +{0x10,0x9600400f}, +{0x14,0x92102000}, +{0x18,0xd802c000}, +{0x1c,0x80a32000}, +{0x20,0x04800009}, +{0x24,0x9602e004}, +{0x28,0xc202bfe8}, +{0x2c,0x8200400c}, +{0x30,0x80a26001}, +{0x34,0x12800004}, +{0x38,0xc222bfe8}, +{0x3c,0xc202000f}, +{0x40,0xc222bfb8}, +{0x44,0x92026001}, +{0x48,0x80a26001}, +{0x4c,0x24bffff4}, +{0x50,0xd802c000}, +{0x54,0x9a036001}, +{0x58,0x90022008}, +{0x5c,0x80a34010}, +{0x60,0x04bfffe2}, +{0x64,0x9402a004}, +{0x68,0x9a102020}, +{0x6c,0xa8102000}, +{0x70,0xa6102040}, +{0x74,0x80a36020}, +{0x78,0x0480000b}, +{0x7c,0x82102020}, +{0xf0,0x89}, +{0x00,0x82102060}, +{0x04,0x8220400d}, +{0x08,0x9a037fe0}, +{0x0c,0xc227bfcc}, +{0x10,0xda27bfd8}, +{0x14,0xc027bfc8}, +{0x18,0xe627bfd0}, +{0x1c,0x10800009}, +{0x20,0xe627bfd4}, +{0x24,0x8220400d}, +{0x28,0x9a036020}, +{0x2c,0xc227bfc8}, +{0x30,0xda27bfd4}, +{0x34,0xe627bfcc}, +{0x38,0xe627bfd0}, +{0x3c,0xc027bfd8}, +{0x40,0x90102000}, +{0x44,0xa4102000}, +{0x48,0xac102000}, +{0x4c,0xaa102000}, +{0x50,0x92102000}, +{0x54,0xae07bff8}, +{0x58,0xa12a6002}, +{0x5c,0x82040017}, +{0x60,0xd6007fd0}, +{0x64,0xd8007fe8}, +{0x68,0x985b000b}, +{0x6c,0x833b201f}, +{0x70,0x8330601a}, +{0x74,0x98030001}, +{0x78,0x9b2a6007}, +{0x7c,0x8223400b}, +{0xf0,0x8a}, +{0x00,0x993b2006}, +{0x04,0x9a03400b}, +{0x08,0x82006080}, +{0x0c,0x825b0001}, +{0x10,0x9a5b000d}, +{0x14,0x9730601f}, +{0x18,0x9533601f}, +{0x1c,0x8200400b}, +{0x20,0x9a03400a}, +{0x24,0x83386001}, +{0x28,0x9b3b6001}, +{0x2c,0x80a26002}, +{0x30,0x9405800c}, +{0x34,0x9e05400c}, +{0x38,0x14800004}, +{0x3c,0x96026001}, +{0x40,0x10800003}, +{0x44,0x90020001}, +{0x48,0x9002000d}, +{0x4c,0x82040017}, +{0x50,0xd8007fd0}, +{0x54,0xda007fb8}, +{0x58,0x9a5b400c}, +{0x5c,0x833b601f}, +{0x60,0x8330601a}, +{0x64,0x9a034001}, +{0x68,0x9b3b6006}, +{0x6c,0x9210000b}, +{0x70,0xa404800d}, +{0x74,0x80a2e004}, +{0x78,0xac10000a}, +{0x7c,0x04bfffd7}, +{0xf0,0x8b}, +{0x00,0xaa10000f}, +{0x04,0x9b3a201f}, +{0x08,0x81836000}, +{0x0c,0x01000000}, +{0x10,0x01000000}, +{0x14,0x01000000}, +{0x18,0x827a000a}, +{0x1c,0xa8052001}, +{0x20,0x80a52002}, +{0x24,0x04bfffb4}, +{0x28,0x9a007f80}, +{0x2c,0xa12c6006}, +{0x30,0xa0034010}, +{0x34,0xa32ca00a}, +{0x38,0x833c601f}, +{0x3c,0x81806000}, +{0x40,0x01000000}, +{0x44,0x01000000}, +{0x48,0x01000000}, +{0x4c,0xa27c400f}, +{0x50,0x90100010}, +{0x54,0x7ffff782}, +{0x58,0x92102000}, +{0x5c,0xc2062720}, +{0x60,0x1b000010}, +{0x64,0xa2044008}, +{0x68,0x8088400d}, +{0x6c,0x912c2010}, +{0x70,0x02800005}, +{0x74,0x820c6fff}, +{0x78,0x82020001}, +{0x7c,0x10800003}, +{0xf0,0x8c}, +{0x00,0x8200400d}, +{0x04,0x82020001}, +{0x08,0xc2262720}, +{0x0c,0x81c7e008}, +{0x10,0x81e80000}, +{0x14,0x9de3bf98}, +{0x18,0x7ffff801}, +{0x1c,0x9010205a}, +{0x20,0xc2002548}, +{0x24,0x9a087fbf}, +{0x28,0xc2002514}, +{0x2c,0x80a06000}, +{0x30,0x02800004}, +{0x34,0xda202548}, +{0x38,0x82136040}, +{0x3c,0xc2202548}, +{0x40,0xc20022d4}, +{0x44,0x80886200}, +{0x48,0x22800007}, +{0x4c,0xc2002514}, +{0x50,0xc20026a0}, +{0x54,0x80886400}, +{0x58,0x22800002}, +{0x5c,0xc0202514}, +{0x60,0xc2002514}, +{0x64,0xb0102000}, +{0x68,0x80a60001}, +{0x6c,0xc2202520}, +{0x70,0xa0102000}, +{0x74,0x1a800019}, +{0x78,0xa32e2002}, +{0x7c,0xc2046720}, +{0xf0,0x8d}, +{0x00,0x8330600d}, +{0x04,0x80886001}, +{0x08,0x12800010}, +{0x0c,0x90100018}, +{0x10,0x7fffff48}, +{0x14,0x01000000}, +{0x18,0xc2002fec}, +{0x1c,0x80a06000}, +{0x20,0x02800004}, +{0x24,0x90100018}, +{0x28,0x9fc04000}, +{0x2c,0x01000000}, +{0x30,0xc2046720}, +{0x34,0x80a06000}, +{0x38,0x02800004}, +{0x3c,0x9b2c2002}, +{0x40,0xa0042001}, +{0x44,0xc2236720}, +{0x48,0xb0062001}, +{0x4c,0xc2002514}, +{0x50,0x10bfffe9}, +{0x54,0x80a60001}, +{0x58,0x03000017}, +{0x5c,0x8210631c}, +{0x60,0xc2004000}, +{0x64,0x80a06002}, +{0x68,0x12800016}, +{0x6c,0xe0202514}, +{0x70,0x80a42001}, +{0x74,0x08800015}, +{0x78,0xb0102000}, +{0x7c,0x80a60010}, +{0xf0,0x8e}, +{0x00,0x1a80000e}, +{0x04,0x96100010}, +{0x08,0x992e2002}, +{0x0c,0xda132730}, +{0x10,0xc2102730}, +{0x14,0x80a34001}, +{0x18,0x08800005}, +{0x1c,0xb0062001}, +{0x20,0xda302730}, +{0x24,0xc2032720}, +{0x28,0xc2202720}, +{0x2c,0x80a6000b}, +{0x30,0x0abffff7}, +{0x34,0x992e2002}, +{0x38,0x82102001}, +{0x3c,0xc2202514}, +{0x40,0x7ffff6b5}, +{0x44,0x81e80000}, +{0x48,0x01000000}, +{0x4c,0x81c7e008}, +{0x50,0x81e80000}, +{0x54,0xc2102548}, +{0x58,0x80886001}, +{0x5c,0xc020255c}, +{0x60,0x02800007}, +{0x64,0x92102000}, +{0x68,0xc20023c8}, +{0x6c,0x8330600d}, +{0x70,0x80886001}, +{0x74,0x02800025}, +{0x78,0x01000000}, +{0x7c,0xd0002304}, +{0xf0,0x8f}, +{0x00,0x80a24008}, +{0x04,0x1a800010}, +{0x08,0x96102000}, +{0x0c,0x03000019}, +{0x10,0x941063c0}, +{0x14,0x992ae002}, +{0x18,0xc203000a}, +{0x1c,0xc203000a}, +{0x20,0x80a04009}, +{0x24,0x24800005}, +{0x28,0x9602e001}, +{0x2c,0xd203000a}, +{0x30,0x9a10000b}, +{0x34,0x9602e001}, +{0x38,0x80a2c008}, +{0x3c,0x0abffff7}, +{0x40,0x992ae002}, +{0x44,0x9b2b6008}, +{0x48,0xc2002288}, +{0x4c,0x80a24001}, +{0x50,0x0680000e}, +{0x54,0x9a036020}, +{0x58,0x98102001}, +{0x5c,0xc2002704}, +{0x60,0x80a06000}, +{0x64,0x12800009}, +{0x68,0xd820255c}, +{0x6c,0xc2002514}, +{0x70,0x80a06000}, +{0x74,0x12800005}, +{0x78,0x0303ffc4}, +{0x7c,0x82034001}, +{0xf0,0x90}, +{0x00,0xc2202720}, +{0x04,0xd8202514}, +{0x08,0x81c3e008}, +{0x0c,0x01000000}, +{0x10,0x9de3bf98}, +{0x14,0x7ffff66a}, +{0x18,0x01000000}, +{0x1c,0xc208254d}, +{0x20,0x80a06000}, +{0x24,0x02800019}, +{0x28,0x033fc180}, +{0x2c,0xc0204000}, +{0x30,0xb0102002}, +{0x34,0x7ffff89c}, +{0x38,0x90102001}, +{0x3c,0x11000099}, +{0x40,0x7ffff516}, +{0x44,0x9012233c}, +{0x48,0xb0863fff}, +{0x4c,0x1cbffffa}, +{0x50,0x01000000}, +{0x54,0xc210254c}, +{0x58,0x80886001}, +{0x5c,0x32800002}, +{0x60,0xc020250c}, +{0x64,0x7ffff342}, +{0x68,0x90102015}, +{0x6c,0xda102548}, +{0x70,0x82102001}, +{0x74,0x808b6001}, +{0x78,0x12800004}, +{0x7c,0xc2202584}, +{0xf0,0x91}, +{0x00,0x7ffff402}, +{0x04,0x91e82001}, +{0x08,0x01000000}, +{0x0c,0x81c7e008}, +{0x10,0x81e80000}, +{0x14,0x9de3bf88}, +{0x18,0x03000017}, +{0x1c,0x82106324}, +{0x20,0xc2004000}, +{0x24,0x80a06001}, +{0x28,0x02800037}, +{0x2c,0x01000000}, +{0x30,0xc208254e}, +{0x34,0x80a00001}, +{0x38,0xda102548}, +{0x3c,0x82602000}, +{0x40,0x9a0b6001}, +{0x44,0x80a0000d}, +{0x48,0x82087ffe}, +{0x4c,0x9a403fff}, +{0x50,0x82006003}, +{0x54,0x8208400d}, +{0x58,0xda086314}, +{0x5c,0xc20026e4}, +{0x60,0x80a0400d}, +{0x64,0x06800028}, +{0x68,0x80a36000}, +{0x6c,0x02800026}, +{0x70,0x01000000}, +{0x74,0xda00254c}, +{0x78,0x83336018}, +{0x7c,0x80886001}, +{0xf0,0x92}, +{0x00,0x12800007}, +{0x04,0x03004000}, +{0x08,0xc20026f4}, +{0x0c,0x80a06000}, +{0x10,0x22800008}, +{0x14,0xc200255c}, +{0x18,0x03004000}, +{0x1c,0x822b4001}, +{0x20,0xc220254c}, +{0x24,0xc027bfec}, +{0x28,0x10800009}, +{0x2c,0xc027bff0}, +{0x30,0x80a06000}, +{0x34,0x12800014}, +{0x38,0x01000000}, +{0x3c,0xc208221c}, +{0x40,0xc227bfec}, +{0x44,0xc208221d}, +{0x48,0xc227bff0}, +{0x4c,0xa0102000}, +{0x50,0xc2002304}, +{0x54,0x80a40001}, +{0x58,0x1a80000b}, +{0x5c,0x01000000}, +{0x60,0xc24c2380}, +{0x64,0xc227bfe8}, +{0x68,0x7ffff7b6}, +{0x6c,0x9007bfe8}, +{0x70,0xa0042001}, +{0x74,0xc2002304}, +{0x78,0x80a40001}, +{0x7c,0x2abffffa}, +{0xf0,0x93}, +{0x00,0xc24c2380}, +{0x04,0x81c7e008}, +{0x08,0x81e80000}, +{0x0c,0x9de3bf78}, +{0x10,0x03000017}, +{0x14,0x82106324}, +{0x18,0xc2004000}, +{0x1c,0x80a06000}, +{0x20,0x12800093}, +{0x24,0xc208254e}, +{0x28,0x80a00001}, +{0x2c,0x82602000}, +{0x30,0xa0087ffe}, +{0x34,0xd8002548}, +{0x38,0x83332010}, +{0x3c,0x80886001}, +{0x40,0x0280000c}, +{0x44,0xa0042003}, +{0x48,0x83332011}, +{0x4c,0x80886001}, +{0x50,0x02800030}, +{0x54,0xa0102000}, +{0x58,0xc2002558}, +{0x5c,0x80a06001}, +{0x60,0x28800081}, +{0x64,0xc02026e4}, +{0x68,0x1080002b}, +{0x6c,0xc20c2314}, +{0x70,0x033fc200}, +{0x74,0x82106030}, +{0x78,0xda004000}, +{0x7c,0xc2002570}, +{0xf0,0x94}, +{0x00,0x80a34001}, +{0x04,0x32800078}, +{0x08,0xc02026e4}, +{0x0c,0x808b2040}, +{0x10,0x3280000f}, +{0x14,0x21000019}, +{0x18,0xc2002200}, +{0x1c,0x80a06000}, +{0x20,0x3280000b}, +{0x24,0x21000019}, +{0x28,0xc200255c}, +{0x2c,0x80a06001}, +{0x30,0x22800007}, +{0x34,0x21000019}, +{0x38,0xc20026f8}, +{0x3c,0x80a06000}, +{0x40,0x22800015}, +{0x44,0xc20c2314}, +{0x48,0x21000019}, +{0x4c,0x92142268}, +{0x50,0x94102018}, +{0x54,0x7ffff59d}, +{0x58,0x90142088}, +{0x5c,0x92142268}, +{0x60,0x90142028}, +{0x64,0x7ffff599}, +{0x68,0x94102018}, +{0x6c,0xda082191}, +{0x70,0x832b6002}, +{0x74,0x8200400d}, +{0x78,0x82004001}, +{0x7c,0x82200001}, +{0xf0,0x95}, +{0x00,0xc22026e4}, +{0x04,0xc02026ec}, +{0x08,0x10800073}, +{0x0c,0xc02026f0}, +{0x10,0xc20c2314}, +{0x14,0x80a06000}, +{0x18,0x22800053}, +{0x1c,0xc02026e4}, +{0x20,0xc20c234c}, +{0x24,0xc227bfec}, +{0x28,0xc20c230c}, +{0x2c,0xc227bff0}, +{0x30,0xda0c2314}, +{0x34,0xc20026e4}, +{0x38,0x80a0400d}, +{0x3c,0x06800066}, +{0x40,0x1b0000c0}, +{0x44,0xc2002548}, +{0x48,0x8208400d}, +{0x4c,0x80a0400d}, +{0x50,0x3280000f}, +{0x54,0xda082191}, +{0x58,0xda082169}, +{0x5c,0xc2002710}, +{0x60,0x80a0400d}, +{0x64,0x2680000a}, +{0x68,0xda082191}, +{0x6c,0xc200270c}, +{0x70,0x82006001}, +{0x74,0xda082168}, +{0x78,0x80a0400d}, +{0x7c,0x06800039}, +{0xf0,0x96}, +{0x00,0xc220270c}, +{0x04,0xc020270c}, +{0x08,0xda082191}, +{0x0c,0xc20026ec}, +{0x10,0x80a0400d}, +{0x14,0x2680000d}, +{0x18,0xd8002548}, +{0x1c,0x21000019}, +{0x20,0x92142088}, +{0x24,0x94102018}, +{0x28,0x7ffff568}, +{0x2c,0x90142268}, +{0x30,0x92142028}, +{0x34,0x90142088}, +{0x38,0x7ffff564}, +{0x3c,0x94102018}, +{0x40,0xc02026ec}, +{0x44,0xd8002548}, +{0x48,0x030000c0}, +{0x4c,0x820b0001}, +{0x50,0x1b000040}, +{0x54,0x80a0400d}, +{0x58,0x32800010}, +{0x5c,0xc2082191}, +{0x60,0xc210218e}, +{0x64,0xda002660}, +{0x68,0x80a34001}, +{0x6c,0x14800005}, +{0x70,0x03000080}, +{0x74,0x82036001}, +{0x78,0x10800005}, +{0x7c,0xc2202660}, +{0xf0,0x97}, +{0x00,0x82130001}, +{0x04,0xc2202548}, +{0x08,0xc0202660}, +{0x0c,0xc027bfec}, +{0x10,0xc027bff0}, +{0x14,0xc2082191}, +{0x18,0xda0026f0}, +{0x1c,0x80a34001}, +{0x20,0x0680000f}, +{0x24,0x82036001}, +{0x28,0xa0102000}, +{0x2c,0xe027bfe8}, +{0x30,0x7ffff724}, +{0x34,0x9007bfe8}, +{0x38,0xa0042001}, +{0x3c,0x80a4202f}, +{0x40,0x24bffffc}, +{0x44,0xe027bfe8}, +{0x48,0xc20026ec}, +{0x4c,0x82006001}, +{0x50,0xc22026ec}, +{0x54,0x10800020}, +{0x58,0xc02026e4}, +{0x5c,0xc22026f0}, +{0x60,0xc02026e4}, +{0x64,0x1080001c}, +{0x68,0xc02026ec}, +{0x6c,0xc2002548}, +{0x70,0x80886040}, +{0x74,0x12800018}, +{0x78,0x01000000}, +{0x7c,0xc2002200}, +{0xf0,0x98}, +{0x00,0x80a06000}, +{0x04,0x12800014}, +{0x08,0x01000000}, +{0x0c,0xc200255c}, +{0x10,0x80a06001}, +{0x14,0x02800010}, +{0x18,0x01000000}, +{0x1c,0xc20026f8}, +{0x20,0x80a06000}, +{0x24,0x1280000c}, +{0x28,0x82102004}, +{0x2c,0xc227bfe0}, +{0x30,0xc227bfdc}, +{0x34,0xa0102000}, +{0x38,0xe027bfd8}, +{0x3c,0x7ffff701}, +{0x40,0x9007bfd8}, +{0x44,0xa0042001}, +{0x48,0x80a4202f}, +{0x4c,0x24bffffc}, +{0x50,0xe027bfd8}, +{0x54,0x81c7e008}, +{0x58,0x81e80000}, +{0x5c,0x03000017}, +{0x60,0x82106324}, +{0x64,0xc2004000}, +{0x68,0x80a06001}, +{0x6c,0x02800023}, +{0x70,0x01000000}, +{0x74,0xc2102548}, +{0x78,0x80886001}, +{0x7c,0x0280001f}, +{0xf0,0x99}, +{0x00,0x96102000}, +{0x04,0xd4002300}, +{0x08,0x80a2c00a}, +{0x0c,0x1a80001b}, +{0x10,0x992ae003}, +{0x14,0xc2002470}, +{0x18,0xda1023b6}, +{0x1c,0x9a5b4001}, +{0x20,0x833b601f}, +{0x24,0x83306019}, +{0x28,0x9a034001}, +{0x2c,0x03000019}, +{0x30,0x9b3b6007}, +{0x34,0x9a20000d}, +{0x38,0x9010632c}, +{0x3c,0x92106328}, +{0x40,0xc2030009}, +{0x44,0x80a0400d}, +{0x48,0x06800006}, +{0x4c,0x9602e001}, +{0x50,0xc2030008}, +{0x54,0x80a0400d}, +{0x58,0x16800006}, +{0x5c,0x80a2c00a}, +{0x60,0xc2002548}, +{0x64,0x82106040}, +{0x68,0xc2202548}, +{0x6c,0x80a2c00a}, +{0x70,0x0abffff4}, +{0x74,0x992ae003}, +{0x78,0x81c3e008}, +{0x7c,0x01000000}, +{0xf0,0x9a}, +{0x00,0x9de3bf98}, +{0x04,0x03000017}, +{0x08,0x82106324}, +{0x0c,0xc2004000}, +{0x10,0x80a06001}, +{0x14,0x02800066}, +{0x18,0xc0202580}, +{0x1c,0xd8002548}, +{0x20,0x83332010}, +{0x24,0x80886001}, +{0x28,0x02800061}, +{0x2c,0x01000000}, +{0x30,0xc2002204}, +{0x34,0x80a06000}, +{0x38,0x0280005d}, +{0x3c,0x83332011}, +{0x40,0x80886001}, +{0x44,0x32800005}, +{0x48,0xc2002514}, +{0x4c,0xc2002208}, +{0x50,0xc2202558}, +{0x54,0xc2002514}, +{0x58,0x80a06000}, +{0x5c,0x02800006}, +{0x60,0x1b000080}, +{0x64,0xc2002558}, +{0x68,0x80a06000}, +{0x6c,0x12800013}, +{0x70,0x80a0603b}, +{0x74,0x82136040}, +{0x78,0x820b0001}, +{0x7c,0x80a0400d}, +{0xf0,0x9b}, +{0x00,0x32800006}, +{0x04,0xc2002558}, +{0x08,0xc200255c}, +{0x0c,0x80a06000}, +{0x10,0x02800015}, +{0x14,0xc2002558}, +{0x18,0x80a06000}, +{0x1c,0x12800007}, +{0x20,0x80a0603b}, +{0x24,0x033fc200}, +{0x28,0xda00232c}, +{0x2c,0x82106074}, +{0x30,0x1080000a}, +{0x34,0xda204000}, +{0x38,0x08800004}, +{0x3c,0x80a06031}, +{0x40,0x10800005}, +{0x44,0xc2002208}, +{0x48,0x38800005}, +{0x4c,0xc2002558}, +{0x50,0x82102032}, +{0x54,0xc2202558}, +{0x58,0xc2002558}, +{0x5c,0x10800006}, +{0x60,0x82006001}, +{0x64,0x80a06000}, +{0x68,0x2280000a}, +{0x6c,0x033fc0c0}, +{0x70,0x82007fff}, +{0x74,0xc2202558}, +{0x78,0xc2002558}, +{0x7c,0x80a06000}, +{0xf0,0x9c}, +{0x00,0x02800004}, +{0x04,0x033fc0c0}, +{0x08,0x7ffff2a0}, +{0x0c,0x91e82001}, +{0x10,0x82106004}, +{0x14,0xc0204000}, +{0x18,0x7ffff29c}, +{0x1c,0x90102000}, +{0x20,0x01000000}, +{0x24,0x033fc1c0}, +{0x28,0x9a102001}, +{0x2c,0x821060d4}, +{0x30,0xda204000}, +{0x34,0x01000000}, +{0x38,0x193fc040}, +{0x3c,0x8213200c}, +{0x40,0xc0204000}, +{0x44,0x01000000}, +{0x48,0x032c8590}, +{0x4c,0xda002204}, +{0x50,0x821062c9}, +{0x54,0x80534001}, +{0x58,0x9b400000}, +{0x5c,0x9b336004}, +{0x60,0x8203400d}, +{0x64,0x8200400d}, +{0x68,0x83286003}, +{0x6c,0x8200400d}, +{0x70,0x83306004}, +{0x74,0x9a132004}, +{0x78,0xc2234000}, +{0x7c,0x01000000}, +{0xf0,0x9d}, +{0x00,0x82102003}, +{0x04,0x98132008}, +{0x08,0xc2230000}, +{0x0c,0x01000000}, +{0x10,0x01000000}, +{0x14,0x01000000}, +{0x18,0x033fc1c0}, +{0x1c,0x9a102081}, +{0x20,0x821060dc}, +{0x24,0xda204000}, +{0x28,0x01000000}, +{0x2c,0x81c7e008}, +{0x30,0x81e80000}, +{0x34,0x9de3bf98}, +{0x38,0x7ffff41d}, +{0x3c,0x01000000}, +{0x40,0xda002548}, +{0x44,0x808b6040}, +{0x48,0x3280000b}, +{0x4c,0xc2002280}, +{0x50,0xc2002704}, +{0x54,0x80a06000}, +{0x58,0x04800003}, +{0x5c,0x82007fff}, +{0x60,0xc2202704}, +{0x64,0x808b6040}, +{0x68,0x02800005}, +{0x6c,0x8333600e}, +{0x70,0xc2002280}, +{0x74,0xc2202704}, +{0x78,0x8333600e}, +{0x7c,0x80886001}, +{0xf0,0x9e}, +{0x00,0x12800056}, +{0x04,0x98102000}, +{0x08,0xc2002514}, +{0x0c,0x80a30001}, +{0x10,0x1a80000b}, +{0x14,0x033fc180}, +{0x18,0x96106004}, +{0x1c,0x832b2002}, +{0x20,0xda006720}, +{0x24,0xda20400b}, +{0x28,0x98032001}, +{0x2c,0xc2002514}, +{0x30,0x80a30001}, +{0x34,0x0abffffb}, +{0x38,0x832b2002}, +{0x3c,0xda00254c}, +{0x40,0x808b6001}, +{0x44,0x32800008}, +{0x48,0xc208254e}, +{0x4c,0xc2002514}, +{0x50,0x9a136001}, +{0x54,0x82106100}, +{0x58,0xda20254c}, +{0x5c,0xc2202514}, +{0x60,0xc208254e}, +{0x64,0x80a06000}, +{0x68,0x3280000b}, +{0x6c,0xd80023c8}, +{0x70,0xc20023c8}, +{0x74,0x83306016}, +{0x78,0x80886001}, +{0x7c,0x22800006}, +{0xf0,0x9f}, +{0x00,0xd80023c8}, +{0x04,0xc2002514}, +{0x08,0x82106200}, +{0x0c,0xc2202514}, +{0x10,0xd80023c8}, +{0x14,0x8333200c}, +{0x18,0x80886001}, +{0x1c,0x1280000f}, +{0x20,0xc2082517}, +{0x24,0x80a06000}, +{0x28,0x32800007}, +{0x2c,0xda002500}, +{0x30,0xc2002560}, +{0x34,0x80a06000}, +{0x38,0x22800008}, +{0x3c,0xc2082517}, +{0x40,0xda002500}, +{0x44,0xc2002514}, +{0x48,0x9b2b6010}, +{0x4c,0x8210400d}, +{0x50,0xc2202514}, +{0x54,0xc2082517}, +{0x58,0x80a06000}, +{0x5c,0x22800010}, +{0x60,0xc2002574}, +{0x64,0xc2002548}, +{0x68,0x80886800}, +{0x6c,0x02800005}, +{0x70,0x80a32000}, +{0x74,0xc2002514}, +{0x78,0x82106400}, +{0x7c,0xc2202514}, +{0xf0,0xa0}, +{0x00,0x36800007}, +{0x04,0xc2002574}, +{0x08,0xc2002514}, +{0x0c,0x1b000004}, +{0x10,0x8210400d}, +{0x14,0xc2202514}, +{0x18,0xc2002574}, +{0x1c,0x80a06000}, +{0x20,0x2280000c}, +{0x24,0xda002514}, +{0x28,0x82007fff}, +{0x2c,0xda082517}, +{0x30,0x80a36000}, +{0x34,0x02800006}, +{0x38,0xc2202574}, +{0x3c,0xc2002514}, +{0x40,0x1b000008}, +{0x44,0x8210400d}, +{0x48,0xc2202514}, +{0x4c,0xda002514}, +{0x50,0x033fc180}, +{0x54,0xda204000}, +{0x58,0x81c7e008}, +{0x5c,0x81e80000}, +{0x60,0x9de3bf98}, +{0x64,0xda002714}, +{0x68,0x80a36000}, +{0x6c,0x36800015}, +{0x70,0xc2002548}, +{0x74,0x193fc180}, +{0x78,0xda002208}, +{0x7c,0xd208216b}, +{0xf0,0xa1}, +{0x00,0x82102860}, +{0x04,0x96132004}, +{0x08,0xc222c000}, +{0x0c,0xc2002710}, +{0x10,0x94132008}, +{0x14,0xc2228000}, +{0x18,0x0316c020}, +{0x1c,0x82106002}, +{0x20,0xc2230000}, +{0x24,0x9a036001}, +{0x28,0x82102001}, +{0x2c,0xda202558}, +{0x30,0xd2202560}, +{0x34,0xc2202714}, +{0x38,0x10800014}, +{0x3c,0xc0202710}, +{0x40,0x8330600e}, +{0x44,0x80886001}, +{0x48,0x22800011}, +{0x4c,0xd8002548}, +{0x50,0xc2002560}, +{0x54,0x80a06000}, +{0x58,0x2280000d}, +{0x5c,0xd8002548}, +{0x60,0x80a36001}, +{0x64,0x2480000a}, +{0x68,0xd8002548}, +{0x6c,0x832b6010}, +{0x70,0x1b168020}, +{0x74,0x8210400d}, +{0x78,0x1b3fc180}, +{0x7c,0xc2234000}, +{0xf0,0xa2}, +{0x00,0xc2002208}, +{0x04,0xc2202558}, +{0x08,0xd8002548}, +{0x0c,0x8333200e}, +{0x10,0x80886001}, +{0x14,0x22800007}, +{0x18,0xc2102516}, +{0x1c,0xc2002714}, +{0x20,0x80a06000}, +{0x24,0x22800029}, +{0x28,0xda002548}, +{0x2c,0xc2102516}, +{0x30,0x80a06000}, +{0x34,0x02800006}, +{0x38,0x9b332002}, +{0x3c,0x808b2004}, +{0x40,0x02800009}, +{0x44,0x8333200e}, +{0x48,0x9b332002}, +{0x4c,0x83332003}, +{0x50,0x9a0b6001}, +{0x54,0x82086001}, +{0x58,0x80a34001}, +{0x5c,0x0280000b}, +{0x60,0x8333200e}, +{0x64,0x80886001}, +{0x68,0x32800009}, +{0x6c,0xc2002560}, +{0x70,0xc200231c}, +{0x74,0x80a06000}, +{0x78,0x22800008}, +{0x7c,0x82102014}, +{0xf0,0xa3}, +{0x00,0x10800006}, +{0x04,0x82102005}, +{0x08,0xc2002560}, +{0x0c,0x80a06000}, +{0x10,0x02800007}, +{0x14,0x82007fff}, +{0x18,0xc2202560}, +{0x1c,0x7ffff642}, +{0x20,0x90102001}, +{0x24,0x10800009}, +{0x28,0xda002548}, +{0x2c,0x7ffff63e}, +{0x30,0x90102000}, +{0x34,0x033fc180}, +{0x38,0xc0204000}, +{0x3c,0xc0202714}, +{0x40,0xc0202710}, +{0x44,0xda002548}, +{0x48,0x8203400d}, +{0x4c,0x82086008}, +{0x50,0x9a0b7ff7}, +{0x54,0x9a134001}, +{0x58,0x03000010}, +{0x5c,0x822b4001}, +{0x60,0x9b306010}, +{0x64,0x808b6001}, +{0x68,0x12800004}, +{0x6c,0xc2202548}, +{0x70,0x7ffff1a6}, +{0x74,0x91e82001}, +{0x78,0x01000000}, +{0x7c,0x81c7e008}, +{0xf0,0xa4}, +{0x00,0x81e80000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00000000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00000000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00000000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x00000000}, +{0xf0,0xa5}, +{0x00,0x00002133}, +{0x04,0xa5010503}, +{0x08,0xa5000044}, +{0x0c,0x00000000}, +{0x10,0x67616f79}, +{0x14,0x49444449}, +{0x18,0xc9c799e7}, +{0x1c,0xbca78a4f}, +{0x20,0xc40fc64d}, +{0x24,0x99e09a11}, +{0x28,0xcc479d60}, +{0x2c,0x99e1bc47}, +{0x30,0xa8980000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0x00000000}, +{0x68,0x53657020}, +{0x6c,0x31342032}, +{0x70,0x30313700}, +{0x74,0x00000000}, +{0x78,0x31343a35}, +{0x7c,0x343a3134}, +}; + + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Kconfig new file mode 100644 index 000000000..e801fa0ea --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Kconfig @@ -0,0 +1,34 @@ +menuconfig BSP_USING_WDT0 +bool "Using watchdog 0 " +default n +if BSP_USING_WDT0 +config WDT_BUS_NAME_0 + string "watchdog bus 0 name" + default "wdt0" + +config WDT_DRIVER_NAME_0 + string "watchdog driver 0 name" + default "wdt0_drv" + +config WDT_0_DEVICE_NAME_0 + string "watchdog device 0 name" + default "wdt0_dev0" +endif + +menuconfig BSP_USING_WDT1 +bool "Using watchdog 1 " +default n +if BSP_USING_WDT1 +config WDT_BUS_NAME_1 + string "watchdog bus 1 name" + default "wdt1" + +config WDT_DRIVER_NAME_1 + string "watchdog driver 1 name" + default "wdt1_drv" + +config WDT_1_DEVICE_NAME_1 + string "watchdog device 1 name" + default "wdt1_dev1" +endif + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Makefile new file mode 100644 index 000000000..c4842fd3a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Makefile @@ -0,0 +1,6 @@ +SRC_FILES := wdt.c connect_wdt.c + + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/connect_wdt.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/connect_wdt.c new file mode 100644 index 000000000..30ac2630e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/connect_wdt.c @@ -0,0 +1,176 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_wdt.c +* @brief support aiit-riscv64-board watchdog function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include + +static uint32 WdtOpen(void *dev) +{ + NULL_PARAM_CHECK(dev); + + wdt_device_number_t id; + struct WdtHardwareDevice *wdt = (struct WdtHardwareDevice *)dev; + id = *(wdt_device_number_t *)wdt->private_data; + + wdt_init(id, 4095, NONE, NONE); + return EOK; +} + +static uint32 WdtConfigure(void *drv, struct BusConfigureInfo *args) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(args); + + struct WdtDriver *wdt = (struct WdtDriver *)drv; + wdt_device_number_t id = *(wdt_device_number_t *)wdt->private_data; + + switch (args->configure_cmd) + { + case OPER_WDT_SET_TIMEOUT: + if (wdt_init(id, (uint64_t)*(int *)args->private_data, NONE, NONE) == 0) { + return ERROR; + } + break; + case OPER_WDT_KEEPALIVE: + wdt_feed(id); + break; + default: + return ERROR; + } + return EOK; +} + +static const struct WdtDevDone dev_done = +{ + WdtOpen, + NONE, + NONE, + NONE, +}; + +/** + * @description: Watchdog function + * @return success: EOK, failure: other + */ +int StartWatchdog(void) +{ + //add feed watchdog task function + + return EOK; +} + +int HwWdtInit(void) +{ + wdt_device_number_t id; + + x_err_t ret = EOK; + +#ifdef BSP_USING_WDT0 + { + static struct WdtBus wdt0; + + ret = WdtBusInit(&wdt0, WDT_BUS_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog bus init error %d\n", ret); + return ERROR; + } + + static struct WdtDriver drv0; + drv0.configure = WdtConfigure; + id = WDT_DEVICE_0; + drv0.private_data = &id; + + ret = WdtDriverInit(&drv0, WDT_DRIVER_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog driver init error %d\n", ret); + return ERROR; + } + + ret = WdtDriverAttachToBus(WDT_DRIVER_NAME_0, WDT_BUS_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog driver attach error %d\n", ret); + return ERROR; + } + + static struct WdtHardwareDevice dev0; + dev0.dev_done = &dev_done; + dev0.private_data = &id; + + ret = WdtDeviceRegister(&dev0, WDT_0_DEVICE_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + + ret = WdtDeviceAttachToBus(WDT_0_DEVICE_NAME_0, WDT_BUS_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + } +#endif + +#ifdef BSP_USING_WDT1 + { + static struct WdtBus wdt1; + + ret = WdtBusInit(&wdt1, WDT_BUS_NAME_1); + if (ret != EOK) { + KPrintf("Watchdog bus init error %d\n", ret); + return ERROR; + } + + static struct WdtDriver drv1; + drv1.configure = WdtConfigure; + id = WDT_DEVICE_1; + drv1.private_data = &id; + + ret = WdtDriverInit(&drv1, WDT_DRIVER_NAME_1); + if (ret != EOK) { + KPrintf("Watchdog driver init error %d\n", ret); + return ERROR; + } + + ret = WdtDriverAttachToBus(WDT_DRIVER_NAME_1, WDT_BUS_NAME_1); + if (ret != EOK) { + KPrintf("Watchdog driver attach error %d\n", ret); + return ERROR; + } + + static struct WdtHardwareDevice dev1; + dev1.dev_done = &dev_done; + dev1.private_data = &id; + + ret = WdtDeviceRegister(&dev1, WDT_1_DEVICE_NAME_1); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + + ret = WdtDeviceAttachToBus(WDT_1_DEVICE_NAME_1, WDT_BUS_NAME_1); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + } +#endif + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/wdt.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/wdt.c new file mode 100644 index 000000000..b106444a2 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/wdt.c @@ -0,0 +1,125 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed 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. + */ + +/** +* @file wdt.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include +#include + +volatile wdt_t *const wdt[2] = +{ + (volatile wdt_t *)WDT0_BASE_ADDR, + (volatile wdt_t *)WDT1_BASE_ADDR +}; + +static void wdt_enable(wdt_device_number_t id) +{ + wdt[id]->crr = WDT_CRR_MASK; + wdt[id]->cr |= WDT_CR_ENABLE; +} + +static void wdt_disable(wdt_device_number_t id) +{ + wdt[id]->crr = WDT_CRR_MASK; + wdt[id]->cr &= (~WDT_CR_ENABLE); +} + +static void wdt_set_timeout(wdt_device_number_t id, uint8_t timeout) +{ + wdt[id]->torr = WDT_TORR_TOP(timeout); +} + +static void wdt_response_mode(wdt_device_number_t id, uint8_t mode) +{ + wdt[id]->cr &= (~WDT_CR_RMOD_MASK); + wdt[id]->cr |= mode; +} + +static uint64_t wdt_get_pclk(wdt_device_number_t id) +{ + return id ? SysctlClockGetFreq(SYSCTL_CLOCK_WDT1) : SysctlClockGetFreq(SYSCTL_CLOCK_WDT0); +} + +static uint8_t wdt_get_top(wdt_device_number_t id, uint64_t timeout_ms) +{ + uint64_t wdt_clk = wdt_get_pclk(id); + uint64_t ret = (timeout_ms * wdt_clk / 1000) >> 16; + if (ret) + ret = (uint32_t)log2(ret); + if (ret > 0xf) + ret = 0xf; + return (uint8_t)ret; +} + +void wdt_feed(wdt_device_number_t id) +{ + wdt[id]->crr = WDT_CRR_MASK; +} + +void wdt_clear_interrupt(wdt_device_number_t id) +{ + wdt[id]->eoi = wdt[id]->eoi; +} + +void wdt_start(wdt_device_number_t id, uint64_t time_out_ms, plic_irq_callback_t on_irq) +{ + sysctl_reset(id ? SYSCTL_RESET_WDT1 : SYSCTL_RESET_WDT0); + sysctl_clock_set_threshold(id ? SYSCTL_THRESHOLD_WDT1 : SYSCTL_THRESHOLD_WDT0, 0); + sysctl_clock_enable(id ? SYSCTL_CLOCK_WDT1 : SYSCTL_CLOCK_WDT0); + + plic_set_priority(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, 1); + plic_irq_enable(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT); + plic_irq_register(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, on_irq, NULL); + + wdt_response_mode(id, WDT_CR_RMOD_INTERRUPT); + uint8_t m_top = wdt_get_top(id, time_out_ms); + wdt_set_timeout(id, m_top); + wdt_enable(id); +} + +uint32_t wdt_init(wdt_device_number_t id, uint64_t time_out_ms, plic_irq_callback_t on_irq, void *ctx) +{ + sysctl_reset(id ? SYSCTL_RESET_WDT1 : SYSCTL_RESET_WDT0); + sysctl_clock_set_threshold(id ? SYSCTL_THRESHOLD_WDT1 : SYSCTL_THRESHOLD_WDT0, 0); + sysctl_clock_enable(id ? SYSCTL_CLOCK_WDT1 : SYSCTL_CLOCK_WDT0); + + plic_set_priority(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, 1); + plic_irq_enable(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT); + plic_irq_register(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, on_irq, ctx); + + wdt_response_mode(id, WDT_CR_RMOD_INTERRUPT); + uint8_t m_top = wdt_get_top(id, time_out_ms); + wdt_set_timeout(id, m_top); + wdt_enable(id); + return (1UL << (m_top + 16 + 1)) * 1000UL / wdt_get_pclk(id); +} + +void wdt_stop(wdt_device_number_t id) +{ + wdt_disable(id); +} + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/Kconfig index 7d3aadb79..71d3f01cf 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/Kconfig @@ -28,6 +28,12 @@ menu "hc32f4a0 feature" endmenu endmenu + config MOUNT_SDCARD + bool + default n + config MOUNT_USB + bool + default n endmenu menu "Hardware feature" diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c index 741e8d28b..68473e72e 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c @@ -34,6 +34,18 @@ Modification: #include #include +#ifdef BSP_USING_SDIO +#include +#endif + +#ifdef BSP_USING_SPI +#include +#endif + +#ifdef BSP_USING_USB +#include +#endif + extern void entry(void); extern int HwUsartInit(); @@ -46,15 +58,10 @@ void SystemClockConfig(void) stc_clock_xtal_init_t stcXtalInit; stc_clock_pll_init_t stcPLLHInit; - /* PCLK0, HCLK Max 240MHz */ - /* PCLK1, PCLK4 Max 120MHz */ - /* PCLK2, PCLK3 Max 60MHz */ - /* EX BUS Max 120MHz */ - CLK_SetClockDiv(CLK_BUS_CLK_ALL, \ - (CLK_PCLK0_DIV1 | CLK_PCLK1_DIV2 | CLK_PCLK2_DIV4 | \ - CLK_PCLK3_DIV4 | CLK_PCLK4_DIV2 | CLK_EXCLK_DIV2 | \ + CLK_SetClockDiv(CLK_BUS_CLK_ALL, + (CLK_PCLK0_DIV1 | CLK_PCLK1_DIV2 | CLK_PCLK2_DIV4 | + CLK_PCLK3_DIV4 | CLK_PCLK4_DIV2 | CLK_EXCLK_DIV2 | CLK_HCLK_DIV1)); - (void)CLK_XtalStructInit(&stcXtalInit); /* Config Xtal and enable Xtal */ stcXtalInit.u8Mode = CLK_XTAL_MD_OSC; @@ -64,26 +71,37 @@ void SystemClockConfig(void) (void)CLK_XtalInit(&stcXtalInit); (void)CLK_PLLStructInit(&stcPLLHInit); + + stcPLLHInit.u8PLLState = CLK_PLL_ON; + stcPLLHInit.PLLCFGR = 0UL; + stcPLLHInit.PLLCFGR_f.PLLM = 1UL - 1UL; + +#ifdef BSP_USING_USB /* VCO = (8/1)*120 = 960MHz*/ - stcPLLHInit.u8PLLState = CLK_PLL_ON; - stcPLLHInit.PLLCFGR = 0UL; - stcPLLHInit.PLLCFGR_f.PLLM = 1UL - 1UL; - stcPLLHInit.PLLCFGR_f.PLLN = 120UL - 1UL; - stcPLLHInit.PLLCFGR_f.PLLP = 4UL - 1UL; - stcPLLHInit.PLLCFGR_f.PLLQ = 4UL - 1UL; - stcPLLHInit.PLLCFGR_f.PLLR = 4UL - 1UL; + stcPLLHInit.PLLCFGR_f.PLLN = 120UL - 1UL; +#else + /* VCO = (8/1)*100 = 800MHz*/ + stcPLLHInit.PLLCFGR_f.PLLN = 100UL - 1UL; +#endif + stcPLLHInit.PLLCFGR_f.PLLP = 4UL - 1UL; + stcPLLHInit.PLLCFGR_f.PLLQ = 4UL - 1UL; + stcPLLHInit.PLLCFGR_f.PLLR = 4UL - 1UL; stcPLLHInit.PLLCFGR_f.PLLSRC = CLK_PLL_SRC_XTAL; (void)CLK_PLLInit(&stcPLLHInit); +#ifdef BSP_USING_USB /* Highspeed SRAM set to 0 Read/Write wait cycle */ SRAM_SetWaitCycle(SRAM_SRAMH, SRAM_WAIT_CYCLE0, SRAM_WAIT_CYCLE0); - /* SRAM1_2_3_4_backup set to 1 Read/Write wait cycle */ SRAM_SetWaitCycle((SRAM_SRAM123 | SRAM_SRAM4 | SRAM_SRAMB), SRAM_WAIT_CYCLE1, SRAM_WAIT_CYCLE1); - +#else + /* Highspeed SRAM set to 1 Read/Write wait cycle */ + SRAM_SetWaitCycle(SRAM_SRAMH, SRAM_WAIT_CYCLE1, SRAM_WAIT_CYCLE1); + /* SRAM1_2_3_4_backup set to 2 Read/Write wait cycle */ + SRAM_SetWaitCycle((SRAM_SRAM123 | SRAM_SRAM4 | SRAM_SRAMB), SRAM_WAIT_CYCLE2, SRAM_WAIT_CYCLE2); +#endif /* 0-wait @ 40MHz */ - (void)EFM_SetWaitCycle(EFM_WAIT_CYCLE5); - + EFM_SetWaitCycle(EFM_WAIT_CYCLE5); /* 4 cycles for 200 ~ 250MHz */ GPIO_SetReadWaitCycle(GPIO_RD_WAIT4); CLK_SetSysClockSrc(CLK_SYSCLK_SRC_PLL); @@ -98,7 +116,7 @@ void PeripheralClockConfig(void) CLK_SetCANClockSrc(CLK_CAN2, CLK_CANCLK_SYSCLK_DIV6); #endif -#if defined(RT_USING_ADC) +#if defined(BSP_USING_ADC) CLK_SetPeriClockSrc(CLK_PERIPHCLK_PCLK); #endif } @@ -117,12 +135,26 @@ void SysTickConfiguration(void) void SysTick_Handler(void) { + x_base lock = 0; + lock = DISABLE_INTERRUPT(); + TickAndTaskTimesliceUpdate(); + + ENABLE_INTERRUPT(lock); } struct InitSequenceDesc _board_init[] = -{ - { " NONE ",NONE }, +{ +#ifdef BSP_USING_SDIO + { "sdio", HwSdioInit }, +#endif +#ifdef BSP_USING_SPI + { "spi", HwSpiInit }, +#endif +#ifdef BSP_USING_USB + { "usb", HwUsbHostInit }, +#endif + { " NONE ", NONE }, }; void InitBoardHardware() diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.h index 427f446d6..802b79aa0 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.h +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.h @@ -35,11 +35,11 @@ Modification: #include -extern int __bss_end; +extern int __heap_start; extern unsigned int g_service_table_start; extern unsigned int g_service_table_end; -#define MEMORY_START_ADDRESS (&__bss_end) +#define MEMORY_START_ADDRESS (&__heap_start) #define HC32F4_SRAM_SIZE 512 #define MEMORY_END_ADDRESS (0x1FFE0000 + HC32F4_SRAM_SIZE * 1024) diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/link.lds b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/link.lds index 2960ba39f..fdf1b5e73 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/link.lds +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/link.lds @@ -216,20 +216,18 @@ SECTIONS __end__ = .; PROVIDE(end = .); PROVIDE(_end = .); - *(.heap*) - . = ALIGN(8); - __HeapLimit = .; __StackLimit = .; *(.stack*) . = ALIGN(8); __StackTop = .; + + __heap_start = .; } >RAM .ARM.attributes 0 : { *(.ARM.attributes) } PROVIDE(_stack = __StackTop); - PROVIDE(_Min_Heap_Size = __HeapLimit - __HeapBase); PROVIDE(_Min_Stack_Size = __StackTop - __StackLimit); __RamEnd = ORIGIN(RAM) + LENGTH(RAM); diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig index 54cf93d4a..e5462cf8e 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig @@ -5,3 +5,27 @@ menuconfig BSP_USING_UART if BSP_USING_UART source "$BSP_DIR/third_party_driver/usart/Kconfig" endif + +menuconfig BSP_USING_SPI + bool "Using SPI device" + default n + select RESOURCES_SPI + if BSP_USING_SPI + source "$BSP_DIR/third_party_driver/spi/Kconfig" + endif + +menuconfig BSP_USING_SDIO + bool "Using SD CARD device" + default n + select RESOURCES_SDIO + if BSP_USING_SDIO + source "$BSP_DIR/third_party_driver/sdio/Kconfig" + endif + +menuconfig BSP_USING_USB + bool "Using USB device" + default n + select RESOURCES_USB + if BSP_USING_USB + source "$BSP_DIR/third_party_driver/usb/Kconfig" + endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile index 35e5215a4..b075a1a82 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile @@ -4,4 +4,16 @@ ifeq ($(CONFIG_BSP_USING_UART),y) SRC_DIR += usart endif +ifeq ($(CONFIG_BSP_USING_SPI),y) + SRC_DIR += spi +endif + +ifeq ($(CONFIG_BSP_USING_SDIO),y) + SRC_DIR += sdio +endif + +ifeq ($(CONFIG_BSP_USING_USB),y) + SRC_DIR += usb +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/inc/hc32f4xx_conf.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/inc/hc32f4xx_conf.h index a4dfcda0d..52184d4ec 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/inc/hc32f4xx_conf.h +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/inc/hc32f4xx_conf.h @@ -101,7 +101,7 @@ extern "C" #define LL_TMRA_ENABLE (DDL_ON) #define LL_TRNG_ENABLE (DDL_ON) #define LL_USART_ENABLE (DDL_ON) -#define LL_USB_ENABLE (DDL_OFF) +#define LL_USB_ENABLE (DDL_ON) #define LL_VREF_ENABLE (DDL_OFF) #define LL_WDT_ENABLE (DDL_ON) diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile index 223086b6b..9a62fee3e 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile @@ -4,4 +4,16 @@ ifeq ($(CONFIG_BSP_USING_UART),y) SRC_FILES += hc32_ll_usart.c endif +ifeq ($(CONFIG_BSP_USING_SDIO),y) + SRC_FILES += hc32_ll_sdioc.c +endif + +ifeq ($(CONFIG_BSP_USING_SPI),y) + SRC_FILES += hc32_ll_spi.c +endif + +ifeq ($(CONFIG_BSP_USING_USB),y) + SRC_FILES += hc32_ll_usb.c +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_sdio.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_sdio.h new file mode 100644 index 000000000..38c72db94 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_sdio.h @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_sdio.h +* @brief define hc32f4a0-board sdio function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-03-15 +*/ + +#ifndef CONNECT_SDIO_H +#define CONNECT_SDIO_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SD_CARD_STACK_SIZE 2048 + +int HwSdioInit(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_spi.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_spi.h new file mode 100644 index 000000000..08489b93b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_spi.h @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_spi.h +* @brief define hc32f4a0-board spi function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef CONNECT_SPI_H +#define CONNECT_SPI_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwSpiInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_spi_lora.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_spi_lora.h new file mode 100644 index 000000000..d696ccf4b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_spi_lora.h @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_spi_lora.h +* @brief define spi lora dev function and struct using bus driver framework +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-31 +*/ + +#ifndef CONNECT_SPI_LORA_H +#define CONNECT_SPI_LORA_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//#define SPI_LORA_FREQUENCY 10000000 +#define SPI_LORA_BUFFER_SIZE 256 + +typedef struct SpiLoraDevice *SpiLoraDeviceType; + +struct LoraDevDone +{ + uint32 (*open) (void *dev); + uint32 (*close) (void *dev); + uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param); + uint32 (*read) (void *dev, struct BusBlockReadParam *read_param); +}; + +struct SpiLoraDevice +{ + struct SpiHardwareDevice *spi_dev; + struct SpiHardwareDevice lora_dev; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_usb.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_usb.h new file mode 100644 index 000000000..71c58a043 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_usb.h @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_usb.h +* @brief define hc32f4a0-board usb function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-07 +*/ + +#ifndef CONNECT_USB_H +#define CONNECT_USB_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(FS_VFS) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define USB_HOST_STACK_SIZE 4096 + +#define USB_SINGLE_BLOCK_SIZE 512 + +int HwUsbHostInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_sdio.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_sdio.h new file mode 100644 index 000000000..a94380164 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_sdio.h @@ -0,0 +1,298 @@ +/** + ******************************************************************************* + * @file sdioc/sdioc_sd/source/sd.h + * @brief This file contains all the functions prototypes of the Secure + * Digital(SD) driver library. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/** +* @file hardware_sdio.h +* @brief define hc32f4a0-board sdio function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-18 +*/ + +#ifndef __HARDWARE_SDIO_H__ +#define __HARDWARE_SDIO_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "hc32_ll_sdioc.h" +#include "hc32_ll_dma.h" +#include "hc32_ll_utility.h" + +/** + * @addtogroup HC32F4A0_DDL_Examples + * @{ + */ + +/** + * @addtogroup SDIOC_SD_Card + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ +/** + * @defgroup SD_Global_Types SD Global Types + * @{ + */ + +/** + * @brief SD Card State enumeration structure definition + */ +typedef enum { + SD_CARD_STAT_IDLE = 0x00U, /*!< Card state is idle */ + SD_CARD_STAT_RDY = 0x01U, /*!< Card state is ready */ + SD_CARD_STAT_IDENTIFY = 0x02U, /*!< Card is in identification state */ + SD_CARD_STAT_STANDBY = 0x03U, /*!< Card is in standby state */ + SD_CARD_STAT_TRANS = 0x04U, /*!< Card is in transfer state */ + SD_CARD_STAT_TX_DATA = 0x05U, /*!< Card is sending an operation */ + SD_CARD_STAT_RX_DATA = 0x06U, /*!< Card is receiving operation information */ + SD_CARD_STAT_PGM = 0x07U, /*!< Card is in programming state */ + SD_CARD_STAT_DISCONNECT = 0x08U /*!< Card is disconnected */ +} en_sd_card_state_t; + +/** + * @brief SD Card Information Structure definition + */ +typedef struct { + uint32_t u32CardType; /*!< Specifies the card Type */ + uint32_t u32CardVersion; /*!< Specifies the card version */ + uint32_t u32Class; /*!< Specifies the class of the card class */ + uint32_t u32RelativeCardAddr; /*!< Specifies the Relative Card Address */ + uint32_t u32BlockNum; /*!< Specifies the Card Capacity in blocks */ + uint32_t u32BlockSize; /*!< Specifies one block size in bytes */ + uint32_t u32LogBlockNum; /*!< Specifies the Card logical Capacity in blocks */ + uint32_t u32LogBlockSize; /*!< Specifies logical block size in bytes */ +} stc_sd_card_info_t; + +/** + * @brief SD Card Specific Data(CSD Register) Structure definition + */ +typedef struct { + uint8_t u8CSDStruct; /*!< CSD structure */ + uint8_t u8Reserved1; /*!< Reserved */ + uint8_t u8TAAC; /*!< Data read access time 1 */ + uint8_t u8NSAC; /*!< Data read access time 2 in CLK cycles */ + uint8_t u8MaxBusClkFreq; /*!< Max. bus clock frequency */ + uint16_t u16CardCmdClass; /*!< Card command classes */ + uint8_t u8ReadBlockLen; /*!< Max. read data block length */ + uint8_t u8BlockReadPartial; /*!< Partial blocks for read allowed */ + uint8_t u8WriteBlockMisalign; /*!< Write block misalignment */ + uint8_t u8ReadBlockMisalign; /*!< Read block misalignment */ + uint8_t u8DSRImplement; /*!< DSR implemented */ + uint8_t u8Reserved2; /*!< Reserved */ + uint32_t u32DeviceSize; /*!< Device Size */ + uint8_t u8MaxReadCurrVDDMin; /*!< Max. read current @ VDD min */ + uint8_t u8MaxReadCurrVDDMax; /*!< Max. read current @ VDD max */ + uint8_t u8MaxWriteCurrVDDMin; /*!< Max. write current @ VDD min */ + uint8_t u8MaxWriteCurrVDDMax; /*!< Max. write current @ VDD max */ + uint8_t u8DeviceSizeMul; /*!< Device size multiplier */ + uint8_t u8EraseSingleBlockEn; /*!< Erase single block enable */ + uint8_t u8EraseSectorSize; /*!< Erase sector size */ + uint8_t u8WriteProtectGroupSize; /*!< Write protect group size */ + uint8_t u8WriteProtectGroupEn; /*!< Write protect group enable */ + uint8_t u8Reserved3; /*!< Reserved */ + uint8_t u8WriteSpeedFactor; /*!< Write speed factor */ + uint8_t u8MaxWriteBlockLen; /*!< Max. write data block length */ + uint8_t u8WriteBlockPartial; /*!< Partial blocks for write allowed */ + uint8_t u8Reserved4; /*!< Reserved */ + uint8_t u8FileFormatGroup; /*!< File format group */ + uint8_t u8CopyFlag; /*!< Copy flag (OTP) */ + uint8_t u8PermWriteProtect; /*!< Permanent write protection */ + uint8_t u8TempWriteProtect; /*!< Temporary write protection */ + uint8_t u8FileFormat; /*!< File format */ + uint8_t u8Reserved5; /*!< Reserved */ + uint8_t u8CRCChecksum; /*!< CSD CRC7 checksum */ + uint8_t u8Reserved6; /*!< Always 1 */ +} stc_sd_card_csd_t; + +/** + * @brief SD Card Identification Data(CID Register) Structure definition + */ +typedef struct { + uint8_t u8ManufacturerID; /*!< Manufacturer ID */ + uint16_t u16OemAppID; /*!< OEM/Application ID */ + uint32_t u32ProductName1; /*!< Product Name part1 */ + uint8_t u8ProductName2; /*!< Product Name part2 */ + uint8_t u8ProductRevision; /*!< Product Revision */ + uint32_t u32ProductSN; /*!< Product Serial Number */ + uint8_t u8Reserved1; /*!< Reserved1 */ + uint16_t u16ManufactDate; /*!< Manufacturing Date */ + uint8_t u8CRCChecksum; /*!< CRC7 checksum */ + uint8_t u8Reserved2; /*!< Always 1 */ +} stc_sd_card_cid_t; + +/** + * @brief SD Card Status Structure definition (returned by ACMD13) + */ +typedef struct { + uint8_t u8DataBusWidth; /*!< Shows the currently defined data bus width */ + uint8_t u8SecuredMode; /*!< Card is in secured mode of operation */ + uint16_t u16CardType; /*!< Carries information about card type */ + uint32_t u32ProtectedAreaSize; /*!< Carries information about the capacity of protected area */ + uint8_t u8SpeedClass; /*!< Carries information about the speed class of the card */ + uint8_t u8PerformanceMove; /*!< Carries information about the card's performance move */ + uint8_t u8AllocUnitSize; /*!< Carries information about the card's allocation unit size */ + uint16_t u16EraseSize; /*!< Determines the number of AUs to be erased in one operation */ + uint8_t u8EraseTimeout; /*!< Determines the timeout for any number of AU erase */ + uint8_t u8EraseOffset; /*!< Carries information about the erase offset */ +} stc_sd_card_status_t; + +/** + * @brief SD handle Structure definition + */ +typedef struct { + CM_SDIOC_TypeDef *SDIOCx; /*!< Pointer to SDIOC registers base address */ + stc_sdioc_init_t stcSdiocInit; /*!< SDIOC Initialize structure @ref stc_sdioc_init_t */ + CM_DMA_TypeDef *DMAx; /*!< Pointer to DMA registers base address */ + uint8_t u8DmaTxCh; /*!< Specifies the DMA channel used to send */ + uint8_t u8DmaRxCh; /*!< Specifies the DMA channel used to receive */ + uint8_t *pu8Buffer; /*!< Pointer to SD Tx/Rx transfer Buffer */ + uint32_t u32Len; /*!< SD Tx/Rx Transfer length */ + uint32_t u32Context; /*!< SD transfer context */ + uint32_t u32ErrorCode; /*!< SD Card Error codes */ + stc_sd_card_info_t stcSdCardInfo; /*!< SD Card information */ + uint32_t u32CSD[4]; /*!< SD card specific data table */ + uint32_t u32CID[4]; /*!< SD card identification number table */ + uint32_t u32SCR[2]; /*!< SD Configuration Register table */ +} stc_sd_handle_t; + +/** + * @} + */ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +/** + * @defgroup SD_Global_Macros SD Global Macros + * @{ + */ + +/** + * @defgroup SD_Transfer_Context SD Transfer Context + * @{ + */ +#define SD_CONTEXT_NONE (0x00UL) /*!< None */ +#define SD_CONTEXT_RD_SINGLE_BLOCK (0x01UL) /*!< Read single block operation */ +#define SD_CONTEXT_RD_MULTI_BLOCK (0x02UL) /*!< Read multiple blocks operation */ +#define SD_CONTEXT_WR_SINGLE_BLOCK (0x10UL) /*!< Write single block operation */ +#define SD_CONTEXT_WR_MULTI_BLOCK (0x20UL) /*!< Write multiple blocks operation */ +#define SD_CONTEXT_INT (0x40UL) /*!< Process in Interrupt mode */ +#define SD_CONTEXT_DMA (0x80UL) /*!< Process in DMA mode */ +/** + * @} + */ + +/** + * @defgroup SD_Support_Memory_Card SD Support Memory Card + * @{ + */ +#define SD_CARD_SDSC (0x00UL) +#define SD_CARD_SDHC_SDXC (0x01UL) +#define SD_CARD_SECURED (0x03UL) +/** + * @} + */ + +/** + * @defgroup SD_Support_Version SD Support Version + * @{ + */ +#define SD_CARD_V1_X (0x00UL) /*!< SD Card version: 1.x */ +#define SD_CARD_V2_X (0x01UL) /*!< SD Card version: 2.x */ +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +/** + * @addtogroup SD_Global_Functions + * @{ + */ +int32_t SD_DeInit(stc_sd_handle_t *handle); +int32_t SD_Init(stc_sd_handle_t *handle); +int32_t SD_GetCardState(stc_sd_handle_t *handle, en_sd_card_state_t *peCardState); +int32_t SD_GetCardCID(const stc_sd_handle_t *handle, stc_sd_card_cid_t *pstcCardCID); +int32_t SD_GetCardCSD(stc_sd_handle_t *handle, stc_sd_card_csd_t *pstcCardCSD); +int32_t SD_GetCardStatus(stc_sd_handle_t *handle, stc_sd_card_status_t *pstcCardStatus); +int32_t SD_GetCardInfo(stc_sd_handle_t *handle, stc_sd_card_info_t *pstcCardInfo); +int32_t SD_GetErrorCode(const stc_sd_handle_t *handle, uint32_t *pu32ErrorCode); + +/* Callback in non blocking modes */ +void SD_IRQHandler(stc_sd_handle_t *handle); +void SD_TxCompleteCallback(stc_sd_handle_t *handle); +void SD_RxCompleteCallback(stc_sd_handle_t *handle); +void SD_ErrorCallback(stc_sd_handle_t *handle); + +/* Polling Mode */ +int32_t SD_Erase(stc_sd_handle_t *handle, uint32_t u32BlockStartAddr, uint32_t u32BlockEndAddr); +int32_t SD_ReadBlocks(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, + uint8_t *pu8Data, uint32_t u32Timeout); +int32_t SD_WriteBlocks(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, + uint8_t *pu8Data, uint32_t u32Timeout); +/* Interrupt Mode */ +int32_t SD_ReadBlocks_INT(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, uint8_t *pu8Data); +int32_t SD_WriteBlocks_INT(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, uint8_t *pu8Data); +/* DMA Mode */ +int32_t SD_ReadBlocks_DMA(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, uint8_t *pu8Data); +int32_t SD_WriteBlocks_DMA(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, uint8_t *pu8Data); +/* Abort */ +int32_t SD_Abort(stc_sd_handle_t *handle); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SD_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/Kconfig new file mode 100644 index 000000000..05f09c07a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/Kconfig @@ -0,0 +1,24 @@ +if BSP_USING_SDIO + config SDIO_BUS_NAME + string "sdio bus name" + default "sdio" + + config SDIO_DRIVER_NAME + string "sdio driver name" + default "sdio_drv" + + config SDIO_DEVICE_NAME + string "sdio device name" + default "sdio_dev" + + config MOUNT_SDCARD_FS + bool "mount sd card file system : if y then not support usb-mount-fs" + default y + select MOUNT_SDCARD + + if MOUNT_SDCARD_FS + config MOUNT_SDCARD_FS_TYPE + int "choose file system type : FATFS(0)" + default 0 + endif +endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/Makefile new file mode 100644 index 000000000..f9e28299a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_sdio.c hardware_sdio.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/connect_sdio.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/connect_sdio.c new file mode 100644 index 000000000..32ae8ac8d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/connect_sdio.c @@ -0,0 +1,349 @@ +/** + ******************************************************************************* + * @file sdioc/sdioc_sd/source/main.c + * @brief Main program of SDIOC SD card for the Device Driver Library. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/** +* @file connect_sdio.c +* @brief support sdio function using bus driver framework on hc32f4a0 board +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-18 +*/ + +/************************************************* +File name: connect_sdio.c +Description: support hc32f4a0-board sd card configure and sdio bus register function +Others: +History: +1. Date: 2022-01-24 +Author: AIIT XUOS Lab +Modification: +1. support hc32f4a0-board sdio configure, write and read +2. support hc32f4a0-board sdio bus device and driver register +*************************************************/ + +#include + +/* SD transfer mode */ +#define SD_TRANS_MD_POLLING (0U) +#define SD_TRANS_MD_INT (1U) +#define SD_TRANS_MD_DMA (2U) +/* Populate the following macro with an value, reference "SD transfer mode" */ +#define SD_TRANS_MD (SD_TRANS_MD_POLLING) + +/* SDIOC configuration define */ +#define SDIOC_SD_UINT (CM_SDIOC1) +#define SDIOC_SD_CLK (FCG1_PERIPH_SDIOC1) + +/* CD = PB13 */ +#define SDIOC_CD_PORT (GPIO_PORT_B) +#define SDIOC_CD_PIN (GPIO_PIN_13) +/* CK = PC12 */ +#define SDIOC_CK_PORT (GPIO_PORT_C) +#define SDIOC_CK_PIN (GPIO_PIN_12) +/* CMD = PD02 */ +#define SDIOC_CMD_PORT (GPIO_PORT_D) +#define SDIOC_CMD_PIN (GPIO_PIN_02) +/* D0 = PB07 */ +#define SDIOC_D0_PORT (GPIO_PORT_B) +#define SDIOC_D0_PIN (GPIO_PIN_07) +/* D1 = PA08 */ +#define SDIOC_D1_PORT (GPIO_PORT_A) +#define SDIOC_D1_PIN (GPIO_PIN_08) +/* D2 = PC10 */ +#define SDIOC_D2_PORT (GPIO_PORT_C) +#define SDIOC_D2_PIN (GPIO_PIN_10) +/* D3 = PB05 */ +#define SDIOC_D3_PORT (GPIO_PORT_B) +#define SDIOC_D3_PIN (GPIO_PIN_05) + +static stc_sd_handle_t gSdHandle; +static int sd_lock = -1; + +static void SdCardConfig(void) +{ + /* Enable SDIOC clock */ + FCG_Fcg1PeriphClockCmd(SDIOC_SD_CLK, ENABLE); + + /* SDIOC pins configuration */ + stc_gpio_init_t stcGpioInit; + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_RST; + stcGpioInit.u16PinDir = PIN_DIR_IN; + (void)GPIO_Init(SDIOC_CD_PORT, SDIOC_CD_PIN, &stcGpioInit); + + GPIO_SetFunc(SDIOC_CK_PORT, SDIOC_CK_PIN, GPIO_FUNC_9); + GPIO_SetFunc(SDIOC_CMD_PORT, SDIOC_CMD_PIN, GPIO_FUNC_9); + GPIO_SetFunc(SDIOC_D0_PORT, SDIOC_D0_PIN, GPIO_FUNC_9); + GPIO_SetFunc(SDIOC_D1_PORT, SDIOC_D1_PIN, GPIO_FUNC_9); + GPIO_SetFunc(SDIOC_D2_PORT, SDIOC_D2_PIN, GPIO_FUNC_9); + GPIO_SetFunc(SDIOC_D3_PORT, SDIOC_D3_PIN, GPIO_FUNC_9); + + /* Configure structure initialization */ + gSdHandle.SDIOCx = SDIOC_SD_UINT; + gSdHandle.stcSdiocInit.u32Mode = SDIOC_MD_SD; + gSdHandle.stcSdiocInit.u8CardDetect = SDIOC_CARD_DETECT_CD_PIN_LVL; + gSdHandle.stcSdiocInit.u8SpeedMode = SDIOC_SPEED_MD_HIGH; + gSdHandle.stcSdiocInit.u8BusWidth = SDIOC_BUS_WIDTH_4BIT; + gSdHandle.stcSdiocInit.u16ClockDiv = SDIOC_CLK_DIV2; + gSdHandle.DMAx = NULL; +} + +static uint32 SdioConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + if (configure_info->configure_cmd == OPER_BLK_GETGEOME) { + NULL_PARAM_CHECK(configure_info->private_data); + struct DeviceBlockArrange *args = (struct DeviceBlockArrange *)configure_info->private_data; + + args->size_perbank = gSdHandle.stcSdCardInfo.u32BlockSize; + args->block_size = gSdHandle.stcSdCardInfo.u32BlockSize; + args->bank_num = gSdHandle.stcSdCardInfo.u32BlockNum; + } + + return EOK; +} + +static uint32 SdioOpen(void *dev) +{ + NULL_PARAM_CHECK(dev); + + if(sd_lock >= 0) { + KSemaphoreDelete(sd_lock); + } + sd_lock = KSemaphoreCreate(1); + if (sd_lock < 0){ + return ERROR; + } + + return EOK; +} + +static uint32 SdioClose(void *dev) +{ + NULL_PARAM_CHECK(dev); + + KSemaphoreDelete(sd_lock); + + return EOK; +} + +static uint32 SdioRead(void *dev, struct BusBlockReadParam *read_param) +{ + uint8 ret = EOK; + uint32 sector = read_param->pos; + uint32 block_num = read_param->size; + uint8 *read_buffer = (uint8 *)read_param->buffer; + + KSemaphoreObtain(sd_lock, WAITING_FOREVER); + + if (LL_OK != SD_ReadBlocks(&gSdHandle, sector, block_num, read_buffer, 2000UL)) { + KPrintf("Read data blocks failed.\r\n"); + return 0; + } + + KSemaphoreAbandon(sd_lock); + + return read_param->size; +} + +static uint32 SdioWrite(void *dev, struct BusBlockWriteParam *write_param) +{ + uint8 ret = EOK; + uint32 sector = write_param->pos; + uint32 block_num = write_param->size; + uint8 *write_buffer = (uint8 *)write_param->buffer; + + KSemaphoreObtain(sd_lock, WAITING_FOREVER); + + if (LL_OK != SD_WriteBlocks(&gSdHandle, sector, block_num, write_buffer, 2000U)) { + KPrintf("Write data blocks failed.\r\n"); + return 0; + } + + KSemaphoreAbandon(sd_lock); + + 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 = gSdHandle.stcSdCardInfo.u32BlockSize; + block_param->dev_block.block_size = gSdHandle.stcSdCardInfo.u32BlockSize; + block_param->dev_block.bank_num = gSdHandle.stcSdCardInfo.u32BlockNum; + } + + return EOK; +} + +static struct SdioDevDone dev_done = +{ + SdioOpen, + SdioClose, + SdioWrite, + 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) +{ + static stc_sd_handle_t *sd_handle = &gSdHandle; + + KPrintf("\r\nCard inserted.\r\n"); + + /* Reset and init SDIOC */ + if (LL_OK != SDIOC_SWReset(sd_handle->SDIOCx, SDIOC_SW_RST_ALL)) { + KPrintf("Reset SDIOC failed!\r\n"); + } else if (LL_OK != SD_Init(sd_handle)) { + KPrintf("SD card initialize failed!\r\n"); + } else { + KPrintf("SD card init done!\r\n"); + } + +#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) +{ + en_pin_state_t sd_cd_state = GPIO_ReadInputPins(SDIOC_CD_PORT, SDIOC_CD_PIN); + + if (PIN_RESET == sd_cd_state) { + return 0; + } else { + return 1; + } +} + +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 HwSdioInit(void) +{ + x_err_t ret = EOK; + + static struct SdioBus sdio_bus; + static struct SdioDriver sdio_drv; + static struct SdioHardwareDevice sdio_dev; + + memset(&sdio_bus, 0, sizeof(struct SdioBus)); + memset(&sdio_drv, 0, sizeof(struct SdioDriver)); + memset(&sdio_dev, 0, sizeof(struct SdioHardwareDevice)); + + SdCardConfig(); + + ret = SdioBusInit(&sdio_bus, SDIO_BUS_NAME); + if (ret != EOK) { + KPrintf("Sdio bus init error %d\n", ret); + return ERROR; + } + + ret = SdioDriverInit(&sdio_drv, SDIO_DRIVER_NAME); + if (ret != EOK) { + KPrintf("Sdio driver init error %d\n", ret); + return ERROR; + } + ret = SdioDriverAttachToBus(SDIO_DRIVER_NAME, SDIO_BUS_NAME); + if (ret != EOK) { + KPrintf("Sdio driver attach error %d\n", ret); + return ERROR; + } + + 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); + return ERROR; + } + ret = SdioDeviceAttachToBus(SDIO_DEVICE_NAME, SDIO_BUS_NAME); + if (ret != EOK) { + KPrintf("Sdio device register error %d\n", ret); + return ERROR; + } + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/hardware_sdio.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/hardware_sdio.c new file mode 100644 index 000000000..b56d151fb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/sdio/hardware_sdio.c @@ -0,0 +1,1782 @@ +/** + ******************************************************************************* + * @file sdioc/sdioc_sd/source/sd.c + * @brief This file provides firmware functions to manage the Secure Digital(SD). + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/** +* @file hardware_sdio.c +* @brief support sdio function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-18 +*/ + +/************************************************* +File name: hardware_sdio.c +Description: support hc32f4a0-board sd card configure +Others: +History: +1. Date: 2022-10-18 +Author: AIIT XUOS Lab +Modification: +1. rename as hardware_sdio.c +2. modify #include hardware_sdio.h +*************************************************/ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include + +/** + * @addtogroup HC32F4A0_DDL_Examples + * @{ + */ + +/** + * @addtogroup SDIOC_SD_Card + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ +/** + * @defgroup SD_Local_Macros SD Local Macros + * @{ + */ + +/* Block size is 512 bytes */ +#define SD_CARD_BLOCK_SIZE (512U) + +/* Switch to high speed mode */ +#define SD_SET_FUNC_HIGH_SPEED (0x80FFFF01UL) +#define SD_CMD6_RESULT_FUNC_GRP_BIT1 (0x0002U) + +/** + * @} + */ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +static void SD_DmaTransConfig(const stc_sd_handle_t *handle, uint8_t u8Ch, uint32_t u32SrcAddr, + uint32_t u32DestAddr, uint16_t u16BlockSize, uint16_t u16TransCount); +static int32_t SD_GetSCR(stc_sd_handle_t *handle, uint32_t pu32SCR[]); +static int32_t SD_SetSpeedMode(stc_sd_handle_t *handle); +static int32_t SD_SetBusWidth(stc_sd_handle_t *handle); +static int32_t SD_InitCard(stc_sd_handle_t *handle); +static int32_t SD_PowerCmd(stc_sd_handle_t *handle, en_functional_state_t enNewState); +static int32_t SD_GetCurrCardStatus(stc_sd_handle_t *handle, uint32_t *pu32CardStatus); +static int32_t SD_GetCurrSDStatus(stc_sd_handle_t *handle, uint32_t *pu32SDStatus); +static int32_t SD_ReadWriteFifo(stc_sd_handle_t *handle, const stc_sdioc_data_config_t *pstcDataConfig, + uint8_t pu8Data[], uint32_t u32Timeout); +static int32_t SD_ExtractCardCSD(stc_sd_handle_t *handle); + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @defgroup SD_Global_Functions SD Global Functions + * @{ + */ + +/** + * @brief De-Initialize SD. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @retval int32_t: + * - LL_OK: SD De-Initialize success + * - LL_ERR_INVD_PARAM: handle == NULL + */ +int32_t SD_DeInit(stc_sd_handle_t *handle) +{ + int32_t i32Ret = LL_OK; + + if (NULL == handle) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + /* Set SD power state to off */ + (void)SD_PowerCmd(handle, DISABLE); + handle->u32ErrorCode = SDMMC_ERR_NONE; + } + + return i32Ret; +} + +/** + * @brief Initialize SD. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @retval int32_t: + * - LL_OK: SD Initialize success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + * - LL_ERR_INVD_MD: The Bus clock frequency is too high + */ +int32_t SD_Init(stc_sd_handle_t *handle) +{ + int32_t i32Ret; + stc_sdioc_init_t stcSdInit; + uint16_t u16ClkDiv = 0U; + + if (NULL == handle) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + /* Check the SDIOC clock is over 25Mhz or 50Mhz */ + i32Ret = SDIOC_VerifyClockDiv(SDIOC_MD_SD, handle->stcSdiocInit.u8SpeedMode, handle->stcSdiocInit.u16ClockDiv); + if (LL_OK != i32Ret) { + return LL_ERR_INVD_MD; + } + + /* Default SDIOC configuration for SD card initialization */ + (void)SDIOC_StructInit(&stcSdInit); + i32Ret = SDIOC_GetOptimumClockDiv(SDIOC_OUTPUT_CLK_FREQ_400K, &u16ClkDiv); + if (LL_OK != i32Ret) { + return LL_ERR_INVD_MD; + } + stcSdInit.u16ClockDiv = u16ClkDiv; + stcSdInit.u32Mode = handle->stcSdiocInit.u32Mode; + stcSdInit.u8CardDetect = handle->stcSdiocInit.u8CardDetect; + /* Set Power State to ON */ + SDIOC_PowerCmd(handle->SDIOCx, ENABLE); + /* Initialize SDIOC with default configure */ + (void)SDIOC_Init(handle->SDIOCx, &stcSdInit); + /* Wait for the SDIOC to initialization */ + DDL_DelayMS(2U); + + /* Identify card operating voltage */ + i32Ret = SD_PowerCmd(handle, ENABLE); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Card initialization */ + i32Ret = SD_InitCard(handle); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Get SCR Register */ + i32Ret = SD_GetSCR(handle, handle->u32SCR); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Configure SD Bus width */ + i32Ret = SD_SetBusWidth(handle); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Configure SD High speed mode */ + i32Ret = SD_SetSpeedMode(handle); + + /* Initialize the error code */ + handle->u32ErrorCode = SDMMC_ERR_NONE; + /* Initialize the SD operation */ + handle->u32Context = SD_CONTEXT_NONE; + } + + return i32Ret; +} + +/** + * @brief Get the current sd card state. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [out] peCardState Pointer to a @ref en_sd_card_state_t enumeration + * @retval int32_t: + * - LL_OK: Get sd card state success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or peCardState == NULL or + * An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +int32_t SD_GetCardState(stc_sd_handle_t *handle, en_sd_card_state_t *peCardState) +{ + int32_t i32Ret; + uint32_t u32Response = 0UL; + + if ((NULL == peCardState) || (NULL == handle)) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + i32Ret = SD_GetCurrCardStatus(handle, &u32Response); + *peCardState = (en_sd_card_state_t)(uint32_t)((u32Response >> SDMMC_STATUS_CURR_STATE_POS) & 0x0FU); + } + + return i32Ret; +} + +/** + * @brief Get information of the card which CID register. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [out] pstcCardCID Pointer to a @ref stc_sd_card_cid_t structure + * @retval int32_t: + * - LL_OK: Get sd card CID register success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or pstcCardCID == NULL + */ +int32_t SD_GetCardCID(const stc_sd_handle_t *handle, stc_sd_card_cid_t *pstcCardCID) +{ + int32_t i32Ret = LL_OK; + + if ((NULL == pstcCardCID) || (NULL == handle)) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + pstcCardCID->u8ManufacturerID = (uint8_t)((handle->u32CID[3] & 0xFF000000U) >> 24U); + pstcCardCID->u16OemAppID = (uint16_t)((handle->u32CID[3] & 0x00FFFF00U) >> 8U); + pstcCardCID->u32ProductName1 = (uint32_t)(((handle->u32CID[3] & 0x000000FFU) << 24U) | + ((handle->u32CID[2] & 0xFFFFFF00U) >> 8U)); + pstcCardCID->u8ProductName2 = (uint8_t)(handle->u32CID[2] & 0x000000FFU); + pstcCardCID->u8ProductRevision = (uint8_t)((handle->u32CID[1] & 0xFF000000U) >> 24U); + pstcCardCID->u32ProductSN = (uint32_t)(((handle->u32CID[1] & 0x00FFFFFFU) << 8U) | + ((handle->u32CID[0] & 0xFF000000U) >> 24U)); + pstcCardCID->u8Reserved1 = (uint8_t)((handle->u32CID[0] & 0x00F00000U) >> 20U); + pstcCardCID->u16ManufactDate = (uint16_t)((handle->u32CID[0] & 0x000FFF00U) >> 8U); + pstcCardCID->u8CRCChecksum = (uint8_t)((handle->u32CID[0] & 0x000000FEU) >> 1U); + pstcCardCID->u8Reserved2 = 1U; + } + + return i32Ret; +} + +/** + * @brief Get information of the card which CSD register. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [out] pstcCardCSD Pointer to a @ref stc_sd_card_csd_t structure + * @retval int32_t: + * - LL_OK: Get sd card CSD register success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or pstcCardCSD == NULL + */ +int32_t SD_GetCardCSD(stc_sd_handle_t *handle, stc_sd_card_csd_t *pstcCardCSD) +{ + int32_t i32Ret = LL_OK; + uint32_t u32Temp; + + if ((NULL == pstcCardCSD) || (NULL == handle)) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + u32Temp = (handle->u32CSD[3] & 0xFF000000U) >> 24U; + pstcCardCSD->u8CSDStruct = (uint8_t)((u32Temp & 0xC0U) >> 6U); + pstcCardCSD->u8Reserved1 = 0U; + pstcCardCSD->u8TAAC = (uint8_t)((handle->u32CSD[3] & 0x00FF0000U) >> 16U); + pstcCardCSD->u8NSAC = (uint8_t)((handle->u32CSD[3] & 0x0000FF00U) >> 8U); + pstcCardCSD->u8MaxBusClkFreq = (uint8_t)(handle->u32CSD[3] & 0x000000FFU); + pstcCardCSD->u16CardCmdClass = (uint16_t)((handle->u32CSD[2] & 0xFFF00000U) >> 20U); + pstcCardCSD->u8ReadBlockLen = (uint8_t)((handle->u32CSD[2] & 0x000F0000U) >> 16U); + + u32Temp = (handle->u32CSD[2] & 0x0000F000U) >> 12U; + pstcCardCSD->u8BlockReadPartial = (uint8_t)(u32Temp & 0x08U); + pstcCardCSD->u8WriteBlockMisalign = (uint8_t)(u32Temp & 0x04U); + pstcCardCSD->u8ReadBlockMisalign = (uint8_t)(u32Temp & 0x02U); + pstcCardCSD->u8DSRImplement = (uint8_t)(u32Temp & 0x01U); + pstcCardCSD->u8Reserved2 = 0U; + + if (SD_CARD_SDSC == handle->stcSdCardInfo.u32CardType) { + u32Temp = (uint8_t)((handle->u32CSD[1] & 0xFF000000U) >> 24U); + pstcCardCSD->u32DeviceSize = (uint32_t)(((handle->u32CSD[2] & 0x000003FFU) << 2U) | + ((u32Temp & 0xC0U) >> 6U)); + pstcCardCSD->u8MaxReadCurrVDDMin = (uint8_t)((u32Temp & 0x38U) >> 3U); + pstcCardCSD->u8MaxReadCurrVDDMax = (uint8_t)(u32Temp & 0x07U); + + u32Temp = (uint8_t)((handle->u32CSD[1] & 0x00FF0000U) >> 16U); + pstcCardCSD->u8MaxWriteCurrVDDMin = (uint8_t)((u32Temp & 0xE0U) >> 5U); + pstcCardCSD->u8MaxWriteCurrVDDMax = (uint8_t)((u32Temp & 0x1CU) >> 2U); + pstcCardCSD->u8DeviceSizeMul = (uint8_t)((u32Temp & 0x03U) << 1U); + + u32Temp = (uint8_t)((handle->u32CSD[1] & 0x0000FF00U) >> 8U); + pstcCardCSD->u8DeviceSizeMul |= (uint8_t)((u32Temp & 0x80U) >> 7U); + + handle->stcSdCardInfo.u32BlockNum = (pstcCardCSD->u32DeviceSize + 1U) ; + handle->stcSdCardInfo.u32BlockNum *= (1UL << (pstcCardCSD->u8DeviceSizeMul + 2U)); + handle->stcSdCardInfo.u32BlockSize = 1UL << (pstcCardCSD->u8ReadBlockLen); + if (handle->stcSdCardInfo.u32BlockSize >= 512U) { + handle->stcSdCardInfo.u32LogBlockNum = handle->stcSdCardInfo.u32BlockNum * + (handle->stcSdCardInfo.u32BlockSize / 512U); + } else { + handle->stcSdCardInfo.u32LogBlockNum = (handle->stcSdCardInfo.u32BlockNum / 512U) * + handle->stcSdCardInfo.u32BlockSize; + } + handle->stcSdCardInfo.u32LogBlockSize = 512UL; + } else if (SD_CARD_SDHC_SDXC == handle->stcSdCardInfo.u32CardType) { + pstcCardCSD->u32DeviceSize = (uint32_t)(((handle->u32CSD[2] & 0x0000003FU) << 16U) | + ((handle->u32CSD[1] & 0xFFFF0000U) >> 16U)); + u32Temp = (uint8_t)((handle->u32CSD[1] & 0x0000FF00U) >> 8U); + + handle->stcSdCardInfo.u32BlockNum = (pstcCardCSD->u32DeviceSize + 1U) * 1024U; + handle->stcSdCardInfo.u32BlockSize = 512U; + handle->stcSdCardInfo.u32LogBlockNum = handle->stcSdCardInfo.u32BlockNum; + handle->stcSdCardInfo.u32LogBlockSize = handle->stcSdCardInfo.u32BlockSize; + } else { + handle->u32ErrorCode |= SDMMC_ERR_UNSUPPORT_FEATURE; + return LL_ERR; + } + + pstcCardCSD->u8EraseSingleBlockEn = (uint8_t)((u32Temp & 0x40U) >> 6U); + pstcCardCSD->u8EraseSectorSize = (uint8_t)((u32Temp & 0x3FU) << 1U); + + u32Temp = (uint8_t)(handle->u32CSD[1] & 0x000000FFU); + pstcCardCSD->u8EraseSectorSize |= (uint8_t)((u32Temp & 0x80U) >> 7U); + pstcCardCSD->u8WriteProtectGroupSize = (uint8_t)(u32Temp & 0x7FU); + + u32Temp = (uint8_t)((handle->u32CSD[0] & 0xFF000000U) >> 24U); + pstcCardCSD->u8WriteProtectGroupEn = (uint8_t)((u32Temp & 0x80U) >> 7U); + pstcCardCSD->u8Reserved3 = 0U; + pstcCardCSD->u8WriteSpeedFactor = (uint8_t)((u32Temp & 0x1CU) >> 2U); + pstcCardCSD->u8MaxWriteBlockLen = (uint8_t)((u32Temp & 0x03U) << 2U); + + u32Temp = (uint8_t)((handle->u32CSD[0] & 0x00FF0000U) >> 16U); + pstcCardCSD->u8MaxWriteBlockLen |= (uint8_t)((u32Temp & 0xC0U) >> 6U); + pstcCardCSD->u8WriteBlockPartial = (uint8_t)((u32Temp & 0x20U) >> 5U); + pstcCardCSD->u8Reserved4 = 0U; + + u32Temp = (uint8_t)((handle->u32CSD[0] & 0x0000FF00U) >> 8U); + pstcCardCSD->u8FileFormatGroup = (uint8_t)((u32Temp & 0x80U) >> 7U); + pstcCardCSD->u8CopyFlag = (uint8_t)((u32Temp & 0x40U) >> 6U); + pstcCardCSD->u8PermWriteProtect = (uint8_t)((u32Temp & 0x20U) >> 5U); + pstcCardCSD->u8TempWriteProtect = (uint8_t)((u32Temp & 0x10U) >> 4U); + pstcCardCSD->u8FileFormat = (uint8_t)((u32Temp & 0x0CU) >> 2U); + pstcCardCSD->u8Reserved5 = (uint8_t)(u32Temp & 0x03U); + + u32Temp = (uint8_t)(handle->u32CSD[0] & 0x000000FFU); + pstcCardCSD->u8CRCChecksum = (uint8_t)((u32Temp & 0xFEU) >> 1U); + pstcCardCSD->u8Reserved6 = 1U; + } + + return i32Ret; +} + +/** + * @brief Get the SD card status. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [out] pstcCardStatus Pointer to a @ref stc_sd_card_status_t structure + * @retval int32_t: + * - LL_OK: Get sd card status success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or pstcCardStatus == NULL or + * An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +int32_t SD_GetCardStatus(stc_sd_handle_t *handle, stc_sd_card_status_t *pstcCardStatus) +{ + int32_t i32Ret; + uint32_t u32SDStatus[16]; + + if ((NULL == pstcCardStatus) || (NULL == handle)) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + i32Ret = SD_GetCurrSDStatus(handle, u32SDStatus); + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } else { + pstcCardStatus->u8DataBusWidth = (uint8_t)((u32SDStatus[0] & 0xC0U) >> 6U); + pstcCardStatus->u8SecuredMode = (uint8_t)((u32SDStatus[0] & 0x20U) >> 5U); + pstcCardStatus->u16CardType = (uint16_t)(((u32SDStatus[0] & 0x00FF0000U) >> 8U) | + ((u32SDStatus[0] & 0xFF000000U) >> 24U)); + pstcCardStatus->u32ProtectedAreaSize = (uint32_t)(((u32SDStatus[1] & 0x000000FFU) << 24U) | + ((u32SDStatus[1] & 0x0000FF00U) << 8U) | + ((u32SDStatus[1] & 0x00FF0000U) >> 8U) | + ((u32SDStatus[1] & 0xFF000000U) >> 24U)); + pstcCardStatus->u8SpeedClass = (uint8_t)((u32SDStatus[2] & 0xFFU)); + pstcCardStatus->u8PerformanceMove = (uint8_t)((u32SDStatus[2] & 0xFF00U) >> 8U); + pstcCardStatus->u8AllocUnitSize = (uint8_t)((u32SDStatus[2] & 0xF00000U) >> 20U); + pstcCardStatus->u16EraseSize = (uint16_t)(((u32SDStatus[2] & 0xFF000000U) >> 16U) | + (u32SDStatus[3] & 0xFFU)); + pstcCardStatus->u8EraseTimeout = (uint8_t)((u32SDStatus[3] & 0xFC00U) >> 10U); + pstcCardStatus->u8EraseOffset = (uint8_t)((u32SDStatus[3] & 0x0300U) >> 8U); + } + } + + return i32Ret; +} + +/** + * @brief Get the SD card information. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [out] pstcCardInfo Pointer to a @ref stc_sd_card_info_t structure + * @retval int32_t: + * - LL_OK: Get sd card information success + * - LL_ERR_INVD_PARAM: handle == NULL or pstcCardInfo == NULL + */ +int32_t SD_GetCardInfo(stc_sd_handle_t *handle, stc_sd_card_info_t *pstcCardInfo) +{ + int32_t i32Ret = LL_OK; + + if ((NULL == pstcCardInfo) || (NULL == handle)) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + pstcCardInfo->u32CardType = handle->stcSdCardInfo.u32CardType; + pstcCardInfo->u32CardVersion = handle->stcSdCardInfo.u32CardVersion; + pstcCardInfo->u32Class = handle->stcSdCardInfo.u32Class; + pstcCardInfo->u32RelativeCardAddr = handle->stcSdCardInfo.u32RelativeCardAddr; + pstcCardInfo->u32BlockNum = handle->stcSdCardInfo.u32BlockNum; + pstcCardInfo->u32BlockSize = handle->stcSdCardInfo.u32BlockSize; + pstcCardInfo->u32LogBlockNum = handle->stcSdCardInfo.u32LogBlockNum; + pstcCardInfo->u32LogBlockSize = handle->stcSdCardInfo.u32LogBlockSize; + } + + return i32Ret; +} + +/** + * @brief Get the SD error code. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [out] pu32ErrorCode Pointer to the value of error code + * @retval int32_t: + * - LL_OK: Get sd error code success + * - LL_ERR_INVD_PARAM: handle == NULL or pu32ErrorCode == NULL + */ +int32_t SD_GetErrorCode(const stc_sd_handle_t *handle, uint32_t *pu32ErrorCode) +{ + int32_t i32Ret = LL_OK; + + if ((NULL == pu32ErrorCode) || (NULL == handle)) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + *pu32ErrorCode = handle->u32ErrorCode; + } + + return i32Ret; +} + +/** + * @brief This function handles SD card interrupt request. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @retval None + */ +void SD_IRQHandler(stc_sd_handle_t *handle) +{ + int32_t i32Ret; + en_sd_card_state_t enCardState = SD_CARD_STAT_IDLE; + en_functional_state_t enTransState; + en_functional_state_t enReceiveState; + + enTransState = SDIOC_GetIntEnableState(handle->SDIOCx, SDIOC_INT_BWRSEN); + enReceiveState = SDIOC_GetIntEnableState(handle->SDIOCx, SDIOC_INT_BRRSEN); + /* Check for SDIO interrupt flags */ + if (RESET != SDIOC_GetIntStatus(handle->SDIOCx, SDIOC_INT_FLAG_TC)) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_FLAG_TC); + SDIOC_IntCmd(handle->SDIOCx, (SDIOC_INT_DEBESEN | SDIOC_INT_DCESEN | SDIOC_INT_DTOESEN | + SDIOC_INT_TCSEN | SDIOC_INT_BRRSEN | SDIOC_INT_BWRSEN), DISABLE); + if ((0UL != (handle->u32Context & SD_CONTEXT_INT)) || (0UL != (handle->u32Context & SD_CONTEXT_DMA))) { + if ((0UL != (handle->u32Context & SD_CONTEXT_WR_MULTI_BLOCK)) || + (0UL != (handle->u32Context & SD_CONTEXT_RD_MULTI_BLOCK))) { + /* Send stop transmission command */ + i32Ret = SDMMC_CMD12_StopTrans(handle->SDIOCx, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + SD_ErrorCallback(handle); + } + } + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + if ((0UL != (handle->u32Context & SD_CONTEXT_WR_SINGLE_BLOCK)) || + (0UL != (handle->u32Context & SD_CONTEXT_WR_MULTI_BLOCK))) { + SD_TxCompleteCallback(handle); + } else { + SD_RxCompleteCallback(handle); + } + } + } else if ((RESET != SDIOC_GetHostStatus(handle->SDIOCx, SDIOC_HOST_FLAG_BWE)) && + (DISABLE != enTransState)) { + (void)SDIOC_WriteBuffer(handle->SDIOCx, handle->pu8Buffer, 4UL); + handle->pu8Buffer += 4U; + handle->u32Len -= 4U; + if (0UL == handle->u32Len) { + SDIOC_IntCmd(handle->SDIOCx, SDIOC_INT_BWRSEN, DISABLE); + } + } else if ((RESET != SDIOC_GetHostStatus(handle->SDIOCx, SDIOC_HOST_FLAG_BRE)) && + (DISABLE != enReceiveState)) { + (void)SDIOC_ReadBuffer(handle->SDIOCx, handle->pu8Buffer, 4UL); + handle->pu8Buffer += 4U; + handle->u32Len -= 4U; + if (0UL == handle->u32Len) { + SDIOC_IntCmd(handle->SDIOCx, SDIOC_INT_BRRSEN, DISABLE); + } + } else if (RESET != SDIOC_GetIntStatus(handle->SDIOCx, (SDIOC_INT_DEBESEN | + SDIOC_INT_DCESEN | SDIOC_INT_DTOESEN))) { + /* Set LL_ERR code */ + if (RESET != SDIOC_GetIntStatus(handle->SDIOCx, SDIOC_INT_DEBESEN)) { + handle->u32ErrorCode |= SDMMC_ERR_DATA_STOP_BIT; + } + if (RESET != SDIOC_GetIntStatus(handle->SDIOCx, SDIOC_INT_DCESEN)) { + handle->u32ErrorCode |= SDMMC_ERR_DATA_CRC_FAIL; + } + if (RESET != SDIOC_GetIntStatus(handle->SDIOCx, SDIOC_INT_DTOESEN)) { + handle->u32ErrorCode |= SDMMC_ERR_DATA_TIMEOUT; + } + + /* Clear All flags */ + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + /* Disable all interrupts */ + SDIOC_IntCmd(handle->SDIOCx, (SDIOC_INT_DEBESEN | SDIOC_INT_DCESEN | SDIOC_INT_DTOESEN | + SDIOC_INT_TCSEN | SDIOC_INT_BRRSEN | SDIOC_INT_BWRSEN), DISABLE); + if (0UL != (handle->u32Context & SD_CONTEXT_INT)) { + SD_ErrorCallback(handle); + } else if (0UL != (handle->u32Context & SD_CONTEXT_DMA)) { + if (NULL != handle->DMAx) { + /* Disable the DMA Channel */ + if ((0UL != (handle->u32Context & SD_CONTEXT_WR_SINGLE_BLOCK)) || + (0UL != (handle->u32Context & SD_CONTEXT_WR_MULTI_BLOCK))) { + (void)DMA_ChCmd(handle->DMAx, handle->u8DmaTxCh, DISABLE); + } else { + (void)DMA_ChCmd(handle->DMAx, handle->u8DmaRxCh, DISABLE); + } + /* Stop SD transfer */ + (void)SD_GetCardState(handle, &enCardState); + handle->u32ErrorCode = SDMMC_ERR_NONE; + if ((SD_CARD_STAT_TX_DATA == enCardState) || (SD_CARD_STAT_RX_DATA == enCardState)) { + /* Send stop transmission command */ + (void)SDMMC_CMD12_StopTrans(handle->SDIOCx, &handle->u32ErrorCode); + } + SD_ErrorCallback(handle); + } + } else { + } + } else { + } +} + +/** + * @brief SD Tx completed callbacks + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @retval None + */ +__WEAKDEF void SD_TxCompleteCallback(stc_sd_handle_t *handle) +{ + (void)handle; + /* NOTE: This function SD_TxCpltCallback can be implemented in the user file */ +} + +/** + * @brief SD Rx completed callbacks + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @retval None + */ +__WEAKDEF void SD_RxCompleteCallback(stc_sd_handle_t *handle) +{ + (void)handle; + /* NOTE: This function SD_TxCpltCallback can be implemented in the user file */ +} + +/** + * @brief SD error callbacks + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @retval None + */ +__WEAKDEF void SD_ErrorCallback(stc_sd_handle_t *handle) +{ + (void)handle; + /* NOTE: This function SD_TxCpltCallback can be implemented in the user file */ +} + +/** + * @brief Erases the specified memory area of the given SD card. + * @note This API should be followed by a check on the card state through SD_GetCardState(). + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [in] u32BlockStartAddr Start Block address + * @param [in] u32BlockEndAddr End Block address + * @retval int32_t: + * - LL_OK: Erases the SD card success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +int32_t SD_Erase(stc_sd_handle_t *handle, uint32_t u32BlockStartAddr, uint32_t u32BlockEndAddr) +{ + int32_t i32Ret; + uint32_t u32CardSta = 0UL; + + if ((u32BlockEndAddr < u32BlockStartAddr) || (NULL == handle)) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + if (u32BlockEndAddr > (handle->stcSdCardInfo.u32LogBlockNum)) { + handle->u32ErrorCode |= SDMMC_ERR_ADDR_OUT_OF_RANGE; + return LL_ERR; + } + /* Check if the card command class supports erase command */ + if (0UL == ((handle->stcSdCardInfo.u32Class) & SDMMC_CSD_SUPPORT_CLASS5_ERASE)) { + handle->u32ErrorCode |= SDMMC_ERR_REQ_NOT_APPLICABLE; + return LL_ERR; + } + /* Check the lock status */ + i32Ret = SD_GetCurrCardStatus(handle, &u32CardSta); + if (LL_OK != i32Ret) { + return i32Ret; + } + if (SDMMC_STATUS_CARD_IS_LOCKED == (u32CardSta & SDMMC_STATUS_CARD_IS_LOCKED)) { + handle->u32ErrorCode |= SDMMC_ERR_LOCK_UNLOCK_FAILED; + return LL_ERR; + } + /* Get start and end block for high capacity cards */ + if (SD_CARD_SDHC_SDXC != handle->stcSdCardInfo.u32CardType) { + u32BlockStartAddr *= 512U; + u32BlockEndAddr *= 512U; + } + + /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */ + if (SD_CARD_SECURED != handle->stcSdCardInfo.u32CardType) { + /* Send CMD32 ERASE_WR_BLK_START with argument as addr */ + i32Ret = SDMMC_CMD32_EraseBlockStartAddr(handle->SDIOCx, u32BlockStartAddr, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + /* Send CMD33 ERASE_WR_BLK_END with argument as addr */ + i32Ret = SDMMC_CMD33_EraseBlockEndAddr(handle->SDIOCx, u32BlockEndAddr, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + } + /* Send CMD38 ERASE */ + i32Ret = SDMMC_CMD38_Erase(handle->SDIOCx, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + } + + return i32Ret; +} + +/** + * @brief Reads block(s) from a specified address in a card. + * @note The Data transfer is managed by polling mode. + * @note This API should be followed by a check on the card state through SD_GetCardState(). + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [in] u32BlockAddr Block Address + * @param [in] u16BlockCount Block Count + * @param [out] pu8Data Pointer to the buffer that will contain the received data + * @param [in] u32Timeout Read timeout value + * @retval int32_t: + * - LL_OK: Read block(s) success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or pu8Data == NULL or + * An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +int32_t SD_ReadBlocks(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, + uint8_t *pu8Data, uint32_t u32Timeout) +{ + int32_t i32Ret; + stc_sdioc_data_config_t stcDataCfg; + + if ((NULL == pu8Data) || (NULL == handle)) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + handle->u32ErrorCode = SDMMC_ERR_NONE; + if ((u32BlockAddr + u16BlockCount) > (handle->stcSdCardInfo.u32LogBlockNum)) { + handle->u32ErrorCode |= SDMMC_ERR_ADDR_OUT_OF_RANGE; + return LL_ERR; + } + if (SD_CARD_SDHC_SDXC != handle->stcSdCardInfo.u32CardType) { + u32BlockAddr *= 512U; + } + + /* Set Block Size for Card */ + i32Ret = SDMMC_CMD16_SetBlockLength(handle->SDIOCx, SD_CARD_BLOCK_SIZE, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + /* Configure the SD data transfer */ + stcDataCfg.u16BlockSize = SD_CARD_BLOCK_SIZE; + stcDataCfg.u16BlockCount = u16BlockCount; + stcDataCfg.u16TransDir = SDIOC_TRANS_DIR_TO_HOST; + stcDataCfg.u16AutoCmd12 = SDIOC_AUTO_SEND_CMD12_DISABLE; + stcDataCfg.u16DataTimeout = SDIOC_DATA_TIMEOUT_CLK_2E27; + stcDataCfg.u16TransMode = (u16BlockCount > 1U) ? (uint16_t)SDIOC_TRANS_MD_MULTI : + (uint16_t)SDIOC_TRANS_MD_SINGLE; + (void)SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); + /* Read block(s) in polling mode */ + if (u16BlockCount > 1U) { + handle->u32Context = SD_CONTEXT_RD_MULTI_BLOCK; + /* Read Multi Block command */ + i32Ret = SDMMC_CMD18_ReadMultipleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } else { + handle->u32Context = SD_CONTEXT_RD_SINGLE_BLOCK; + /* Read Single Block command */ + i32Ret = SDMMC_CMD17_ReadSingleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } + + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + /* Get data */ + i32Ret = SD_ReadWriteFifo(handle, &stcDataCfg, (uint8_t *)pu8Data, u32Timeout); + if (LL_OK != i32Ret) { + return i32Ret; + } + } + + return i32Ret; +} + +/** + * @brief Write block(s) to a specified address in a card. + * @note The Data transfer is managed by polling mode. + * @note This API should be followed by a check on the card state through SD_GetCardState(). + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [in] u32BlockAddr Block Address + * @param [in] u16BlockCount Block Count + * @param [in] pu8Data Pointer to the buffer that will contain the data to transmit + * @param [in] u32Timeout Write timeout value + * @retval int32_t: + * - LL_OK: Write block(s) success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or pu8Data == NULL or + * An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +int32_t SD_WriteBlocks(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, + uint8_t *pu8Data, uint32_t u32Timeout) +{ + int32_t i32Ret; + stc_sdioc_data_config_t stcDataCfg; + + if ((NULL == pu8Data) || (NULL == handle)) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + handle->u32ErrorCode = SDMMC_ERR_NONE; + if ((u32BlockAddr + u16BlockCount) > (handle->stcSdCardInfo.u32LogBlockNum)) { + handle->u32ErrorCode |= SDMMC_ERR_ADDR_OUT_OF_RANGE; + return LL_ERR; + } + if (SD_CARD_SDHC_SDXC != handle->stcSdCardInfo.u32CardType) { + u32BlockAddr *= 512U; + } + + /* Set Block Size for Card */ + i32Ret = SDMMC_CMD16_SetBlockLength(handle->SDIOCx, SD_CARD_BLOCK_SIZE, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + /* Configure the SD data transfer */ + stcDataCfg.u16BlockSize = SD_CARD_BLOCK_SIZE; + stcDataCfg.u16BlockCount = u16BlockCount; + stcDataCfg.u16TransDir = SDIOC_TRANS_DIR_TO_CARD; + stcDataCfg.u16AutoCmd12 = SDIOC_AUTO_SEND_CMD12_DISABLE; + stcDataCfg.u16DataTimeout = SDIOC_DATA_TIMEOUT_CLK_2E27; + stcDataCfg.u16TransMode = (u16BlockCount > 1U) ? (uint16_t)SDIOC_TRANS_MD_MULTI : + (uint16_t)SDIOC_TRANS_MD_SINGLE; + (void)SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); + /* Write block(s) in polling mode */ + if (u16BlockCount > 1U) { + handle->u32Context = SD_CONTEXT_WR_MULTI_BLOCK; + /* Write Multi Block command */ + i32Ret = SDMMC_CMD25_WriteMultipleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } else { + handle->u32Context = SD_CONTEXT_WR_SINGLE_BLOCK; + /* Write Single Block command */ + i32Ret = SDMMC_CMD24_WriteSingleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } + + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + /* Get data */ + i32Ret = SD_ReadWriteFifo(handle, &stcDataCfg, (uint8_t *)pu8Data, u32Timeout); + if (LL_OK != i32Ret) { + return i32Ret; + } + } + + return i32Ret; +} + +/** + * @brief Reads block(s) from a specified address in a card. + * @note The Data transfer is managed by interrupt mode. + * @note This API should be followed by a check on the card state through SD_GetCardState(). + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [in] u32BlockAddr Block Address + * @param [in] u16BlockCount Block Count + * @param [out] pu8Data Pointer to the buffer that will contain the received data + * @retval int32_t: + * - LL_OK: Read block(s) success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or pu8Data == NULL or + * An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +int32_t SD_ReadBlocks_INT(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, uint8_t *pu8Data) +{ + int32_t i32Ret; + stc_sdioc_data_config_t stcDataCfg; + + if ((NULL == pu8Data) || (NULL == handle)) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + handle->u32ErrorCode = SDMMC_ERR_NONE; + if ((u32BlockAddr + u16BlockCount) > (handle->stcSdCardInfo.u32LogBlockNum)) { + handle->u32ErrorCode |= SDMMC_ERR_ADDR_OUT_OF_RANGE; + return LL_ERR; + } + if (SD_CARD_SDHC_SDXC != handle->stcSdCardInfo.u32CardType) { + u32BlockAddr *= 512U; + } + + /* Set Block Size for Card */ + i32Ret = SDMMC_CMD16_SetBlockLength(handle->SDIOCx, SD_CARD_BLOCK_SIZE, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + /* Configure interrupt transfer parameters */ + handle->pu8Buffer = pu8Data; + handle->u32Len = (uint32_t)u16BlockCount * SD_CARD_BLOCK_SIZE; + SDIOC_ClearIntStatus(handle->SDIOCx, (SDIOC_INT_FLAG_BWR | SDIOC_INT_FLAG_BRR)); + /* Enable SDIOC interrupt */ + SDIOC_IntCmd(handle->SDIOCx, (SDIOC_INT_DEBESEN | SDIOC_INT_DCESEN | SDIOC_INT_DTOESEN | + SDIOC_INT_TCSEN | SDIOC_INT_BRRSEN), ENABLE); + /* Configure the SD data transfer */ + stcDataCfg.u16BlockSize = SD_CARD_BLOCK_SIZE; + stcDataCfg.u16BlockCount = u16BlockCount; + stcDataCfg.u16TransDir = SDIOC_TRANS_DIR_TO_HOST; + stcDataCfg.u16AutoCmd12 = SDIOC_AUTO_SEND_CMD12_DISABLE; + stcDataCfg.u16DataTimeout = SDIOC_DATA_TIMEOUT_CLK_2E27; + stcDataCfg.u16TransMode = (u16BlockCount > 1U) ? (uint16_t)SDIOC_TRANS_MD_MULTI : + (uint16_t)SDIOC_TRANS_MD_SINGLE; + (void)SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); + /* Read block(s) in interrupt mode */ + if (u16BlockCount > 1U) { + handle->u32Context = SD_CONTEXT_RD_MULTI_BLOCK | SD_CONTEXT_INT; + /* Read Multi Block command */ + i32Ret = SDMMC_CMD18_ReadMultipleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } else { + handle->u32Context = SD_CONTEXT_RD_SINGLE_BLOCK | SD_CONTEXT_INT; + /* Read Single Block command */ + i32Ret = SDMMC_CMD17_ReadSingleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } + + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + } + + return i32Ret; +} + +/** + * @brief Write block(s) to a specified address in a card. + * @note The Data transfer is managed by interrupt mode. + * @note This API should be followed by a check on the card state through SD_GetCardState(). + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [in] u32BlockAddr Block Address + * @param [in] u16BlockCount Block Count + * @param [in] pu8Data Pointer to the buffer that will contain the data to transmit + * @retval int32_t: + * - LL_OK: Write block(s) success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or pu8Data == NULL or + * An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +int32_t SD_WriteBlocks_INT(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, uint8_t *pu8Data) +{ + int32_t i32Ret; + stc_sdioc_data_config_t stcDataCfg; + + if ((NULL == pu8Data) || (NULL == handle)) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + handle->u32ErrorCode = SDMMC_ERR_NONE; + if ((u32BlockAddr + u16BlockCount) > (handle->stcSdCardInfo.u32LogBlockNum)) { + handle->u32ErrorCode |= SDMMC_ERR_ADDR_OUT_OF_RANGE; + return LL_ERR; + } + if (SD_CARD_SDHC_SDXC != handle->stcSdCardInfo.u32CardType) { + u32BlockAddr *= 512U; + } + + /* Set Block Size for Card */ + i32Ret = SDMMC_CMD16_SetBlockLength(handle->SDIOCx, SD_CARD_BLOCK_SIZE, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + /* Configure interrupt transfer parameters */ + handle->pu8Buffer = pu8Data; + handle->u32Len = (uint32_t)u16BlockCount * SD_CARD_BLOCK_SIZE; + SDIOC_ClearIntStatus(handle->SDIOCx, (SDIOC_INT_FLAG_BWR | SDIOC_INT_FLAG_BRR)); + /* Enable SDIOC interrupt */ + SDIOC_IntCmd(handle->SDIOCx, (SDIOC_INT_DEBESEN | SDIOC_INT_DCESEN | SDIOC_INT_DTOESEN | + SDIOC_INT_TCSEN | SDIOC_INT_BWRSEN), ENABLE); + /* Configure the SD data transfer */ + stcDataCfg.u16BlockSize = SD_CARD_BLOCK_SIZE; + stcDataCfg.u16BlockCount = u16BlockCount; + stcDataCfg.u16TransDir = SDIOC_TRANS_DIR_TO_CARD; + stcDataCfg.u16AutoCmd12 = SDIOC_AUTO_SEND_CMD12_DISABLE; + stcDataCfg.u16DataTimeout = SDIOC_DATA_TIMEOUT_CLK_2E27; + stcDataCfg.u16TransMode = (u16BlockCount > 1U) ? (uint16_t)SDIOC_TRANS_MD_MULTI : + (uint16_t)SDIOC_TRANS_MD_SINGLE; + (void)SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); + /* Write block(s) in interrupt mode */ + if (u16BlockCount > 1U) { + handle->u32Context = SD_CONTEXT_WR_MULTI_BLOCK | SD_CONTEXT_INT; + /* Write Multi Block command */ + i32Ret = SDMMC_CMD25_WriteMultipleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } else { + handle->u32Context = SD_CONTEXT_WR_SINGLE_BLOCK | SD_CONTEXT_INT; + /* Write Single Block command */ + i32Ret = SDMMC_CMD24_WriteSingleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } + + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + } + + return i32Ret; +} + +/** + * @brief Reads block(s) from a specified address in a card. + * @note The Data transfer is managed by DMA mode. + * @note This API should be followed by a check on the card state through SD_GetCardState(). + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [in] u32BlockAddr Block Address + * @param [in] u16BlockCount Block Count + * @param [out] pu8Data Pointer to the buffer that will contain the received data + * @retval int32_t: + * - LL_OK: Read block(s) success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or pu8Data == NULL or NULL == handle->DMAx or + * An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +int32_t SD_ReadBlocks_DMA(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, uint8_t *pu8Data) +{ + int32_t i32Ret; + stc_sdioc_data_config_t stcDataCfg; + + if ((NULL == pu8Data) || (NULL == handle) || (NULL == handle->DMAx) || (0U != ((uint32_t)pu8Data % 4U))) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + handle->u32ErrorCode = SDMMC_ERR_NONE; + if ((u32BlockAddr + u16BlockCount) > (handle->stcSdCardInfo.u32LogBlockNum)) { + handle->u32ErrorCode |= SDMMC_ERR_ADDR_OUT_OF_RANGE; + return LL_ERR; + } + if (SD_CARD_SDHC_SDXC != handle->stcSdCardInfo.u32CardType) { + u32BlockAddr *= 512U; + } + + /* Set Block Size for Card */ + i32Ret = SDMMC_CMD16_SetBlockLength(handle->SDIOCx, SD_CARD_BLOCK_SIZE, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + /* Enable SDIOC transfer complete and errors interrupt */ + SDIOC_IntCmd(handle->SDIOCx, (SDIOC_INT_TCSEN | SDIOC_INT_DEBESEN | + SDIOC_INT_DCESEN | SDIOC_INT_DTOESEN), ENABLE); + /* Configure DMA parameters */ + SD_DmaTransConfig(handle, handle->u8DmaRxCh, (uint32_t)(&handle->SDIOCx->BUF0), (uint32_t)pu8Data, + (SD_CARD_BLOCK_SIZE / 4U), u16BlockCount); + /* Enable the DMA Channel */ + (void)DMA_ChCmd(handle->DMAx, handle->u8DmaRxCh, ENABLE); + /* Configure the SD data transfer */ + stcDataCfg.u16BlockSize = SD_CARD_BLOCK_SIZE; + stcDataCfg.u16BlockCount = u16BlockCount; + stcDataCfg.u16TransDir = SDIOC_TRANS_DIR_TO_HOST; + stcDataCfg.u16AutoCmd12 = SDIOC_AUTO_SEND_CMD12_DISABLE; + stcDataCfg.u16DataTimeout = SDIOC_DATA_TIMEOUT_CLK_2E27; + stcDataCfg.u16TransMode = (u16BlockCount > 1U) ? (uint16_t)SDIOC_TRANS_MD_MULTI : + (uint16_t)SDIOC_TRANS_MD_SINGLE; + (void)SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); + /* Read block(s) in DMA mode */ + if (u16BlockCount > 1U) { + handle->u32Context = SD_CONTEXT_RD_MULTI_BLOCK | SD_CONTEXT_DMA; + /* Read Multi Block command */ + i32Ret = SDMMC_CMD18_ReadMultipleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } else { + handle->u32Context = SD_CONTEXT_RD_SINGLE_BLOCK | SD_CONTEXT_DMA; + /* Read Single Block command */ + i32Ret = SDMMC_CMD17_ReadSingleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } + + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + } + + return i32Ret; +} + +/** + * @brief Write block(s) to a specified address in a card. + * @note The Data transfer is managed by DMA mode. + * @note This API should be followed by a check on the card state through SD_GetCardState(). + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [in] u32BlockAddr Block Address + * @param [in] u16BlockCount Block Count + * @param [in] pu8Data Pointer to the buffer that will contain the data to transmit + * @retval int32_t: + * - LL_OK: Write block(s) success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or pu8Data == NULL or NULL == handle->DMAx or + * An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +int32_t SD_WriteBlocks_DMA(stc_sd_handle_t *handle, uint32_t u32BlockAddr, uint16_t u16BlockCount, uint8_t *pu8Data) +{ + int32_t i32Ret; + stc_sdioc_data_config_t stcDataCfg; + + if ((NULL == pu8Data) || (NULL == handle) || (NULL == handle->DMAx) || (0U != ((uint32_t)pu8Data % 4U))) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + handle->u32ErrorCode = SDMMC_ERR_NONE; + if ((u32BlockAddr + u16BlockCount) > (handle->stcSdCardInfo.u32LogBlockNum)) { + handle->u32ErrorCode |= SDMMC_ERR_ADDR_OUT_OF_RANGE; + return LL_ERR; + } + if (SD_CARD_SDHC_SDXC != handle->stcSdCardInfo.u32CardType) { + u32BlockAddr *= 512U; + } + + /* Set Block Size for Card */ + i32Ret = SDMMC_CMD16_SetBlockLength(handle->SDIOCx, SD_CARD_BLOCK_SIZE, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + /* Enable SDIOC transfer complete and errors interrupt */ + SDIOC_IntCmd(handle->SDIOCx, (SDIOC_INT_TCSEN | SDIOC_INT_DEBESEN | + SDIOC_INT_DCESEN | SDIOC_INT_DTOESEN), ENABLE); + /* Configure DMA parameters */ + SD_DmaTransConfig(handle, handle->u8DmaTxCh, (uint32_t)pu8Data, (uint32_t)(&handle->SDIOCx->BUF0), + (SD_CARD_BLOCK_SIZE / 4U), u16BlockCount); + /* Enable the DMA Channel */ + (void)DMA_ChCmd(handle->DMAx, handle->u8DmaTxCh, ENABLE); + /* Configure the SD data transfer */ + stcDataCfg.u16BlockSize = SD_CARD_BLOCK_SIZE; + stcDataCfg.u16BlockCount = u16BlockCount; + stcDataCfg.u16TransDir = SDIOC_TRANS_DIR_TO_CARD; + stcDataCfg.u16AutoCmd12 = SDIOC_AUTO_SEND_CMD12_DISABLE; + stcDataCfg.u16DataTimeout = SDIOC_DATA_TIMEOUT_CLK_2E27; + stcDataCfg.u16TransMode = (u16BlockCount > 1U) ? (uint16_t)SDIOC_TRANS_MD_MULTI : + (uint16_t)SDIOC_TRANS_MD_SINGLE; + (void)SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); + /* Write block(s) in DMA mode */ + if (u16BlockCount > 1U) { + handle->u32Context = SD_CONTEXT_WR_MULTI_BLOCK | SD_CONTEXT_DMA; + /* Write Multi Block command */ + i32Ret = SDMMC_CMD25_WriteMultipleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } else { + handle->u32Context = SD_CONTEXT_WR_SINGLE_BLOCK | SD_CONTEXT_DMA; + /* Write Single Block command */ + i32Ret = SDMMC_CMD24_WriteSingleBlock(handle->SDIOCx, u32BlockAddr, &handle->u32ErrorCode); + } + + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + } + + return i32Ret; +} + +/** + * @brief Abort the current transfer and disable the SD. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @retval int32_t: + * - LL_OK: Abort transfer success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: handle == NULL or + * An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +int32_t SD_Abort(stc_sd_handle_t *handle) +{ + int32_t i32Ret = LL_OK; + en_sd_card_state_t enCardState = SD_CARD_STAT_IDLE; + + if (NULL == handle) { + i32Ret = LL_ERR_INVD_PARAM; + } else { + /* Disable All interrupts */ + SDIOC_IntCmd(handle->SDIOCx, (SDIOC_INT_DEBESEN | SDIOC_INT_DCESEN | SDIOC_INT_DTOESEN | + SDIOC_INT_TCSEN | SDIOC_INT_BRRSEN | SDIOC_INT_BWRSEN), DISABLE); + /* Clear All flags */ + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + + if (0UL != (handle->u32Context & SD_CONTEXT_DMA)) { + if (NULL != handle->DMAx) { + /* Disable the DMA Channel */ + if ((0UL != (handle->u32Context & SD_CONTEXT_WR_SINGLE_BLOCK)) || + (0UL != (handle->u32Context & SD_CONTEXT_WR_MULTI_BLOCK))) { + (void)DMA_ChCmd(handle->DMAx, handle->u8DmaTxCh, DISABLE); + } else { + (void)DMA_ChCmd(handle->DMAx, handle->u8DmaRxCh, DISABLE); + } + } + } + /* Stop SD transfer */ + (void)SD_GetCardState(handle, &enCardState); + handle->u32ErrorCode = SDMMC_ERR_NONE; + if ((SD_CARD_STAT_TX_DATA == enCardState) || (SD_CARD_STAT_RX_DATA == enCardState)) { + /* Send stop transmission command */ + (void)SDMMC_CMD12_StopTrans(handle->SDIOCx, &handle->u32ErrorCode); + } + } + + return i32Ret; +} + +/** + * @brief Configure the Dma transfer parameters. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [in] u8Ch DMA transfer channel + * @param [in] u32SrcAddr Source Address + * @param [in] u32DestAddr Destination Address + * @param [in] u16BlockSize Block Size + * @param [in] u16TransCount Transfer Count + * @retval None + */ +static void SD_DmaTransConfig(const stc_sd_handle_t *handle, uint8_t u8Ch, uint32_t u32SrcAddr, uint32_t u32DestAddr, + uint16_t u16BlockSize, uint16_t u16TransCount) +{ + /* Stop Configure channel */ + (void)DMA_ChCmd(handle->DMAx, u8Ch, DISABLE); + DMA_ClearTransCompleteStatus(handle->DMAx, (uint32_t)(0x1UL << u8Ch)); + + /* Config DMA source and destination address */ + DMA_SetSrcAddr(handle->DMAx, u8Ch, u32SrcAddr); + DMA_SetDestAddr(handle->DMAx, u8Ch, u32DestAddr); + /* Config DMA block size and transfer count */ + DMA_SetBlockSize(handle->DMAx, u8Ch, u16BlockSize); + DMA_SetTransCount(handle->DMAx, u8Ch, u16TransCount); +} + +/** + * @brief Get the SD card SCR register value. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [out] pu32SCR Pointer to the value of SD card SCR register + * @retval int32_t: + * - LL_OK: Get the SCR register value success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +static int32_t SD_GetSCR(stc_sd_handle_t *handle, uint32_t pu32SCR[]) +{ + stc_sdioc_data_config_t stcDataCfg; + int32_t i32Ret; + uint32_t u32CardSta = 0UL; + uint32_t u32TempSCR[2] = {0UL, 0UL}; + + /* Check the lock status */ + i32Ret = SD_GetCurrCardStatus(handle, &u32CardSta); + if (LL_OK != i32Ret) { + return i32Ret; + } + if (SDMMC_STATUS_CARD_IS_LOCKED == (u32CardSta & SDMMC_STATUS_CARD_IS_LOCKED)) { + handle->u32ErrorCode |= SDMMC_ERR_LOCK_UNLOCK_FAILED; + return LL_ERR; + } + + /* Set Block Size To 8 Bytes */ + i32Ret = SDMMC_CMD16_SetBlockLength(handle->SDIOCx, 8UL, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Send CMD55 APP_CMD with argument as card's RCA */ + i32Ret = SDMMC_CMD55_AppCmd(handle->SDIOCx, (uint32_t)(handle->stcSdCardInfo.u32RelativeCardAddr << 16U), + &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Configure the SD data transfer */ + stcDataCfg.u16BlockSize = 8U; + stcDataCfg.u16BlockCount = 1U; + stcDataCfg.u16TransDir = SDIOC_TRANS_DIR_TO_HOST; + stcDataCfg.u16AutoCmd12 = SDIOC_AUTO_SEND_CMD12_DISABLE; + stcDataCfg.u16TransMode = SDIOC_TRANS_MD_SINGLE; + stcDataCfg.u16DataTimeout = SDIOC_DATA_TIMEOUT_CLK_2E27; + (void)SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); + /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */ + i32Ret = SDMMC_ACMD51_SendSCR(handle->SDIOCx, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + + i32Ret = SD_ReadWriteFifo(handle, &stcDataCfg, (uint8_t *)(&u32TempSCR[0]), SDMMC_DATA_TIMEOUT); + if (LL_OK != i32Ret) { + return i32Ret; + } + pu32SCR[1] = ((u32TempSCR[0] & 0x000000FFUL) << 24U) | ((u32TempSCR[0] & 0x0000FF00UL) << 8U) | + ((u32TempSCR[0] & 0x00FF0000UL) >> 8U) | ((u32TempSCR[0] & 0xFF000000UL) >> 24U); + pu32SCR[0] = ((u32TempSCR[1] & 0x000000FFUL) << 24U) | ((u32TempSCR[1] & 0x0000FF00UL) << 8U) | + ((u32TempSCR[1] & 0x00FF0000UL) >> 8U) | ((u32TempSCR[1] & 0xFF000000UL) >> 24U); + + return i32Ret; +} + +/** + * @brief Set the speed mode of the SD card. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @retval int32_t: + * - LL_OK: Set speed mode success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +static int32_t SD_SetSpeedMode(stc_sd_handle_t *handle) +{ + int32_t i32Ret = LL_OK; + stc_sdioc_data_config_t stcDataCfg; + uint32_t u32SDStatus[16]; + uint16_t u16Grp1Func; + + if (SD_CARD_SECURED != handle->stcSdCardInfo.u32CardType) { + if (SDIOC_SPEED_MD_HIGH == handle->stcSdiocInit.u8SpeedMode) { + /* Supports Specification version V1.1 or V2.0 */ + if ((SDMMC_SCR_PHY_SPEC_VER_1P1 == (handle->u32SCR[1] & SDMMC_SCR_PHY_SPEC_VER_1P1)) || + (SDMMC_SCR_PHY_SPEC_VER_2P0 == (handle->u32SCR[1] & SDMMC_SCR_PHY_SPEC_VER_2P0))) { + /* Set Block Size To 64 Bytes */ + i32Ret = SDMMC_CMD16_SetBlockLength(handle->SDIOCx, 64UL, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Configure the SD data transfer */ + stcDataCfg.u16BlockSize = 64U; + stcDataCfg.u16BlockCount = 1U; + stcDataCfg.u16TransDir = SDIOC_TRANS_DIR_TO_HOST; + stcDataCfg.u16AutoCmd12 = SDIOC_AUTO_SEND_CMD12_DISABLE; + stcDataCfg.u16TransMode = SDIOC_TRANS_MD_SINGLE; + stcDataCfg.u16DataTimeout = SDIOC_DATA_TIMEOUT_CLK_2E27; + (void)SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); + /* Send CMD6 SWITCH_FUNC with argument */ + i32Ret = SDMMC_CMD6_SwitchFunc(handle->SDIOCx, SD_SET_FUNC_HIGH_SPEED, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + + /* Get status data */ + i32Ret = SD_ReadWriteFifo(handle, &stcDataCfg, (uint8_t *)(&u32SDStatus[0]), SDMMC_DATA_TIMEOUT); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Check the result of switch function */ + u16Grp1Func = (uint16_t)(((u32SDStatus[3] & 0x000000FFUL) << 8U) | + ((u32SDStatus[3] & 0x0000FF00UL) >> 8U)); + if (SD_CMD6_RESULT_FUNC_GRP_BIT1 != (u16Grp1Func & SD_CMD6_RESULT_FUNC_GRP_BIT1)) { + handle->u32ErrorCode |= SDMMC_ERR_SWITCH_ERR; + return LL_ERR; + } + } else { + handle->u32ErrorCode |= SDMMC_ERR_REQ_NOT_APPLICABLE; + return LL_ERR; + } + } + } else { + /* MMC Card does not support this feature */ + handle->u32ErrorCode |= SDMMC_ERR_UNSUPPORT_FEATURE; + return LL_ERR; + } + /* Set the clock division and speed mode of SDIOC */ + SDIOC_SetSpeedMode(handle->SDIOCx, handle->stcSdiocInit.u8SpeedMode); + SDIOC_SetClockDiv(handle->SDIOCx, handle->stcSdiocInit.u16ClockDiv); + + return i32Ret; +} + +/** + * @brief Set the bus width of the SD card. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @retval int32_t: + * - LL_OK: Set bus width success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +static int32_t SD_SetBusWidth(stc_sd_handle_t *handle) +{ + int32_t i32Ret; + uint32_t u32BusWidth; + + if (SD_CARD_SECURED != handle->stcSdCardInfo.u32CardType) { + if (SDIOC_BUS_WIDTH_1BIT == handle->stcSdiocInit.u8BusWidth) { + u32BusWidth = 0UL; /* 1 Bit */ + } else if (SDIOC_BUS_WIDTH_4BIT == handle->stcSdiocInit.u8BusWidth) { + u32BusWidth = 2UL; /* 4 Bit */ + } else { + return LL_ERR_INVD_PARAM; + } + } else { + /* MMC Card does not support this feature */ + handle->u32ErrorCode |= SDMMC_ERR_UNSUPPORT_FEATURE; + return LL_ERR; + } + + /* Supports wide bus or 1 bit mode operation */ + if ((SDMMC_SCR_BUS_WIDTH_4BIT == (handle->u32SCR[1] & SDMMC_SCR_BUS_WIDTH_4BIT)) || + (SDMMC_SCR_BUS_WIDTH_1BIT == (handle->u32SCR[1] & SDMMC_SCR_BUS_WIDTH_1BIT))) { + /* Send CMD55 APP_CMD with argument as card's RCA.*/ + i32Ret = SDMMC_CMD55_AppCmd(handle->SDIOCx, (uint32_t)(handle->stcSdCardInfo.u32RelativeCardAddr << 16U), + &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Send ACMD6 APP_CMD with argument */ + i32Ret = SDMMC_ACMD6_SetBusWidth(handle->SDIOCx, u32BusWidth, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + } else { + handle->u32ErrorCode |= SDMMC_ERR_REQ_NOT_APPLICABLE; + return LL_ERR; + } + /* Set the bus width of SDIOC */ + SDIOC_SetBusWidth(handle->SDIOCx, handle->stcSdiocInit.u8BusWidth); + + return i32Ret; +} + +/** + * @brief Initializes the sd card. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @retval int32_t: + * - LL_OK: SD card Initialize success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +static int32_t SD_InitCard(stc_sd_handle_t *handle) +{ + int32_t i32Ret; + uint16_t u16RcaVal = 0U; + uint32_t u32TempBuffer[4]; + + /* Check the power State */ + if (DISABLE == SDIOC_GetPowerState(handle->SDIOCx)) { + handle->u32ErrorCode |= SDMMC_ERR_REQ_NOT_APPLICABLE; + return LL_ERR; + } + + if (SD_CARD_SECURED != handle->stcSdCardInfo.u32CardType) { + /* Send CMD2 ALL_SEND_CID */ + i32Ret = SDMMC_CMD2_AllSendCID(handle->SDIOCx, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Get Card identification number data */ + (void)SDIOC_GetResponse(handle->SDIOCx, SDIOC_RESP_REG_BIT0_31, &u32TempBuffer[0]); + (void)SDIOC_GetResponse(handle->SDIOCx, SDIOC_RESP_REG_BIT32_63, &u32TempBuffer[1]); + (void)SDIOC_GetResponse(handle->SDIOCx, SDIOC_RESP_REG_BIT64_95, &u32TempBuffer[2]); + (void)SDIOC_GetResponse(handle->SDIOCx, SDIOC_RESP_REG_BIT96_127, &u32TempBuffer[3]); + handle->u32CID[0] = (u32TempBuffer[0] << 8U); + handle->u32CID[1] = (u32TempBuffer[1] << 8U) | ((u32TempBuffer[0] >> 24U) & 0xFFU); + handle->u32CID[2] = (u32TempBuffer[2] << 8U) | ((u32TempBuffer[1] >> 24U) & 0xFFU); + handle->u32CID[3] = (u32TempBuffer[3] << 8U) | ((u32TempBuffer[2] >> 24U) & 0xFFU); + /* Send CMD3 SET_REL_ADDR with argument 0 */ + /* SD Card publishes its RCA */ + i32Ret = SDMMC_CMD3_SendRelativeAddr(handle->SDIOCx, &u16RcaVal, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Get the SD card RCA */ + handle->stcSdCardInfo.u32RelativeCardAddr = u16RcaVal; + /* Send CMD9 SEND_CSD with argument as card's RCA */ + i32Ret = SDMMC_CMD9_SendCSD(handle->SDIOCx, (uint32_t)(handle->stcSdCardInfo.u32RelativeCardAddr << 16U), + &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Get Card Specific Data */ + (void)SDIOC_GetResponse(handle->SDIOCx, SDIOC_RESP_REG_BIT0_31, &u32TempBuffer[0]); + (void)SDIOC_GetResponse(handle->SDIOCx, SDIOC_RESP_REG_BIT32_63, &u32TempBuffer[1]); + (void)SDIOC_GetResponse(handle->SDIOCx, SDIOC_RESP_REG_BIT64_95, &u32TempBuffer[2]); + (void)SDIOC_GetResponse(handle->SDIOCx, SDIOC_RESP_REG_BIT96_127, &u32TempBuffer[3]); + handle->u32CSD[0] = (u32TempBuffer[0] << 8U); + handle->u32CSD[1] = (u32TempBuffer[1] << 8U) | ((u32TempBuffer[0] >> 24U) & 0xFFU); + handle->u32CSD[2] = (u32TempBuffer[2] << 8U) | ((u32TempBuffer[1] >> 24U) & 0xFFU); + handle->u32CSD[3] = (u32TempBuffer[3] << 8U) | ((u32TempBuffer[2] >> 24U) & 0xFFU); + } + + /* Get the Card Class */ + handle->stcSdCardInfo.u32Class = handle->u32CSD[2] >> 20U; + /* Get CSD parameters */ + (void)SD_ExtractCardCSD(handle); + /* Select the Card */ + i32Ret = SDMMC_CMD7_SelectDeselectCard(handle->SDIOCx, (uint32_t)(handle->stcSdCardInfo.u32RelativeCardAddr << 16U), + &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + + return i32Ret; +} + +/** + * @brief Enable or disable SD power. + * @note At the power-on, Enquires cards about their operating voltage and configures + * clock controls and stores SD information. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [in] enNewState An @ref en_functional_state_t enumeration value. + * @retval int32_t: + * - LL_OK: Enable or disable SD power success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +static int32_t SD_PowerCmd(stc_sd_handle_t *handle, en_functional_state_t enNewState) +{ + uint32_t u32Response = 0UL, u32PowerSta = 0UL; + __IO uint32_t u32Count = 0UL; + int32_t i32Ret = LL_OK; + + if (DISABLE != enNewState) { + /* CMD0: GO_IDLE_STATE */ + i32Ret = SDMMC_CMD0_GoIdleState(handle->SDIOCx, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Wait for reset to completed */ + DDL_DelayMS(1U); + /* CMD8: SEND_IF_COND: Command available only on V2.0 cards */ + i32Ret = SDMMC_CMD8_SendInterfaceCond(handle->SDIOCx, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + handle->stcSdCardInfo.u32CardVersion = SD_CARD_V1_X; + /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */ + while (0UL == u32PowerSta) { + if (u32Count++ >= SDMMC_MAX_VOLT_TRIAL) { + handle->u32ErrorCode |= SDMMC_ERR_INVD_VOLT; + return LL_ERR; + } + + /* SEND CMD55 APP_CMD with RCA as 0 */ + i32Ret = SDMMC_CMD55_AppCmd(handle->SDIOCx, 0UL, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + handle->u32ErrorCode |= SDMMC_ERR_UNSUPPORT_FEATURE; + return LL_ERR; + } + /* Send ACMD41 */ + i32Ret = SDMMC_ACMD41_SendOperatCond(handle->SDIOCx, SDMMC_OCR_STD_CAPACITY, + &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + handle->u32ErrorCode |= SDMMC_ERR_UNSUPPORT_FEATURE; + return LL_ERR; + } + + /* Get command response */ + (void)SDIOC_GetResponse(handle->SDIOCx, SDIOC_RESP_REG_BIT0_31, &u32Response); + /* Get Card power up status bit (busy) */ + u32PowerSta = (((u32Response >> 31U) == 1UL) ? 1UL : 0UL); + } + /* Card type is SDSC */ + handle->stcSdCardInfo.u32CardType = SD_CARD_SDSC; + } else { + handle->stcSdCardInfo.u32CardVersion = SD_CARD_V2_X; + /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */ + while (0UL == u32PowerSta) { + if (u32Count++ >= SDMMC_MAX_VOLT_TRIAL) { + handle->u32ErrorCode |= SDMMC_ERR_INVD_VOLT; + return LL_ERR; + } + + /* SEND CMD55 APP_CMD with RCA as 0 */ + i32Ret = SDMMC_CMD55_AppCmd(handle->SDIOCx, 0UL, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Send ACMD41 */ + i32Ret = SDMMC_ACMD41_SendOperatCond(handle->SDIOCx, SDMMC_OCR_HIGH_CAPACITY, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Get command response */ + (void)SDIOC_GetResponse(handle->SDIOCx, SDIOC_RESP_REG_BIT0_31, &u32Response); + /* Get Card power up status bit (busy) */ + u32PowerSta = (((u32Response >> 31U) == 1UL) ? 1UL : 0UL); + } + + if (SDMMC_OCR_HIGH_CAPACITY == (u32Response & SDMMC_OCR_HIGH_CAPACITY)) { + handle->stcSdCardInfo.u32CardType = SD_CARD_SDHC_SDXC; + } else { + handle->stcSdCardInfo.u32CardType = SD_CARD_SDSC; + } + } + } else { + /* Set Power State to OFF */ + SDIOC_ClockCmd(handle->SDIOCx, DISABLE); + SDIOC_PowerCmd(handle->SDIOCx, DISABLE); + } + + return i32Ret; +} + +/** + * @brief Get the current card status. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [out] pu32CardStatus Pointer to the value of current card status + * @retval int32_t: + * - LL_OK: Get card status success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +static int32_t SD_GetCurrCardStatus(stc_sd_handle_t *handle, uint32_t *pu32CardStatus) +{ + int32_t i32Ret; + + /* Send Status command */ + i32Ret = SDMMC_CMD13_SendStatus(handle->SDIOCx, (uint32_t)(handle->stcSdCardInfo.u32RelativeCardAddr << 16U), + &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Get SD card status */ + (void)SDIOC_GetResponse(handle->SDIOCx, SDIOC_RESP_REG_BIT0_31, pu32CardStatus); + + return i32Ret; +} + +/** + * @brief Get the current SD status. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [out] pu32SDStatus Pointer to the buffer of current SD status + * @retval int32_t: + * - LL_OK: Get card status success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +static int32_t SD_GetCurrSDStatus(stc_sd_handle_t *handle, uint32_t *pu32SDStatus) +{ + int32_t i32Ret; + stc_sdioc_data_config_t stcDataCfg; + uint32_t u32CardSta = 0UL; + + /* Check the lock status */ + i32Ret = SD_GetCurrCardStatus(handle, &u32CardSta); + if (LL_OK != i32Ret) { + return i32Ret; + } + if (SDMMC_STATUS_CARD_IS_LOCKED == (u32CardSta & SDMMC_STATUS_CARD_IS_LOCKED)) { + handle->u32ErrorCode |= SDMMC_ERR_LOCK_UNLOCK_FAILED; + return LL_ERR; + } + + /* Set Block Size To 64 Bytes */ + i32Ret = SDMMC_CMD16_SetBlockLength(handle->SDIOCx, 64UL, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Send CMD55 APP_CMD with argument as card's RCA.*/ + i32Ret = SDMMC_CMD55_AppCmd(handle->SDIOCx, (uint32_t)(handle->stcSdCardInfo.u32RelativeCardAddr << 16U), + &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + /* Configure the SD data transfer */ + stcDataCfg.u16BlockSize = 64U; + stcDataCfg.u16BlockCount = 1U; + stcDataCfg.u16TransDir = SDIOC_TRANS_DIR_TO_HOST; + stcDataCfg.u16AutoCmd12 = SDIOC_AUTO_SEND_CMD12_DISABLE; + stcDataCfg.u16TransMode = SDIOC_TRANS_MD_SINGLE; + stcDataCfg.u16DataTimeout = SDIOC_DATA_TIMEOUT_CLK_2E27; + (void)SDIOC_ConfigData(handle->SDIOCx, &stcDataCfg); + /* Send ACMD13 SD_STATUS */ + i32Ret = SDMMC_ACMD13_SendStatus(handle->SDIOCx, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + return i32Ret; + } + + /* Get status data */ + i32Ret = SD_ReadWriteFifo(handle, &stcDataCfg, (uint8_t *)pu32SDStatus, SDMMC_DATA_TIMEOUT); + if (LL_OK != i32Ret) { + return i32Ret; + } + + return i32Ret; +} + +/** + * @brief Read or Write the SD Card FIFO. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @param [in] pstcDataConfig Pointer to a @ref stc_sdioc_data_config_t structure + * @param [out] pu8Data Pointer to the value of read/write fifo + * @param [in] u32Timeout The timeout time + * @retval int32_t: + * - LL_OK: Read or Write the FIFO success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + * - LL_ERR_INVD_PARAM: An invalid parameter was write to the send command + * - LL_ERR_TIMEOUT: Send command timeout + */ +static int32_t SD_ReadWriteFifo(stc_sd_handle_t *handle, const stc_sdioc_data_config_t *pstcDataConfig, + uint8_t pu8Data[], uint32_t u32Timeout) +{ + __IO uint32_t u32Count; + int32_t i32Ret = LL_OK; + uint32_t u32Index = 0UL; + + /* The u32Timeout is expressed in ms */ + u32Count = u32Timeout * (HCLK_VALUE / 20000UL); + while (RESET == SDIOC_GetIntStatus(handle->SDIOCx, (SDIOC_INT_FLAG_DEBE | SDIOC_INT_FLAG_DCE | + SDIOC_INT_FLAG_DTOE | SDIOC_INT_FLAG_TC))) { + if (SDIOC_TRANS_DIR_TO_CARD != pstcDataConfig->u16TransDir) { + /* Read buffer data */ + if (SET == SDIOC_GetHostStatus(handle->SDIOCx, SDIOC_HOST_FLAG_BRE)) { + (void)SDIOC_ReadBuffer(handle->SDIOCx, (uint8_t *)&pu8Data[u32Index], + (uint32_t)(pstcDataConfig->u16BlockSize)); + u32Index += pstcDataConfig->u16BlockSize; + } + } else { + /* Write buffer data */ + if (SET == SDIOC_GetHostStatus(handle->SDIOCx, SDIOC_HOST_FLAG_BWE)) { + (void)SDIOC_WriteBuffer(handle->SDIOCx, (uint8_t *)&pu8Data[u32Index], + (uint32_t)(pstcDataConfig->u16BlockSize)); + u32Index += pstcDataConfig->u16BlockSize; + } + } + if (0UL == u32Count) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return LL_ERR_TIMEOUT; + } + u32Count--; + } + + /* Send stop transmission command in case of multiblock read/write */ + if ((SET == SDIOC_GetIntStatus(handle->SDIOCx, SDIOC_INT_FLAG_TC)) && (pstcDataConfig->u16BlockCount > 1U)) { + if (SD_CARD_SECURED != handle->stcSdCardInfo.u32CardType) { + /* Send stop transmission command */ + i32Ret = SDMMC_CMD12_StopTrans(handle->SDIOCx, &handle->u32ErrorCode); + if (LL_OK != i32Ret) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return i32Ret; + } + } + } + + /* Get error state */ + if (SET == SDIOC_GetIntStatus(handle->SDIOCx, SDIOC_INT_FLAG_DEBE)) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + handle->u32ErrorCode |= SDMMC_ERR_DATA_STOP_BIT; + return LL_ERR; + } else if (SET == SDIOC_GetIntStatus(handle->SDIOCx, SDIOC_INT_FLAG_DCE)) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + handle->u32ErrorCode |= SDMMC_ERR_DATA_CRC_FAIL; + return LL_ERR; + } else if (SET == SDIOC_GetIntStatus(handle->SDIOCx, SDIOC_INT_FLAG_DTOE)) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + handle->u32ErrorCode |= SDMMC_ERR_DATA_TIMEOUT; + return LL_ERR; + } else { + /* Empty FIFO if there is still any data */ + if (SDIOC_TRANS_DIR_TO_CARD != pstcDataConfig->u16TransDir) { + u32Count = u32Timeout * (HCLK_VALUE / 20000UL); + while (SET == SDIOC_GetHostStatus(handle->SDIOCx, SDIOC_HOST_FLAG_BRE)) { + (void)SDIOC_ReadBuffer(handle->SDIOCx, (uint8_t *)&pu8Data[u32Index], + (uint32_t)(pstcDataConfig->u16BlockSize)); + u32Index += pstcDataConfig->u16BlockSize; + if (0UL == u32Count) { + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + return LL_ERR_TIMEOUT; + } + u32Count--; + } + } + /* Clear all the error and completed flags */ + SDIOC_ClearIntStatus(handle->SDIOCx, SDIOC_INT_STATIC_FLAGS); + } + + return i32Ret; +} + +/** + * @brief Extract information of the card which CSD register. + * @param [in] handle Pointer to a @ref stc_sd_handle_t structure + * @retval int32_t: + * - LL_OK: Get sd card CSD register success + * - LL_ERR: Refer to u32ErrorCode for the reason of error + */ +static int32_t SD_ExtractCardCSD(stc_sd_handle_t *handle) +{ + int32_t i32Ret = LL_OK; + uint32_t u32Temp; + stc_sd_card_csd_t stcCardCSD; + + stcCardCSD.u8ReadBlockLen = (uint8_t)((handle->u32CSD[2] & 0x000F0000U) >> 16U); + if (SD_CARD_SDSC == handle->stcSdCardInfo.u32CardType) { + u32Temp = (uint8_t)((handle->u32CSD[1] & 0xFF000000U) >> 24U); + stcCardCSD.u32DeviceSize = (uint32_t)(((handle->u32CSD[2] & 0x000003FFU) << 2U) | ((u32Temp & 0xC0U) >> 6U)); + u32Temp = (uint8_t)((handle->u32CSD[1] & 0x00FF0000U) >> 16U); + stcCardCSD.u8DeviceSizeMul = (uint8_t)((u32Temp & 0x03U) << 1U); + u32Temp = (uint8_t)((handle->u32CSD[1] & 0x0000FF00U) >> 8U); + stcCardCSD.u8DeviceSizeMul |= (uint8_t)((u32Temp & 0x80U) >> 7U); + + handle->stcSdCardInfo.u32BlockNum = (stcCardCSD.u32DeviceSize + 1U) ; + handle->stcSdCardInfo.u32BlockNum *= (1UL << (stcCardCSD.u8DeviceSizeMul + 2U)); + handle->stcSdCardInfo.u32BlockSize = 1UL << (stcCardCSD.u8ReadBlockLen); + if (handle->stcSdCardInfo.u32BlockSize >= 512U) { + handle->stcSdCardInfo.u32LogBlockNum = handle->stcSdCardInfo.u32BlockNum * + (handle->stcSdCardInfo.u32BlockSize / 512U); + } else { + handle->stcSdCardInfo.u32LogBlockNum = (handle->stcSdCardInfo.u32BlockNum / 512U) * + handle->stcSdCardInfo.u32BlockSize; + } + handle->stcSdCardInfo.u32LogBlockSize = 512UL; + } else if (SD_CARD_SDHC_SDXC == handle->stcSdCardInfo.u32CardType) { + stcCardCSD.u32DeviceSize = (uint32_t)(((handle->u32CSD[2] & 0x0000003FU) << 16U) | + ((handle->u32CSD[1] & 0xFFFF0000U) >> 16U)); + + handle->stcSdCardInfo.u32BlockNum = (stcCardCSD.u32DeviceSize + 1U) * 1024U; + handle->stcSdCardInfo.u32BlockSize = 512U; + handle->stcSdCardInfo.u32LogBlockNum = handle->stcSdCardInfo.u32BlockNum; + handle->stcSdCardInfo.u32LogBlockSize = handle->stcSdCardInfo.u32BlockSize; + } else { + handle->u32ErrorCode |= SDMMC_ERR_UNSUPPORT_FEATURE; + return LL_ERR; + } + + return i32Ret; +} + +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/Kconfig new file mode 100644 index 000000000..262f7cecc --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/Kconfig @@ -0,0 +1,42 @@ +if BSP_USING_SPI + config BSP_USING_SPI1 + bool "Using spi1" + default y + + if BSP_USING_SPI1 + config SPI_BUS_NAME_1 + string "spi bus 1 name" + default "spi1" + config SPI_1_DEVICE_NAME_0 + string "spi bus 1 device 0 name" + default "spi1_dev0" + config SPI_1_DRV_NAME + string "spi bus 1 driver name" + default "spi1_drv" + + menuconfig RESOURCES_SPI_LORA + bool "Using spi lora function" + default n + if RESOURCES_SPI_LORA + config SX12XX_DEVICE_NAME + string "SX12XX(SX1278 SX1276) lora device name" + default "spi1_lora" + endif + endif + + config BSP_USING_SPI6 + bool "Using spi6" + default n + + if BSP_USING_SPI6 + config SPI_BUS_NAME_6 + string "spi bus 6 name" + default "spi6" + config SPI_6_DEVICE_NAME_0 + string "spi bus 6 device 0 name" + default "spi6_dev0" + config SPI_6_DRV_NAME + string "spi bus 6 driver name" + default "spi6_drv" + endif +endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/Makefile new file mode 100644 index 000000000..d07c0cb5c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/Makefile @@ -0,0 +1,8 @@ +SRC_FILES := connect_spi.c + +ifeq ($(CONFIG_RESOURCES_SPI_LORA),y) + SRC_DIR := third_party_spi_lora + SRC_FILES += connect_lora_spi.c +endif + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/connect_lora_spi.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/connect_lora_spi.c new file mode 100644 index 000000000..baa130571 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/connect_lora_spi.c @@ -0,0 +1,469 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_lora_spi.c +* @brief support to register spi lora pointer and function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-31 +*/ + +#include + +/* RST = PI02 */ +#define LORA_RST_PORT (GPIO_PORT_I) +#define LORA_RST_PIN (GPIO_PIN_02) + +static struct HardwareDev *g_spi_lora_dev; +tRadioDriver *Radio = NONE; + +void SX1276InitIo(void) +{ + stc_gpio_init_t stcGpioInit; + + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_RST; + stcGpioInit.u16PinDir = PIN_DIR_OUT; + (void)GPIO_Init(LORA_RST_PORT, LORA_RST_PIN, &stcGpioInit); +} + +inline void SX1276WriteRxTx(uint8_t txEnable) +{ + if (txEnable != 0) { + /*to do*/ + } else { + /*to do*/ + } +} + +void SX1276SetReset(uint8_t state) +{ + if (state == RADIO_RESET_ON) { + GPIO_ResetPins(LORA_RST_PORT, LORA_RST_PIN); + } else { + stc_gpio_init_t stcGpioInit; + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinDir = PIN_DIR_IN; + (void)GPIO_Init(LORA_RST_PORT, LORA_RST_PIN, &stcGpioInit); + } +} + +//Not-necessary Function +uint8_t SX1276ReadDio0(void) +{ + return 1; +} + +uint8_t SX1276ReadDio1(void) +{ + return 1; +} + +uint8_t SX1276ReadDio2(void) +{ + return 1; +} + +uint8_t SX1276ReadDio3(void) +{ + return 1; +} + +uint8_t SX1276ReadDio4(void) +{ + return 1; +} + +uint8_t SX1276ReadDio5(void) +{ + return 1; +} + +void SX1276WriteBuffer(uint8_t addr, uint8_t *buffer, uint8_t size) +{ + struct BusBlockWriteParam write_param; + uint8 write_addr = addr | 0x80; + + BusDevOpen(g_spi_lora_dev); + + write_param.buffer = (void *)&write_addr; + write_param.size = 1; + BusDevWriteData(g_spi_lora_dev, &write_param); + + write_param.buffer = (void *)buffer; + write_param.size = size; + BusDevWriteData(g_spi_lora_dev, &write_param); + + BusDevClose(g_spi_lora_dev); +} + +void SX1276ReadBuffer(uint8_t addr, uint8_t *buffer, uint8_t size) +{ + struct BusBlockWriteParam write_param; + struct BusBlockReadParam read_param; + + uint8 write_addr = addr & 0x7F; + + BusDevOpen(g_spi_lora_dev); + + write_param.buffer = (void *)&write_addr; + write_param.size = 1; + BusDevWriteData(g_spi_lora_dev, &write_param); + + read_param.buffer = (void *)buffer; + read_param.size = size; + BusDevReadData(g_spi_lora_dev, &read_param); + + BusDevClose(g_spi_lora_dev); +} + +void SX1276WriteFifo(uint8_t *buffer, uint8_t size) +{ + SX1276WriteBuffer(0, buffer, size); +} + +void SX1276ReadFifo(uint8_t *buffer, uint8_t size) +{ + SX1276ReadBuffer(0, buffer, size); +} + +void SX1276Write(uint8_t addr, uint8_t data) +{ + SX1276WriteBuffer(addr, &data, 1); +} + +void SX1276Read(uint8_t addr, uint8_t *data) +{ + SX1276ReadBuffer(addr, data, 1); +} + +uint8_t Sx1276SpiCheck(void) +{ + uint8_t test = 0; + + tLoRaSettings settings; + SX1276Read(REG_LR_VERSION, &test); + KPrintf("version code of the chip is 0x%x\n", test); + + settings.RFFrequency = SX1276LoRaGetRFFrequency(); + KPrintf("SX1278 Lora parameters are :\nRFFrequency is %d\n", settings.RFFrequency); + + settings.Power = SX1276LoRaGetRFPower(); + KPrintf("RFPower is %d\n",settings.Power); + + settings.SignalBw = SX1276LoRaGetSignalBandwidth(); + KPrintf("SignalBw is %d\n",settings.SignalBw); + + settings.SpreadingFactor = SX1276LoRaGetSpreadingFactor(); + KPrintf("SpreadingFactor is %d\n",settings.SpreadingFactor); + + /*SPI confirm*/ + SX1276Write(REG_LR_HOPPERIOD, 0x91); + SX1276Read(REG_LR_HOPPERIOD, &test); + if (test != 0x91) { + return 0; + } + return test; +} + +/** + * This function supports to write data to the lora. + * + * @param dev lora dev descriptor + * @param write_param lora dev write datacfg param + */ +static uint32 SpiLoraWrite(void *dev, struct BusBlockWriteParam *write_param) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(write_param); + + if (write_param->size > 256) { + KPrintf("SpiLoraWrite ERROR:The message is too long!\n"); + return ERROR; + } else { + SX1276SetTxPacket(write_param->buffer, write_param->size); + while(SX1276Process() != RF_TX_DONE); + KPrintf("SpiLoraWrite success!\n"); + } + + return EOK; +} + +/** + * This function supports to read data from the lora. + * + * @param dev lora dev descriptor + * @param read_param lora dev read datacfg param + */ +static uint32 SpiLoraRead(void *dev, struct BusBlockReadParam *read_param) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(read_param); + + int read_times = 100; + + SX1276StartRx(); + KPrintf("SpiLoraRead Ready!\n"); + + while (read_times) { + if (SX1276Process() != RF_RX_DONE) { + read_times --; + MdelayKTask(500); + } else { + break; + } + } + + if (read_times > 0) { + SX1276GetRxPacket(read_param->buffer, (uint16 *)&read_param->read_length); + } else { + read_param->read_length = 0; + } + + return read_param->read_length; +} + +static uint32 SpiLoraOpen(void *dev) +{ + NULL_PARAM_CHECK(dev); + + KPrintf("SpiLoraOpen start\n"); + + x_err_t ret = EOK; + static x_bool lora_init_status = RET_FALSE; + + if (RET_TRUE == lora_init_status) { + return EOK; + } + + struct HardwareDev *haldev = (struct HardwareDev *)dev; + + struct SpiHardwareDevice *lora_dev = CONTAINER_OF(haldev, struct SpiHardwareDevice, haldev); + NULL_PARAM_CHECK(lora_dev); + + SpiLoraDeviceType spi_lora_dev = CONTAINER_OF(lora_dev, struct SpiLoraDevice, lora_dev); + NULL_PARAM_CHECK(spi_lora_dev); + + struct Driver *spi_drv = spi_lora_dev->spi_dev->haldev.owner_bus->owner_driver; + + struct BusConfigureInfo configure_info; + struct SpiMasterParam spi_master_param; + spi_master_param.spi_data_bit_width = 8; + spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB; + + configure_info.configure_cmd = OPE_CFG; + configure_info.private_data = (void *)&spi_master_param; + ret = BusDrvConfigure(spi_drv, &configure_info); + if (ret) { + KPrintf("spi drv OPE_CFG error drv %8p cfg %8p\n", spi_drv, &spi_master_param); + return ERROR; + } + + configure_info.configure_cmd = OPE_INT; + ret = BusDrvConfigure(spi_drv, &configure_info); + if (ret) { + KPrintf("spi drv OPE_INT error drv %8p\n", spi_drv); + return ERROR; + } + + SX1276Init(); + + if (0x91 != Sx1276SpiCheck()) { + KPrintf("LoRa check failed!\n!"); + } else { + Radio = RadioDriverInit(); + KPrintf("LoRa check ok!\nNote: The length of the message that can be sent in a single time is 256 characters\n"); + } + + lora_init_status = RET_TRUE; + + return ret; +} + +static uint32 SpiLoraClose(void *dev) +{ + NULL_PARAM_CHECK(dev); + + return EOK; +} + +static const struct LoraDevDone lora_done = +{ + .open = SpiLoraOpen, + .close = SpiLoraClose, + .write = SpiLoraWrite, + .read = SpiLoraRead, +}; + +/** + * This function supports to init spi_lora_dev + * + * @param bus_name spi bus name + * @param dev_name spi dev name + * @param drv_name spi drv name + * @param lora_name lora dev name + */ +SpiLoraDeviceType SpiLoraInit(char *bus_name, char *dev_name, char *drv_name, char *lora_name) +{ + NULL_PARAM_CHECK(dev_name); + NULL_PARAM_CHECK(drv_name); + NULL_PARAM_CHECK(lora_name); + NULL_PARAM_CHECK(bus_name); + + x_err_t ret; + static HardwareDevType haldev; + + haldev = SpiDeviceFind(dev_name, TYPE_SPI_DEV); + if (NONE == haldev) { + KPrintf("SpiLoraInit find spi haldev %s error! \n", dev_name); + return NONE; + } + + SpiLoraDeviceType spi_lora_dev = (SpiLoraDeviceType)malloc(sizeof(struct SpiLoraDevice)); + if (NONE == spi_lora_dev) { + KPrintf("SpiLoraInit malloc spi_lora_dev failed\n"); + free(spi_lora_dev); + return NONE; + } + + memset(spi_lora_dev, 0, sizeof(struct SpiLoraDevice)); + + spi_lora_dev->spi_dev = CONTAINER_OF(haldev, struct SpiHardwareDevice, haldev); + + spi_lora_dev->lora_dev.spi_dev_flag = RET_TRUE; + spi_lora_dev->lora_dev.haldev.dev_done = (struct HalDevDone *)&lora_done; + + struct Driver *spi_driver = SpiDriverFind(drv_name, TYPE_SPI_DRV); + if (NONE == spi_driver) { + KPrintf("SpiLoraInit find spi driver %s error! \n", drv_name); + free(spi_lora_dev); + return NONE; + } + + //spi drv get spi dev param (SpiDeviceParam) + spi_driver->private_data = spi_lora_dev->spi_dev->haldev.private_data; + spi_lora_dev->spi_dev->haldev.owner_bus->owner_driver = spi_driver; + + ret = SpiDeviceRegister(&spi_lora_dev->lora_dev, spi_lora_dev->spi_dev->haldev.private_data, lora_name); + if (EOK != ret) { + KPrintf("SpiLoraInit SpiDeviceRegister device %s error %d\n", lora_name, ret); + free(spi_lora_dev); + return NONE; + } + + ret = SpiDeviceAttachToBus(lora_name, bus_name); + if (EOK != ret) { + KPrintf("SpiLoraInit SpiDeviceAttachToBus device %s error %d\n", lora_name, ret); + free(spi_lora_dev); + return NONE; + } + + g_spi_lora_dev = &spi_lora_dev->spi_dev->haldev; + + return spi_lora_dev; +} + +/** + * This function supports to release spi_lora_dev + * + * @param spi_lora_dev spi lora descriptor + */ +uint32 SpiLoraRelease(SpiLoraDeviceType spi_lora_dev) +{ + NULL_PARAM_CHECK(spi_lora_dev); + + x_err_t ret; + + DeviceDeleteFromBus(spi_lora_dev->lora_dev.haldev.owner_bus, &spi_lora_dev->lora_dev.haldev); + + free(spi_lora_dev); + + return EOK; +} + +int LoraSx12xxSpiDeviceInit(void) +{ +#ifdef BSP_USING_SPI1 + if (NONE == SpiLoraInit(SPI_BUS_NAME_1, SPI_1_DEVICE_NAME_0, SPI_1_DRV_NAME, SX12XX_DEVICE_NAME)) { + return ERROR; + } +#endif + + return EOK; +} + +#define LORA_TEST +#ifdef LORA_TEST +/*Just for lora test*/ +static struct Bus *bus; +static struct HardwareDev *dev; + +void LoraOpen(void) +{ + x_err_t ret = EOK; + + bus = BusFind(SPI_BUS_NAME_1); + dev = BusFindDevice(bus, SX12XX_DEVICE_NAME); + + ret = SpiLoraOpen(dev); + if (EOK != ret) { + KPrintf("LoRa init failed\n"); + return; + } + + KPrintf("LoRa init succeed\n"); + + return; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + LoraOpen, LoraOpen, open lora device and read parameters ); + +static void LoraReceive(void) +{ + uint32 read_length = 0; + struct BusBlockReadParam read_param; + memset(&read_param, 0, sizeof(struct BusBlockReadParam)); + + read_param.buffer = malloc(SPI_LORA_BUFFER_SIZE); + + read_length = SpiLoraRead(dev, &read_param); + + KPrintf("LoraReceive length %d\n", read_length); + for (int i = 0; i < read_length; i ++) { + KPrintf("i %d data 0x%x\n", i, ((uint8 *)read_param.buffer)[i]); + } + + free(read_param.buffer); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0), +LoraReceive, LoraReceive, lora wait message ); + +static void LoraSend(int argc, char *argv[]) +{ + char Msg[SPI_LORA_BUFFER_SIZE] = {0}; + struct BusBlockWriteParam write_param; + memset(&write_param, 0, sizeof(struct BusBlockWriteParam)); + + if (argc == 2) { + strncpy(Msg, argv[1], SPI_LORA_BUFFER_SIZE); + write_param.buffer = Msg; + write_param.size = strlen(Msg); + + KPrintf("LoraSend data %s length %d\n", Msg, strlen(Msg)); + + SpiLoraWrite(dev, &write_param); + } +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +LoraSend, LoraSend, lora send message ); +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/connect_spi.c new file mode 100644 index 000000000..f74767f13 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/connect_spi.c @@ -0,0 +1,585 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_spi.c +* @brief support hc32f4a0-board spi function and register to bus framework +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +/************************************************* +File name: connect_spi.c +Description: support hc32f4a0-board spi function and register to bus framework +Others: +History: +1. Date: 2022-10-17 +Author: AIIT XUOS Lab +Modification: +1. support hc32f4a0-board spi configure, write and read +2. support hc32f4a0-board spi bus device and driver register +3. SPI1 for LoRa, SPI6 using J12-pin-header to connect +*************************************************/ + +#include + +#define SPI1_MASTER_SLAVE_MODE (SPI_MASTER) + +/* SPI1 definition */ +#define SPI1_UNIT (CM_SPI1) +#define SPI1_CLK (FCG1_PERIPH_SPI1) + +/* SS = PI01 */ +#define SPI1_SS_PORT (GPIO_PORT_I) +#define SPI1_SS_PIN (GPIO_PIN_01) +/* SCK = PH14 */ +#define SPI1_SCK_PORT (GPIO_PORT_H) +#define SPI1_SCK_PIN (GPIO_PIN_14) +#define SPI1_SCK_FUNC (GPIO_FUNC_40) +/* MOSI = PI00 */ +#define SPI1_MOSI_PORT (GPIO_PORT_I) +#define SPI1_MOSI_PIN (GPIO_PIN_00) +#define SPI1_MOSI_FUNC (GPIO_FUNC_41) +/* MISO = PH15 */ +#define SPI1_MISO_PORT (GPIO_PORT_H) +#define SPI1_MISO_PIN (GPIO_PIN_15) +#define SPI1_MISO_FUNC (GPIO_FUNC_42) + +#define SPI1_DEVICE_SLAVE_ID_0 0 + +/* SPI6 definition */ +#define SPI6_UNIT (CM_SPI6) +#define SPI6_CLK (FCG1_PERIPH_SPI6) + +/* SS = PI01 */ +#define SPI6_SS_PORT (GPIO_PORT_I) +#define SPI6_SS_PIN (GPIO_PIN_01) +/* SCK = PH14 */ +#define SPI6_SCK_PORT (GPIO_PORT_H) +#define SPI6_SCK_PIN (GPIO_PIN_14) +#define SPI6_SCK_FUNC (GPIO_FUNC_40) +/* MOSI = PI00 */ +#define SPI6_MOSI_PORT (GPIO_PORT_I) +#define SPI6_MOSI_PIN (GPIO_PIN_00) +#define SPI6_MOSI_FUNC (GPIO_FUNC_41) +/* MISO = PH15 */ +#define SPI6_MISO_PORT (GPIO_PORT_H) +#define SPI6_MISO_PIN (GPIO_PIN_15) +#define SPI6_MISO_FUNC (GPIO_FUNC_42) + +#define SPI6_DEVICE_SLAVE_ID_0 0 + +static void HwSpiEnable(CM_SPI_TypeDef *SPIx) +{ + /* Check if the SPI is already enabled */ + if (SPI_CR1_SPE != (SPIx->CR1 & SPI_CR1_SPE)) { + SPI_Cmd(SPIx, ENABLE); + } +} + +/*Init the spi sdk intetface */ +static uint32 SpiSdkInit(struct SpiDriver *spi_drv) +{ + NULL_PARAM_CHECK(spi_drv); + + stc_spi_init_t stcSpiInit; + stc_gpio_init_t stcGpioInit; + + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data); + +#ifdef BSP_USING_SPI1 + /* Configure Port */ + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_RST; + stcGpioInit.u16PinDir = PIN_DIR_OUT; + (void)GPIO_Init(SPI1_SS_PORT, SPI1_SS_PIN, &stcGpioInit); + GPIO_SetPins(SPI1_SS_PORT, SPI1_SS_PIN); + + GPIO_SetFunc(SPI1_SCK_PORT, SPI1_SCK_PIN, SPI1_SCK_FUNC); + GPIO_SetFunc(SPI1_MOSI_PORT, SPI1_MOSI_PIN, SPI1_MOSI_FUNC); + GPIO_SetFunc(SPI1_MISO_PORT, SPI1_MISO_PIN, SPI1_MISO_FUNC); + + /* Configuration SPI */ + FCG_Fcg1PeriphClockCmd(SPI1_CLK, ENABLE); + SPI_StructInit(&stcSpiInit); + + stcSpiInit.u32WireMode = SPI_4_WIRE; + stcSpiInit.u32TransMode = SPI_FULL_DUPLEX; + stcSpiInit.u32MasterSlave = SPI1_MASTER_SLAVE_MODE; + stcSpiInit.u32Parity = SPI_PARITY_INVD; + + if (SPI_MODE_0 == dev_param->spi_master_param->spi_work_mode & 0x3) { + stcSpiInit.u32SpiMode = SPI_MD_0; + } else if (SPI_MODE_1 == dev_param->spi_master_param->spi_work_mode & 0x3) { + stcSpiInit.u32SpiMode = SPI_MD_1; + } else if (SPI_MODE_2 == dev_param->spi_master_param->spi_work_mode & 0x3) { + stcSpiInit.u32SpiMode = SPI_MD_2; + } else if (SPI_MODE_3 == dev_param->spi_master_param->spi_work_mode & 0x3) { + stcSpiInit.u32SpiMode = SPI_MD_3; + } + + stcSpiInit.u32BaudRatePrescaler = SPI_BR_CLK_DIV64; + + if (8 == dev_param->spi_master_param->spi_data_bit_width) { + stcSpiInit.u32DataBits = SPI_DATA_SIZE_8BIT; + } else if (7 == dev_param->spi_master_param->spi_data_bit_width) { + stcSpiInit.u32DataBits = SPI_DATA_SIZE_7BIT; + } + + if (SPI_LSB == dev_param->spi_master_param->spi_work_mode & 0x4) { + stcSpiInit.u32FirstBit = SPI_FIRST_LSB; + } else if(SPI_MSB == dev_param->spi_master_param->spi_work_mode & 0x4) { + stcSpiInit.u32FirstBit = SPI_FIRST_MSB; + } + + stcSpiInit.u32FrameLevel = SPI_1_FRAME; + + (void)SPI_Init(SPI1_UNIT, &stcSpiInit); + SPI_Cmd(SPI1_UNIT, ENABLE); +#endif + +#ifdef BSP_USING_SPI6 + /* Configure Port */ + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_RST; + stcGpioInit.u16PinDir = PIN_DIR_OUT; + (void)GPIO_Init(SPI6_SS_PORT, SPI6_SS_PIN, &stcGpioInit); + GPIO_SetPins(SPI6_SS_PORT, SPI6_SS_PIN); + + GPIO_SetFunc(SPI6_SCK_PORT, SPI6_SCK_PIN, SPI6_SCK_FUNC); + GPIO_SetFunc(SPI6_MOSI_PORT, SPI6_MOSI_PIN, SPI6_MOSI_FUNC); + GPIO_SetFunc(SPI6_MISO_PORT, SPI6_MISO_PIN, SPI6_MISO_FUNC); + + /* Configuration SPI */ + FCG_Fcg1PeriphClockCmd(SPI6_CLK, ENABLE); + SPI_StructInit(&stcSpiInit); + + stcSpiInit.u32WireMode = SPI_4_WIRE; + stcSpiInit.u32TransMode = SPI_FULL_DUPLEX; + stcSpiInit.u32MasterSlave = SPI1_MASTER_SLAVE_MODE; + stcSpiInit.u32Parity = SPI_PARITY_INVD; + + if (SPI_MODE_0 == dev_param->spi_master_param->spi_work_mode & 0x3) { + stcSpiInit.u32SpiMode = SPI_MD_0; + } else if (SPI_MODE_1 == dev_param->spi_master_param->spi_work_mode & 0x3) { + stcSpiInit.u32SpiMode = SPI_MD_1; + } else if (SPI_MODE_2 == dev_param->spi_master_param->spi_work_mode & 0x3) { + stcSpiInit.u32SpiMode = SPI_MD_2; + } else if (SPI_MODE_3 == dev_param->spi_master_param->spi_work_mode & 0x3) { + stcSpiInit.u32SpiMode = SPI_MD_3; + } + + stcSpiInit.u32BaudRatePrescaler = SPI_BR_CLK_DIV64; + + if (8 == dev_param->spi_master_param->spi_data_bit_width) { + stcSpiInit.u32DataBits = SPI_DATA_SIZE_8BIT; + } else if (7 == dev_param->spi_master_param->spi_data_bit_width) { + stcSpiInit.u32DataBits = SPI_DATA_SIZE_7BIT; + } + + if (SPI_LSB == dev_param->spi_master_param->spi_work_mode & 0x4) { + stcSpiInit.u32FirstBit = SPI_FIRST_LSB; + } else if(SPI_MSB == dev_param->spi_master_param->spi_work_mode & 0x4) { + stcSpiInit.u32FirstBit = SPI_FIRST_MSB; + } + + stcSpiInit.u32FrameLevel = SPI_1_FRAME; + + (void)SPI_Init(SPI6_UNIT, &stcSpiInit); + SPI_Cmd(SPI6_UNIT, ENABLE); +#endif + + return EOK; +} + +static uint32 SpiSdkCfg(struct SpiDriver *spi_drv, struct SpiMasterParam *spi_param) +{ + NULL_PARAM_CHECK(spi_drv); + NULL_PARAM_CHECK(spi_param); + + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data); + + dev_param->spi_master_param = spi_param; + dev_param->spi_master_param->spi_work_mode = dev_param->spi_master_param->spi_work_mode & SPI_MODE_MASK; + + return EOK; +} + +/*Configure the spi device param, make sure struct (configure_info->private_data) = (SpiMasterParam)*/ +static uint32 SpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct SpiDriver *spi_drv = (struct SpiDriver *)drv; + struct SpiMasterParam *spi_param; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + ret = SpiSdkInit(spi_drv); + break; + case OPE_CFG: + spi_param = (struct SpiMasterParam *)configure_info->private_data; + ret = SpiSdkCfg(spi_drv, spi_param); + break; + default: + break; + } + + return ret; +} + +static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + uint8 cs_gpio_port = dev_param->spi_slave_param->spi_cs_gpio_port; + CM_SPI_TypeDef *spi = spi_dev->haldev.owner_bus->private_data; + + int i = 0; + uint32 ret = EOK; + int32 spi_write_status = 0; + + while (NONE != spi_datacfg) { + if (spi_datacfg->spi_chip_select) { + GPIO_ResetPins(cs_gpio_port, cs_gpio_pin); + } + + if (spi_datacfg->length) { + uint8 *tx_buff = x_malloc(spi_datacfg->length); + if ((spi_datacfg->tx_buff) && (tx_buff)) { + memset(tx_buff, 0, spi_datacfg->length); + + for (i = 0; i < spi_datacfg->length; i++) { + tx_buff[i] = ((uint8 *)spi_datacfg->tx_buff)[i]; + } + + HwSpiEnable(spi); + spi_write_status = SPI_Trans(spi, tx_buff, spi_datacfg->length, 1000); + + while (RESET != SPI_GetStatus(spi, SPI_FLAG_IDLE)); + + if (LL_OK == spi_write_status) { + ret = ERROR; + } + } + + if (tx_buff) { + x_free(tx_buff); + } + + SPI_ClearStatus(spi, SPI_FLAG_CLR_ALL | SPI_FLAG_RX_BUF_FULL); + } + + if (spi_datacfg->spi_cs_release) { + GPIO_SetPins(cs_gpio_port, cs_gpio_pin); + } + + spi_datacfg = spi_datacfg->next; + } + + return ret; +} + +static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + uint8 cs_gpio_port = dev_param->spi_slave_param->spi_cs_gpio_port; + CM_SPI_TypeDef *spi = spi_dev->haldev.owner_bus->private_data; + + int i = 0; + int32 spi_read_status = 0; + uint32 spi_read_length = 0; + + while (NONE != spi_datacfg) { + if (spi_datacfg->spi_chip_select) { + GPIO_ResetPins(cs_gpio_port, cs_gpio_pin); + } + + if (spi_datacfg->length) { + uint8_t *rx_buff = x_malloc(spi_datacfg->length); + if ((spi_datacfg->rx_buff) && (rx_buff)) { + memset(rx_buff, 0xFF, spi_datacfg->length); + + HwSpiEnable(spi); + spi_read_status = SPI_Receive(spi, rx_buff, spi_datacfg->length, 1000); + + while (RESET != SPI_GetStatus(spi, SPI_FLAG_IDLE)); + if (LL_OK == spi_read_status) { + for (i = 0; i < spi_datacfg->length; i++) { + ((uint8_t *)spi_datacfg->rx_buff)[i] = rx_buff[i]; + } + } + } + if (rx_buff) { + x_free(rx_buff); + } + + SPI_ClearStatus(spi, SPI_FLAG_CLR_ALL | SPI_FLAG_RX_BUF_FULL); + } + + if (spi_datacfg->spi_cs_release) { + GPIO_SetPins(cs_gpio_port, cs_gpio_pin); + } + + spi_read_length += spi_datacfg->length; + spi_datacfg = spi_datacfg->next; + } + + return spi_read_length; +} + +/*manage the spi device operations*/ +static const struct SpiDevDone spi_dev_done = +{ + .dev_open = NONE, + .dev_close = NONE, + .dev_write = SpiWriteData, + .dev_read = SpiReadData, +}; + +static int BoardSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver, const char *bus_name, const char *drv_name) +{ + x_err_t ret = EOK; + + /*Init the spi bus */ + ret = SpiBusInit(spi_bus, bus_name); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiBusInit error %d\n", ret); + return ERROR; + } + + /*Init the spi driver*/ + ret = SpiDriverInit(spi_driver, drv_name); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the spi driver to the spi bus*/ + ret = SpiDriverAttachToBus(drv_name, bus_name); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the spi device to the spi bus*/ +static int BoardSpiDevBend(void) +{ + x_err_t ret = EOK; + +#ifdef SPI_1_DEVICE_NAME_0 + static struct SpiHardwareDevice spi1_device0; + memset(&spi1_device0, 0, sizeof(struct SpiHardwareDevice)); + + static struct SpiSlaveParam spi1_slaveparam0; + memset(&spi1_slaveparam0, 0, sizeof(struct SpiSlaveParam)); + + spi1_slaveparam0.spi_slave_id = SPI1_DEVICE_SLAVE_ID_0; + spi1_slaveparam0.spi_cs_gpio_pin = SPI1_SS_PIN; + spi1_slaveparam0.spi_cs_gpio_port = SPI1_SS_PORT; + + spi1_device0.spi_param.spi_slave_param = &spi1_slaveparam0; + + spi1_device0.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi1_device0, (void *)(&spi1_device0.spi_param), SPI_1_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("BoardSpiDevBend SpiDeviceRegister device %s error %d\n", SPI_1_DEVICE_NAME_0, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_0, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("BoardSpiDevBend SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_0, ret); + return ERROR; + } +#endif + +#ifdef SPI_6_DEVICE_NAME_0 + static struct SpiHardwareDevice spi6_device0; + memset(&spi6_device0, 0, sizeof(struct SpiHardwareDevice)); + + static struct SpiSlaveParam spi6_slaveparam0; + memset(&spi6_slaveparam0, 0, sizeof(struct SpiSlaveParam)); + + spi6_slaveparam0.spi_slave_id = SPI1_DEVICE_SLAVE_ID_0; + spi6_slaveparam0.spi_cs_gpio_pin = SPI6_SS_PIN; + spi6_slaveparam0.spi_cs_gpio_port = SPI6_SS_PORT; + + spi6_device0.spi_param.spi_slave_param = &spi6_slaveparam0; + + spi6_device0.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi6_device0, (void *)(&spi6_device0.spi_param), SPI_6_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("BoardSpiDevBend SpiDeviceRegister device %s error %d\n", SPI_6_DEVICE_NAME_0, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_6_DEVICE_NAME_0, SPI_BUS_NAME_6); + if (EOK != ret) { + KPrintf("BoardSpiDevBend SpiDeviceAttachToBus device %s error %d\n", SPI_6_DEVICE_NAME_0, ret); + return ERROR; + } +#endif + + return ret; +} + +int HwSpiInit(void) +{ + x_err_t ret = EOK; + +#ifdef BSP_USING_SPI1 + static struct SpiBus spi1_bus; + memset(&spi1_bus, 0, sizeof(struct SpiBus)); + + static struct SpiDriver spi1_driver; + memset(&spi1_driver, 0, sizeof(struct SpiDriver)); + + spi1_bus.private_data = SPI1_UNIT; + spi1_driver.configure = SpiDrvConfigure; + + ret = BoardSpiBusInit(&spi1_bus, &spi1_driver, SPI_BUS_NAME_1, SPI_1_DRV_NAME); + if (EOK != ret) { + KPrintf("BoardSpiBusInit error ret %u\n", ret); + return ERROR; + } + + ret = BoardSpiDevBend(); + if (EOK != ret) { + KPrintf("BoardSpiDevBend error ret %u\n", ret); + return ERROR; + } +#endif + +#ifdef BSP_USING_SPI6 + static struct SpiBus spi6_bus; + memset(&spi6_bus, 0, sizeof(struct SpiBus)); + + static struct SpiDriver spi6_driver; + memset(&spi6_driver, 0, sizeof(struct SpiDriver)); + + spi6_bus.private_data = SPI6_UNIT; + spi6_driver.configure = SpiDrvConfigure; + + ret = BoardSpiBusInit(&spi6_bus, &spi6_driver, SPI_BUS_NAME_6, SPI_6_DRV_NAME); + if (EOK != ret) { + KPrintf("BoardSpiBusInit error ret %u\n", ret); + return ERROR; + } + + ret = BoardSpiDevBend(); + if (EOK != ret) { + KPrintf("BoardSpiDevBend error ret %u\n", ret); + return ERROR; + } +#endif + + return ret; +} + +/*Just for lora test*/ +static struct Bus *bus; +static struct HardwareDev *dev; +static struct Driver *drv; + +static uint32 TestSpiLoraOpen(void) +{ + NULL_PARAM_CHECK(drv); + + KPrintf("SpiLoraOpen start\n"); + + x_err_t ret = EOK; + + struct BusConfigureInfo configure_info; + struct SpiMasterParam spi_master_param; + spi_master_param.spi_data_bit_width = 8; + spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB; + + configure_info.configure_cmd = OPE_CFG; + configure_info.private_data = (void *)&spi_master_param; + ret = BusDrvConfigure(drv, &configure_info); + if (ret) { + KPrintf("spi drv OPE_CFG error drv %8p cfg %8p\n", drv, &spi_master_param); + return ERROR; + } + + configure_info.configure_cmd = OPE_INT; + ret = BusDrvConfigure(drv, &configure_info); + if (ret) { + KPrintf("spi drv OPE_INT error drv %8p\n", drv); + return ERROR; + } + + return ret; +} + +static void TestSpiRead(void) +{ + struct BusBlockWriteParam write_param; + struct BusBlockReadParam read_param; + + uint8 write_addr = 0x06 & 0x7F; + uint8 read_data = 0; + + BusDevOpen(dev); + + write_param.buffer = (void *)&write_addr; + write_param.size = 1; + BusDevWriteData(dev, &write_param); + + read_param.buffer = (void *)&read_data; + read_param.size = 1; + BusDevReadData(dev, &read_param); + + BusDevClose(dev); + + KPrintf("read data from lora 0x06 register, receive data 0x%x\n", read_data); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + TestSpiRead, TestSpiRead, read data from lora register); + +void TestLoraOpen(void) +{ + x_err_t ret = EOK; + + bus = BusFind(SPI_BUS_NAME_1); + dev = BusFindDevice(bus, SPI_1_DEVICE_NAME_0); + drv = BusFindDriver(bus, SPI_1_DRV_NAME); + + bus->match(drv, dev); + + ret = TestSpiLoraOpen(); + if (EOK != ret) { + KPrintf("LoRa init failed\n"); + return; + } + + KPrintf("LoRa init succeed\n"); + + return; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + TestLoraOpen, TestLoraOpen, open lora device and read parameters); + + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/Makefile new file mode 100644 index 000000000..bd947913d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/Makefile @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_RESOURCES_SPI_LORA),y) + SRC_DIR := sx12xx +endif + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/Makefile new file mode 100644 index 000000000..d4ee439ce --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/Makefile @@ -0,0 +1,3 @@ +SRC_DIR := src + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/inc/spi_lora_sx12xx.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/inc/spi_lora_sx12xx.h new file mode 100644 index 000000000..df39d277c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/inc/spi_lora_sx12xx.h @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file spi_lora_sx12xx.h +* @brief define spi lora driver function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-31 +*/ + +#ifndef SPI_LORA_SX12XX_H +#define SPI_LORA_SX12XX_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +uint8_t SX1276ReadDio0(void); +uint8_t SX1276ReadDio1(void); +uint8_t SX1276ReadDio2(void); +uint8_t SX1276ReadDio3(void); +uint8_t SX1276ReadDio4(void); +uint8_t SX1276ReadDio5(void); + +void SX1276Write(uint8_t addr, uint8_t data); +void SX1276Read(uint8_t addr, uint8_t *data); +void SX1276WriteBuffer(uint8_t addr, uint8_t *buffer, uint8_t size); +void SX1276ReadBuffer(uint8_t addr, uint8_t *buffer, uint8_t size); +void SX1276WriteFifo(uint8_t *buffer, uint8_t size); +void SX1276ReadFifo(uint8_t *buffer, uint8_t size); +void SX1276SetReset(uint8_t state); +uint8_t Sx1276SpiCheck(void); +void SX1276WriteRxTx(uint8_t txEnable); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/Makefile new file mode 100644 index 000000000..ace186b70 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/Makefile @@ -0,0 +1,3 @@ +SRC_DIR := radio + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/Makefile new file mode 100644 index 000000000..4cc90adb8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := radio.c sx1276-Fsk.c sx1276-FskMisc.c sx1276-LoRa.c sx1276-LoRaMisc.c sx1276.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/platform.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/platform.h new file mode 100644 index 000000000..cb4bff6d5 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/platform.h @@ -0,0 +1,96 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file platform.h + * \brief + * + * \version 1.0 + * \date Nov 21 2012 + * \author Miguel Luis + */ +/************************************************* +File name: platform.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ +#ifndef __PLATFORM_H__ +#define __PLATFORM_H__ + +#ifndef __GNUC__ +#define inline +#endif + +/*! + * Platform definition + */ +#define Bleeper 3 +#define SX1243ska 2 +#define SX12xxEiger 1 +#define SX12000DVK 0 + +/*! + * Platform choice. Please uncoment the PLATFORM define and choose your platform + * or add/change the PLATFORM definition on the compiler Defines option + */ +#define PLATFORM SX12xxEiger + +#if( PLATFORM == SX12xxEiger ) +/*! + * Radio choice. Please uncomment the wanted radio and comment the others + * or add/change wanted radio definition on the compiler Defines option + */ +//#define USE_SX1232_RADIO +//#define USE_SX1272_RADIO +#define USE_SX1276_RADIO +//#define USE_SX1243_RADIO + +/*! + * Module choice. There are three existing module with the SX1276. + * Please set the connected module to the value 1 and set the others to 0 + */ +#ifdef USE_SX1276_RADIO +#define MODULE_SX1276RF1IAS 0 +#define MODULE_SX1276RF1JAS 0 +#define MODULE_SX1276RF1KAS 1 +#endif + +#include +#define USE_UART 0 + +#elif( PLATFORM == SX12000DVK ) +/*! + * Radio choice. Please uncomment the wanted radio and comment the others + * or add/change wanted radio definition on the compiler Defines option + */ +//#define USE_SX1232_RADIO +#define USE_SX1272_RADIO +//#define USE_SX1276_RADIO +//#define USE_SX1243_RADIO + + #include "sx1200dvk/sx1200dvk.h" + +#elif( PLATFORM == SX1243ska ) + +#elif( PLATFORM == Bleeper ) + #define USE_SX1272_RADIO + + #include "bleeper/bleeper.h" + #define USE_UART 0 + +#else + #error "Missing define: Platform (ie. SX12xxEiger)" +#endif + +#endif // __PLATFORM_H__ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.c new file mode 100644 index 000000000..31f8aaebd --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.c @@ -0,0 +1,75 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file radio.c + * \brief Generic radio driver ( radio abstraction ) + * + * \version 2.0.0 + * \date Nov 21 2012 + * \author Miguel Luis + * + * Last modified by Gregory Cristian on Apr 25 2013 + */ +/************************************************* +File name: radio.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ +#include +#include "platform.h" +#include "radio.h" + +#if defined( USE_SX1232_RADIO ) + #include "sx1232.h" +#elif defined( USE_SX1272_RADIO ) + #include "sx1272.h" +#elif defined( USE_SX1276_RADIO ) + #include "sx1276.h" +#else + #error "Missing define: USE_XXXXXX_RADIO (ie. USE_SX1272_RADIO)" +#endif + +tRadioDriver RadioDriver; + +tRadioDriver* RadioDriverInit( void ) +{ +#if defined( USE_SX1232_RADIO ) + RadioDriver.Init = SX1232Init; + RadioDriver.Reset = SX1232Reset; + RadioDriver.StartRx = SX1232StartRx; + RadioDriver.GetRxPacket = SX1232GetRxPacket; + RadioDriver.SetTxPacket = SX1232SetTxPacket; + RadioDriver.Process = SX1232Process; +#elif defined( USE_SX1272_RADIO ) + RadioDriver.Init = SX1272Init; + RadioDriver.Reset = SX1272Reset; + RadioDriver.StartRx = SX1272StartRx; + RadioDriver.GetRxPacket = SX1272GetRxPacket; + RadioDriver.SetTxPacket = SX1272SetTxPacket; + RadioDriver.Process = SX1272Process; +#elif defined( USE_SX1276_RADIO ) + RadioDriver.Init = SX1276Init; + RadioDriver.Reset = SX1276Reset; + RadioDriver.StartRx = SX1276StartRx; + RadioDriver.GetRxPacket = SX1276GetRxPacket; + RadioDriver.SetTxPacket = SX1276SetTxPacket; + RadioDriver.Process = SX1276Process; + RadioDriver.ChannelEmpty = SX1276ChannelEmpty; +#else + #error "Missing define: USE_XXXXXX_RADIO (ie. USE_SX1272_RADIO)" +#endif + + return &RadioDriver; +} diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.h new file mode 100644 index 000000000..04749ebd5 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.h @@ -0,0 +1,77 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file radio.h + * \brief Generic radio driver ( radio abstraction ) + * + * \version 2.0.B2 + * \date Nov 21 2012 + * \author Miguel Luis + * + * Last modified by Gregory Cristian on Apr 25 2013 + */ +/************************************************* +File name: radio.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#ifndef __RADIO_H__ +#define __RADIO_H__ + +/*! + * SX1272 and SX1276 General parameters definition + */ +#define LORA 1 // [0: OFF, 1: ON] + +/*! + * RF process function return codes + */ +typedef enum +{ + RF_IDLE, + RF_BUSY, + RF_RX_DONE, + RF_RX_TIMEOUT, + RF_TX_DONE, + RF_TX_TIMEOUT, + RF_LEN_ERROR, + RF_CHANNEL_EMPTY, + RF_CHANNEL_ACTIVITY_DETECTED, +}tRFProcessReturnCodes; + +/*! + * Radio driver structure defining the different function pointers + */ +typedef struct sRadioDriver +{ + void ( *Init )( void ); + void ( *Reset )( void ); + void ( *StartRx )( void ); + void ( *GetRxPacket )( void *buffer, uint16_t *size ); + void ( *SetTxPacket )( const void *buffer, uint16_t size ); + uint32_t ( *Process )( void ); + uint32_t ( *ChannelEmpty )(void ); +}tRadioDriver; + +/*! + * \brief Initializes the RadioDriver structure with specific radio + * functions. + * + * \retval radioDriver Pointer to the radio driver variable + */ +tRadioDriver* RadioDriverInit( void ); + +#endif // __RADIO_H__ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.c new file mode 100644 index 000000000..4d89b60cd --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.c @@ -0,0 +1,616 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276.c + * \brief SX1276 RF chip driver + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-Fsk.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#include +#include + +#include "platform.h" + +#if defined( USE_SX1276_RADIO ) + +#include "radio.h" + +#include "sx1276-Hal.h" +#include "sx1276.h" + +#include "sx1276-FskMisc.h" +#include "sx1276-Fsk.h" + +// Default settings +tFskSettings FskSettings = +{ + 870000000, // RFFrequency + 9600, // Bitrate + 50000, // Fdev + 20, // Power + 100000, // RxBw + 150000, // RxBwAfc + true, // CrcOn + true, // AfcOn + 255 // PayloadLength (set payload size to the maximum for variable mode, else set the exact payload length) +}; + +/*! + * SX1276 FSK registers variable + */ +tSX1276* SX1276; + +/*! + * Local RF buffer for communication support + */ +static uint8_t RFBuffer[RF_BUFFER_SIZE]; + +/*! + * Chunk size of data write in buffer + */ +static uint8_t DataChunkSize = 32; + + +/*! + * RF state machine variable + */ +static uint8_t RFState = RF_STATE_IDLE; + +/*! + * Rx management support variables + */ + +/*! + * PacketTimeout holds the RF packet timeout + * SyncSize = [0..8] + * VariableSize = [0;1] + * AddressSize = [0;1] + * PayloadSize = [0..RF_BUFFER_SIZE] + * CrcSize = [0;2] + * PacketTimeout = ( ( 8 * ( VariableSize + AddressSize + PayloadSize + CrcSize ) / BR ) * 1000.0 ) + 1 + * Computed timeout is in miliseconds + */ +static uint32_t PacketTimeout; + +/*! + * Preamble2SyncTimeout + * Preamble2SyncTimeout = ( ( 8 * ( PremableSize + SyncSize ) / RFBitrate ) * 1000.0 ) + 1 + * Computed timeout is in miliseconds + */ +static uint32_t Preamble2SyncTimeout; + +static bool PreambleDetected = false; +static bool SyncWordDetected = false; +static bool PacketDetected = false; +static uint16_t RxPacketSize = 0; +static uint8_t RxBytesRead = 0; +static uint8_t TxBytesSent = 0; +static double RxPacketRssiValue; +static uint32_t RxPacketAfcValue; +static uint8_t RxGain = 1; +static uint32_t RxTimeoutTimer = 0; +static uint32_t Preamble2SyncTimer = 0; + +/*! + * Tx management support variables + */ +static uint16_t TxPacketSize = 0; +static uint32_t TxTimeoutTimer = 0; + +void SX1276FskInit( void ) +{ + RFState = RF_STATE_IDLE; + + SX1276FskSetDefaults( ); + + SX1276ReadBuffer( REG_OPMODE, SX1276Regs + 1, 0x70 - 1 ); + + // Set the device in FSK mode and Sleep Mode + SX1276->RegOpMode = RF_OPMODE_MODULATIONTYPE_FSK | RF_OPMODE_SLEEP; + SX1276Write( REG_OPMODE, SX1276->RegOpMode ); + + SX1276->RegPaRamp = RF_PARAMP_MODULATIONSHAPING_01; + SX1276Write( REG_PARAMP, SX1276->RegPaRamp ); + + SX1276->RegLna = RF_LNA_GAIN_G1; + SX1276Write( REG_LNA, SX1276->RegLna ); + + if( FskSettings.AfcOn == true ) + { + SX1276->RegRxConfig = RF_RXCONFIG_RESTARTRXONCOLLISION_OFF | RF_RXCONFIG_AFCAUTO_ON | + RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT; + } + else + { + SX1276->RegRxConfig = RF_RXCONFIG_RESTARTRXONCOLLISION_OFF | RF_RXCONFIG_AFCAUTO_OFF | + RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT; + } + + SX1276->RegPreambleLsb = 8; + + SX1276->RegPreambleDetect = RF_PREAMBLEDETECT_DETECTOR_ON | RF_PREAMBLEDETECT_DETECTORSIZE_2 | + RF_PREAMBLEDETECT_DETECTORTOL_10; + + SX1276->RegRssiThresh = 0xFF; + + SX1276->RegSyncConfig = RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON | RF_SYNCCONFIG_PREAMBLEPOLARITY_AA | + RF_SYNCCONFIG_SYNC_ON | + RF_SYNCCONFIG_SYNCSIZE_4; + + SX1276->RegSyncValue1 = 0x69; + SX1276->RegSyncValue2 = 0x81; + SX1276->RegSyncValue3 = 0x7E; + SX1276->RegSyncValue4 = 0x96; + + SX1276->RegPacketConfig1 = RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE | RF_PACKETCONFIG1_DCFREE_OFF | + ( FskSettings.CrcOn << 4 ) | RF_PACKETCONFIG1_CRCAUTOCLEAR_ON | + RF_PACKETCONFIG1_ADDRSFILTERING_OFF | RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT; + SX1276FskGetPacketCrcOn( ); // Update CrcOn on FskSettings + + SX1276->RegPayloadLength = FskSettings.PayloadLength; + + // we can now update the registers with our configuration + SX1276WriteBuffer( REG_OPMODE, SX1276Regs + 1, 0x70 - 1 ); + + // then we need to set the RF settings + SX1276FskSetRFFrequency( FskSettings.RFFrequency ); + SX1276FskSetBitrate( FskSettings.Bitrate ); + SX1276FskSetFdev( FskSettings.Fdev ); + + SX1276FskSetDccBw( &SX1276->RegRxBw, 0, FskSettings.RxBw ); + SX1276FskSetDccBw( &SX1276->RegAfcBw, 0, FskSettings.RxBwAfc ); + SX1276FskSetRssiOffset( 0 ); + +#if( ( MODULE_SX1276RF1IAS == 1 ) || ( MODULE_SX1276RF1KAS == 1 ) ) + if( FskSettings.RFFrequency > 860000000 ) + { + SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_RFO ); + SX1276FskSetPa20dBm( false ); + FskSettings.Power = 14; + SX1276FskSetRFPower( FskSettings.Power ); + } + else + { + SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_PABOOST ); + SX1276FskSetPa20dBm( true ); + FskSettings.Power = 20; + SX1276FskSetRFPower( FskSettings.Power ); + } +#elif( MODULE_SX1276RF1JAS == 1 ) + if( FskSettings.RFFrequency > 860000000 ) + { + SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_PABOOST ); + SX1276FskSetPa20dBm( true ); + FskSettings.Power = 20; + SX1276FskSetRFPower( FskSettings.Power ); + } + else + { + SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_RFO ); + SX1276FskSetPa20dBm( false ); + FskSettings.Power = 14; + SX1276FskSetRFPower( FskSettings.Power ); + } +#endif + + SX1276FskSetOpMode( RF_OPMODE_STANDBY ); + + // Calibrate the HF + SX1276FskRxCalibrate( ); +} + +void SX1276FskSetDefaults( void ) +{ + // REMARK: See SX1276 datasheet for modified default values. + + SX1276Read( REG_VERSION, &SX1276->RegVersion ); +} + +void SX1276FskSetOpMode( uint8_t opMode ) +{ + static uint8_t opModePrev = RF_OPMODE_STANDBY; + static bool antennaSwitchTxOnPrev = true; + bool antennaSwitchTxOn = false; + + opModePrev = SX1276->RegOpMode & ~RF_OPMODE_MASK; + + if( opMode != opModePrev ) + { + if( opMode == RF_OPMODE_TRANSMITTER ) + { + antennaSwitchTxOn = true; + } + else + { + antennaSwitchTxOn = false; + } + if( antennaSwitchTxOn != antennaSwitchTxOnPrev ) + { + antennaSwitchTxOnPrev = antennaSwitchTxOn; + RXTX( antennaSwitchTxOn ); // Antenna switch control + } + SX1276->RegOpMode = ( SX1276->RegOpMode & RF_OPMODE_MASK ) | opMode; + + SX1276Write( REG_OPMODE, SX1276->RegOpMode ); + } +} + +uint8_t SX1276FskGetOpMode( void ) +{ + SX1276Read( REG_OPMODE, &SX1276->RegOpMode ); + + return SX1276->RegOpMode & ~RF_OPMODE_MASK; +} + +int32_t SX1276FskReadFei( void ) +{ + SX1276ReadBuffer( REG_FEIMSB, &SX1276->RegFeiMsb, 2 ); // Reads the FEI value + + return ( int32_t )( double )( ( ( uint16_t )SX1276->RegFeiMsb << 8 ) | ( uint16_t )SX1276->RegFeiLsb ) * ( double )FREQ_STEP; +} + +int32_t SX1276FskReadAfc( void ) +{ + SX1276ReadBuffer( REG_AFCMSB, &SX1276->RegAfcMsb, 2 ); // Reads the AFC value + return ( int32_t )( double )( ( ( uint16_t )SX1276->RegAfcMsb << 8 ) | ( uint16_t )SX1276->RegAfcLsb ) * ( double )FREQ_STEP; +} + +uint8_t SX1276FskReadRxGain( void ) +{ + SX1276Read( REG_LNA, &SX1276->RegLna ); + return( SX1276->RegLna >> 5 ) & 0x07; +} + +double SX1276FskReadRssi( void ) +{ + SX1276Read( REG_RSSIVALUE, &SX1276->RegRssiValue ); // Reads the RSSI value + + return -( double )( ( double )SX1276->RegRssiValue / 2.0 ); +} + +uint8_t SX1276FskGetPacketRxGain( void ) +{ + return RxGain; +} + +double SX1276FskGetPacketRssi( void ) +{ + return RxPacketRssiValue; +} + +uint32_t SX1276FskGetPacketAfc( void ) +{ + return RxPacketAfcValue; +} + +void SX1276FskStartRx( void ) +{ + SX1276FskSetRFState( RF_STATE_RX_INIT ); +} + +void SX1276FskGetRxPacket( void *buffer, uint16_t *size ) +{ + *size = RxPacketSize; + RxPacketSize = 0; + memcpy( ( void * )buffer, ( void * )RFBuffer, ( size_t )*size ); +} + +void SX1276FskSetTxPacket( const void *buffer, uint16_t size ) +{ + TxPacketSize = size; + memcpy( ( void * )RFBuffer, buffer, ( size_t )TxPacketSize ); + + RFState = RF_STATE_TX_INIT; +} + +// Remark: SX1276 must be fully initialized before calling this function +uint16_t SX1276FskGetPacketPayloadSize( void ) +{ + uint16_t syncSize; + uint16_t variableSize; + uint16_t addressSize; + uint16_t payloadSize; + uint16_t crcSize; + + syncSize = ( SX1276->RegSyncConfig & 0x07 ) + 1; + variableSize = ( ( SX1276->RegPacketConfig1 & 0x80 ) == 0x80 ) ? 1 : 0; + addressSize = ( ( SX1276->RegPacketConfig1 & 0x06 ) != 0x00 ) ? 1 : 0; + payloadSize = SX1276->RegPayloadLength; + crcSize = ( ( SX1276->RegPacketConfig1 & 0x10 ) == 0x10 ) ? 2 : 0; + + return syncSize + variableSize + addressSize + payloadSize + crcSize; +} + +// Remark: SX1276 must be fully initialized before calling this function +uint16_t SX1276FskGetPacketHeaderSize( void ) +{ + uint16_t preambleSize; + uint16_t syncSize; + + preambleSize = ( ( uint16_t )SX1276->RegPreambleMsb << 8 ) | ( uint16_t )SX1276->RegPreambleLsb; + syncSize = ( SX1276->RegSyncConfig & 0x07 ) + 1; + + return preambleSize + syncSize; +} + +uint8_t SX1276FskGetRFState( void ) +{ + return RFState; +} + +void SX1276FskSetRFState( uint8_t state ) +{ + RFState = state; +} + +uint32_t SX1276FskProcess( void ) +{ + uint32_t result = RF_BUSY; + + switch( RFState ) + { + case RF_STATE_IDLE: + break; + // Rx management + case RF_STATE_RX_INIT: + // DIO mapping setup + if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_ON ) == RF_PACKETCONFIG1_CRC_ON ) + { + // CrcOk, FifoLevel, SyncAddr, FifoEmpty + SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_01 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_11 | RF_DIOMAPPING1_DIO3_00; + } + else + { + // PayloadReady, FifoLevel, SyncAddr, FifoEmpty + SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_11 | RF_DIOMAPPING1_DIO3_00; + } + // Preamble, Data + SX1276->RegDioMapping2 = RF_DIOMAPPING2_DIO4_11 | RF_DIOMAPPING2_DIO5_10 | RF_DIOMAPPING2_MAP_PREAMBLEDETECT; + SX1276WriteBuffer( REG_DIOMAPPING1, &SX1276->RegDioMapping1, 2 ); + + SX1276FskSetOpMode( RF_OPMODE_RECEIVER ); + + memset( RFBuffer, 0, ( size_t )RF_BUFFER_SIZE ); + + PacketTimeout = ( uint16_t )( round( ( 8.0 * ( ( double )SX1276FskGetPacketPayloadSize( ) ) / ( double )FskSettings.Bitrate ) * 1000.0 ) + 1.0 ); + PacketTimeout = PacketTimeout + ( PacketTimeout >> 1 ); // Set the Packet timeout as 1.5 times the full payload transmission time + + Preamble2SyncTimeout = PacketTimeout; + + Preamble2SyncTimer = RxTimeoutTimer = GET_TICK_COUNT( ); + + SX1276->RegFifoThresh = RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY | 0x20; // 32 bytes of data + SX1276Write( REG_FIFOTHRESH, SX1276->RegFifoThresh ); + + PreambleDetected = false; + SyncWordDetected = false; + PacketDetected = false; + RxBytesRead = 0; + RxPacketSize = 0; + RFState = RF_STATE_RX_SYNC; + break; + case RF_STATE_RX_SYNC: + if( ( DIO4 == 1 ) && ( PreambleDetected == false ) )// Preamble + { + PreambleDetected = true; + Preamble2SyncTimer = GET_TICK_COUNT( ); + } + if( ( DIO2 == 1 ) && ( PreambleDetected == true ) && ( SyncWordDetected == false ) ) // SyncAddr + { + SyncWordDetected = true; + + RxPacketRssiValue = SX1276FskReadRssi( ); + + RxPacketAfcValue = SX1276FskReadAfc( ); + RxGain = SX1276FskReadRxGain( ); + + Preamble2SyncTimer = RxTimeoutTimer = GET_TICK_COUNT( ); + + RFState = RF_STATE_RX_RUNNING; + } + + // Preamble 2 SyncAddr timeout + if( ( SyncWordDetected == false ) && ( PreambleDetected == true ) && ( ( GET_TICK_COUNT( ) - Preamble2SyncTimer ) > Preamble2SyncTimeout ) ) + { + RFState = RF_STATE_RX_INIT; + SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK ); + } + if( ( SyncWordDetected == false ) && + ( PreambleDetected == false ) && + ( PacketDetected == false ) && + ( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ) ) + { + RFState = RF_STATE_RX_TIMEOUT; + } + break; + case RF_STATE_RX_RUNNING: + if( RxPacketSize > RF_BUFFER_SIZE_MAX ) + { + RFState = RF_STATE_RX_LEN_ERROR; + break; + } +#if 1 + if( DIO1 == 1 ) // FifoLevel + { + if( ( RxPacketSize == 0 ) && ( RxBytesRead == 0 ) ) // Read received packet size + { + if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) + { + SX1276ReadFifo( ( uint8_t* )&RxPacketSize, 1 ); + } + else + { + RxPacketSize = SX1276->RegPayloadLength; + } + } + + if( ( RxPacketSize - RxBytesRead ) > ( SX1276->RegFifoThresh & 0x3F ) ) + { + SX1276ReadFifo( ( RFBuffer + RxBytesRead ), ( SX1276->RegFifoThresh & 0x3F ) ); + RxBytesRead += ( SX1276->RegFifoThresh & 0x3F ); + } + else + { + SX1276ReadFifo( ( RFBuffer + RxBytesRead ), RxPacketSize - RxBytesRead ); + RxBytesRead += ( RxPacketSize - RxBytesRead ); + } + } +#endif + if( DIO0 == 1 ) // PayloadReady/CrcOk + { + RxTimeoutTimer = GET_TICK_COUNT( ); + if( ( RxPacketSize == 0 ) && ( RxBytesRead == 0 ) ) // Read received packet size + { + if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) + { + SX1276ReadFifo( ( uint8_t* )&RxPacketSize, 1 ); + } + else + { + RxPacketSize = SX1276->RegPayloadLength; + } + SX1276ReadFifo( RFBuffer + RxBytesRead, RxPacketSize - RxBytesRead ); + RxBytesRead += ( RxPacketSize - RxBytesRead ); + PacketDetected = true; + RFState = RF_STATE_RX_DONE; + } + else + { + SX1276ReadFifo( RFBuffer + RxBytesRead, RxPacketSize - RxBytesRead ); + RxBytesRead += ( RxPacketSize - RxBytesRead ); + PacketDetected = true; + RFState = RF_STATE_RX_DONE; + } + } + + // Packet timeout + if( ( PacketDetected == false ) && ( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ) ) + { + RFState = RF_STATE_RX_TIMEOUT; + } + break; + case RF_STATE_RX_DONE: + RxBytesRead = 0; + RFState = RF_STATE_RX_INIT; + result = RF_RX_DONE; + break; + case RF_STATE_RX_TIMEOUT: + RxBytesRead = 0; + RxPacketSize = 0; + SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK ); + RFState = RF_STATE_RX_INIT; + result = RF_RX_TIMEOUT; + break; + case RF_STATE_RX_LEN_ERROR: + RxBytesRead = 0; + RxPacketSize = 0; + SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK ); + RFState = RF_STATE_RX_INIT; + result = RF_LEN_ERROR; + break; + // Tx management + case RF_STATE_TX_INIT: + // Packet DIO mapping setup + // PacketSent, FifoLevel, FifoFull, TxReady + SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_00 | RF_DIOMAPPING1_DIO3_01; + // LowBat, Data + SX1276->RegDioMapping2 = RF_DIOMAPPING2_DIO4_00 | RF_DIOMAPPING2_DIO5_10; + SX1276WriteBuffer( REG_DIOMAPPING1, &SX1276->RegDioMapping1, 2 ); + + SX1276->RegFifoThresh = RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY | 0x18; // 24 bytes of data + SX1276Write( REG_FIFOTHRESH, SX1276->RegFifoThresh ); + + SX1276FskSetOpMode( RF_OPMODE_TRANSMITTER ); + RFState = RF_STATE_TX_READY_WAIT; + TxBytesSent = 0; + break; + case RF_STATE_TX_READY_WAIT: + if( DIO3 == 1 ) // TxReady + { + if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) + { + SX1276WriteFifo( ( uint8_t* )&TxPacketSize, 1 ); + } + + if( ( TxPacketSize > 0 ) && ( TxPacketSize <= 64 ) ) + { + DataChunkSize = TxPacketSize; + } + else + { + DataChunkSize = 32; + } + + SX1276WriteFifo( RFBuffer, DataChunkSize ); + TxBytesSent += DataChunkSize; + TxTimeoutTimer = GET_TICK_COUNT( ); + RFState = RF_STATE_TX_RUNNING; + } + break; + + case RF_STATE_TX_RUNNING: + if( DIO1 == 0 ) // FifoLevel below thresold + { + if( ( TxPacketSize - TxBytesSent ) > DataChunkSize ) + { + SX1276WriteFifo( ( RFBuffer + TxBytesSent ), DataChunkSize ); + TxBytesSent += DataChunkSize; + } + else + { + // we write the last chunk of data + SX1276WriteFifo( RFBuffer + TxBytesSent, TxPacketSize - TxBytesSent ); + TxBytesSent += TxPacketSize - TxBytesSent; + } + } + + if( DIO0 == 1 ) // PacketSent + { + TxTimeoutTimer = GET_TICK_COUNT( ); + RFState = RF_STATE_TX_DONE; + SX1276FskSetOpMode( RF_OPMODE_STANDBY ); + } + + // Packet timeout + if( ( GET_TICK_COUNT( ) - TxTimeoutTimer ) > TICK_RATE_MS( 1000 ) ) + { + RFState = RF_STATE_TX_TIMEOUT; + } + break; + case RF_STATE_TX_DONE: + RFState = RF_STATE_IDLE; + result = RF_TX_DONE; + break; + case RF_STATE_TX_TIMEOUT: + RFState = RF_STATE_IDLE; + result = RF_TX_TIMEOUT; + break; + default: + break; + } + return result; +} + +#endif // USE_SX1276_RADIO diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.h new file mode 100644 index 000000000..21502bf72 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.h @@ -0,0 +1,1471 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276-Fsk.h + * \brief SX1276 RF chip driver mode FSK + * + * \version 2.0.B2 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-Fsk.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ +#ifndef __SX1276_FSK_H__ +#define __SX1276_FSK_H__ + +#include "stdint.h" +#include "stdbool.h" +/*! + * SX1276 FSK General parameters definition + */ + +typedef struct sFskSettings +{ + uint32_t RFFrequency; + uint32_t Bitrate; + uint32_t Fdev; + int8_t Power; + uint32_t RxBw; + uint32_t RxBwAfc; + bool CrcOn; + bool AfcOn; + uint8_t PayloadLength; +}tFskSettings; + +/*! + * RF packet definition + */ +#define RF_BUFFER_SIZE_MAX 256 +#define RF_BUFFER_SIZE 256 + +/*! + * RF state machine + */ +// FSK +typedef enum +{ + RF_STATE_IDLE, + RF_STATE_RX_INIT, + RF_STATE_RX_SYNC, + RF_STATE_RX_RUNNING, + RF_STATE_RX_DONE, + RF_STATE_RX_TIMEOUT, + RF_STATE_RX_LEN_ERROR, + RF_STATE_TX_INIT, + RF_STATE_TX_READY_WAIT, + RF_STATE_TX_RUNNING, + RF_STATE_TX_DONE, + RF_STATE_TX_TIMEOUT, +}tRFStates; + +/*! + * SX1276 definitions + */ +#define XTAL_FREQ 32000000 +#define FREQ_STEP 61.03515625 + +/*! + * SX1276 Internal registers Address + */ +#define REG_FIFO 0x00 +// Common settings +#define REG_OPMODE 0x01 +#define REG_BITRATEMSB 0x02 +#define REG_BITRATELSB 0x03 +#define REG_FDEVMSB 0x04 +#define REG_FDEVLSB 0x05 +#define REG_FRFMSB 0x06 +#define REG_FRFMID 0x07 +#define REG_FRFLSB 0x08 +// Tx settings +#define REG_PACONFIG 0x09 +#define REG_PARAMP 0x0A +#define REG_OCP 0x0B +// Rx settings +#define REG_LNA 0x0C +#define REG_RXCONFIG 0x0D +#define REG_RSSICONFIG 0x0E +#define REG_RSSICOLLISION 0x0F +#define REG_RSSITHRESH 0x10 +#define REG_RSSIVALUE 0x11 +#define REG_RXBW 0x12 +#define REG_AFCBW 0x13 +#define REG_OOKPEAK 0x14 +#define REG_OOKFIX 0x15 +#define REG_OOKAVG 0x16 +#define REG_RES17 0x17 +#define REG_RES18 0x18 +#define REG_RES19 0x19 +#define REG_AFCFEI 0x1A +#define REG_AFCMSB 0x1B +#define REG_AFCLSB 0x1C +#define REG_FEIMSB 0x1D +#define REG_FEILSB 0x1E +#define REG_PREAMBLEDETECT 0x1F +#define REG_RXTIMEOUT1 0x20 +#define REG_RXTIMEOUT2 0x21 +#define REG_RXTIMEOUT3 0x22 +#define REG_RXDELAY 0x23 +// Oscillator settings +#define REG_OSC 0x24 +// Packet handler settings +#define REG_PREAMBLEMSB 0x25 +#define REG_PREAMBLELSB 0x26 +#define REG_SYNCCONFIG 0x27 +#define REG_SYNCVALUE1 0x28 +#define REG_SYNCVALUE2 0x29 +#define REG_SYNCVALUE3 0x2A +#define REG_SYNCVALUE4 0x2B +#define REG_SYNCVALUE5 0x2C +#define REG_SYNCVALUE6 0x2D +#define REG_SYNCVALUE7 0x2E +#define REG_SYNCVALUE8 0x2F +#define REG_PACKETCONFIG1 0x30 +#define REG_PACKETCONFIG2 0x31 +#define REG_PAYLOADLENGTH 0x32 +#define REG_NODEADRS 0x33 +#define REG_BROADCASTADRS 0x34 +#define REG_FIFOTHRESH 0x35 +// SM settings +#define REG_SEQCONFIG1 0x36 +#define REG_SEQCONFIG2 0x37 +#define REG_TIMERRESOL 0x38 +#define REG_TIMER1COEF 0x39 +#define REG_TIMER2COEF 0x3A +// Service settings +#define REG_IMAGECAL 0x3B +#define REG_TEMP 0x3C +#define REG_LOWBAT 0x3D +// Status +#define REG_IRQFLAGS1 0x3E +#define REG_IRQFLAGS2 0x3F +// I/O settings +#define REG_DIOMAPPING1 0x40 +#define REG_DIOMAPPING2 0x41 +// Version +#define REG_VERSION 0x42 +// Additional settings +#define REG_PLLHOP 0x44 +#define REG_TCXO 0x4B +#define REG_PADAC 0x4D +#define REG_FORMERTEMP 0x5B +#define REG_BITRATEFRAC 0x5D +#define REG_AGCREF 0x61 +#define REG_AGCTHRESH1 0x62 +#define REG_AGCTHRESH2 0x63 +#define REG_AGCTHRESH3 0x64 + + +/*! + * SX1276 FSK bit control definition + */ + +/*! + * RegFifo + */ + +/*! + * RegOpMode + */ +#define RF_OPMODE_LONGRANGEMODE_MASK 0x7F +#define RF_OPMODE_LONGRANGEMODE_OFF 0x00 // Default +#define RF_OPMODE_LONGRANGEMODE_ON 0x80 + +#define RF_OPMODE_MODULATIONTYPE_MASK 0x9F +#define RF_OPMODE_MODULATIONTYPE_FSK 0x00 // Default +#define RF_OPMODE_MODULATIONTYPE_OOK 0x20 + +#define RF_OPMODE_FREQMODE_ACCESS_MASK 0xF7 +#define RF_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default +#define RF_OPMODE_FREQMODE_ACCESS_HF 0x00 + +#define RF_OPMODE_MASK 0xF8 +#define RF_OPMODE_SLEEP 0x00 +#define RF_OPMODE_STANDBY 0x01 // Default +#define RF_OPMODE_SYNTHESIZER_TX 0x02 +#define RF_OPMODE_TRANSMITTER 0x03 +#define RF_OPMODE_SYNTHESIZER_RX 0x04 +#define RF_OPMODE_RECEIVER 0x05 + +/*! + * RegBitRate (bits/sec) + */ +#define RF_BITRATEMSB_1200_BPS 0x68 +#define RF_BITRATELSB_1200_BPS 0x2B +#define RF_BITRATEMSB_2400_BPS 0x34 +#define RF_BITRATELSB_2400_BPS 0x15 +#define RF_BITRATEMSB_4800_BPS 0x1A // Default +#define RF_BITRATELSB_4800_BPS 0x0B // Default +#define RF_BITRATEMSB_9600_BPS 0x0D +#define RF_BITRATELSB_9600_BPS 0x05 +#define RF_BITRATEMSB_15000_BPS 0x08 +#define RF_BITRATELSB_15000_BPS 0x55 +#define RF_BITRATEMSB_19200_BPS 0x06 +#define RF_BITRATELSB_19200_BPS 0x83 +#define RF_BITRATEMSB_38400_BPS 0x03 +#define RF_BITRATELSB_38400_BPS 0x41 +#define RF_BITRATEMSB_76800_BPS 0x01 +#define RF_BITRATELSB_76800_BPS 0xA1 +#define RF_BITRATEMSB_153600_BPS 0x00 +#define RF_BITRATELSB_153600_BPS 0xD0 +#define RF_BITRATEMSB_57600_BPS 0x02 +#define RF_BITRATELSB_57600_BPS 0x2C +#define RF_BITRATEMSB_115200_BPS 0x01 +#define RF_BITRATELSB_115200_BPS 0x16 +#define RF_BITRATEMSB_12500_BPS 0x0A +#define RF_BITRATELSB_12500_BPS 0x00 +#define RF_BITRATEMSB_25000_BPS 0x05 +#define RF_BITRATELSB_25000_BPS 0x00 +#define RF_BITRATEMSB_50000_BPS 0x02 +#define RF_BITRATELSB_50000_BPS 0x80 +#define RF_BITRATEMSB_100000_BPS 0x01 +#define RF_BITRATELSB_100000_BPS 0x40 +#define RF_BITRATEMSB_150000_BPS 0x00 +#define RF_BITRATELSB_150000_BPS 0xD5 +#define RF_BITRATEMSB_200000_BPS 0x00 +#define RF_BITRATELSB_200000_BPS 0xA0 +#define RF_BITRATEMSB_250000_BPS 0x00 +#define RF_BITRATELSB_250000_BPS 0x80 +#define RF_BITRATEMSB_32768_BPS 0x03 +#define RF_BITRATELSB_32768_BPS 0xD1 + +/*! + * RegFdev (Hz) + */ + +#define RF_FDEVMSB_BANDREG_MASK 0x3F +#define RF_FDEVMSB_BANDREG_AUTO 0x00 // Default +#define RF_FDEVMSB_BANDREG_DIV_BY_1 0x40 +#define RF_FDEVMSB_BANDREG_DIV_BY_2 0x80 +#define RF_FDEVMSB_BANDREG_DIV_BY_6 0xC0 + +#define RF_FDEVMSB_FDEV_MASK 0xC0 + +#define RF_FDEVMSB_2000_HZ 0x00 +#define RF_FDEVLSB_2000_HZ 0x21 +#define RF_FDEVMSB_5000_HZ 0x00 // Default +#define RF_FDEVLSB_5000_HZ 0x52 // Default +#define RF_FDEVMSB_10000_HZ 0x00 +#define RF_FDEVLSB_10000_HZ 0xA4 +#define RF_FDEVMSB_15000_HZ 0x00 +#define RF_FDEVLSB_15000_HZ 0xF6 +#define RF_FDEVMSB_20000_HZ 0x01 +#define RF_FDEVLSB_20000_HZ 0x48 +#define RF_FDEVMSB_25000_HZ 0x01 +#define RF_FDEVLSB_25000_HZ 0x9A +#define RF_FDEVMSB_30000_HZ 0x01 +#define RF_FDEVLSB_30000_HZ 0xEC +#define RF_FDEVMSB_35000_HZ 0x02 +#define RF_FDEVLSB_35000_HZ 0x3D +#define RF_FDEVMSB_40000_HZ 0x02 +#define RF_FDEVLSB_40000_HZ 0x8F +#define RF_FDEVMSB_45000_HZ 0x02 +#define RF_FDEVLSB_45000_HZ 0xE1 +#define RF_FDEVMSB_50000_HZ 0x03 +#define RF_FDEVLSB_50000_HZ 0x33 +#define RF_FDEVMSB_55000_HZ 0x03 +#define RF_FDEVLSB_55000_HZ 0x85 +#define RF_FDEVMSB_60000_HZ 0x03 +#define RF_FDEVLSB_60000_HZ 0xD7 +#define RF_FDEVMSB_65000_HZ 0x04 +#define RF_FDEVLSB_65000_HZ 0x29 +#define RF_FDEVMSB_70000_HZ 0x04 +#define RF_FDEVLSB_70000_HZ 0x7B +#define RF_FDEVMSB_75000_HZ 0x04 +#define RF_FDEVLSB_75000_HZ 0xCD +#define RF_FDEVMSB_80000_HZ 0x05 +#define RF_FDEVLSB_80000_HZ 0x1F +#define RF_FDEVMSB_85000_HZ 0x05 +#define RF_FDEVLSB_85000_HZ 0x71 +#define RF_FDEVMSB_90000_HZ 0x05 +#define RF_FDEVLSB_90000_HZ 0xC3 +#define RF_FDEVMSB_95000_HZ 0x06 +#define RF_FDEVLSB_95000_HZ 0x14 +#define RF_FDEVMSB_100000_HZ 0x06 +#define RF_FDEVLSB_100000_HZ 0x66 +#define RF_FDEVMSB_110000_HZ 0x07 +#define RF_FDEVLSB_110000_HZ 0x0A +#define RF_FDEVMSB_120000_HZ 0x07 +#define RF_FDEVLSB_120000_HZ 0xAE +#define RF_FDEVMSB_130000_HZ 0x08 +#define RF_FDEVLSB_130000_HZ 0x52 +#define RF_FDEVMSB_140000_HZ 0x08 +#define RF_FDEVLSB_140000_HZ 0xF6 +#define RF_FDEVMSB_150000_HZ 0x09 +#define RF_FDEVLSB_150000_HZ 0x9A +#define RF_FDEVMSB_160000_HZ 0x0A +#define RF_FDEVLSB_160000_HZ 0x3D +#define RF_FDEVMSB_170000_HZ 0x0A +#define RF_FDEVLSB_170000_HZ 0xE1 +#define RF_FDEVMSB_180000_HZ 0x0B +#define RF_FDEVLSB_180000_HZ 0x85 +#define RF_FDEVMSB_190000_HZ 0x0C +#define RF_FDEVLSB_190000_HZ 0x29 +#define RF_FDEVMSB_200000_HZ 0x0C +#define RF_FDEVLSB_200000_HZ 0xCD + +/*! + * RegFrf (MHz) + */ +#define RF_FRFMSB_863_MHZ 0xD7 +#define RF_FRFMID_863_MHZ 0xC0 +#define RF_FRFLSB_863_MHZ 0x00 +#define RF_FRFMSB_864_MHZ 0xD8 +#define RF_FRFMID_864_MHZ 0x00 +#define RF_FRFLSB_864_MHZ 0x00 +#define RF_FRFMSB_865_MHZ 0xD8 +#define RF_FRFMID_865_MHZ 0x40 +#define RF_FRFLSB_865_MHZ 0x00 +#define RF_FRFMSB_866_MHZ 0xD8 +#define RF_FRFMID_866_MHZ 0x80 +#define RF_FRFLSB_866_MHZ 0x00 +#define RF_FRFMSB_867_MHZ 0xD8 +#define RF_FRFMID_867_MHZ 0xC0 +#define RF_FRFLSB_867_MHZ 0x00 +#define RF_FRFMSB_868_MHZ 0xD9 +#define RF_FRFMID_868_MHZ 0x00 +#define RF_FRFLSB_868_MHZ 0x00 +#define RF_FRFMSB_869_MHZ 0xD9 +#define RF_FRFMID_869_MHZ 0x40 +#define RF_FRFLSB_869_MHZ 0x00 +#define RF_FRFMSB_870_MHZ 0xD9 +#define RF_FRFMID_870_MHZ 0x80 +#define RF_FRFLSB_870_MHZ 0x00 + +#define RF_FRFMSB_902_MHZ 0xE1 +#define RF_FRFMID_902_MHZ 0x80 +#define RF_FRFLSB_902_MHZ 0x00 +#define RF_FRFMSB_903_MHZ 0xE1 +#define RF_FRFMID_903_MHZ 0xC0 +#define RF_FRFLSB_903_MHZ 0x00 +#define RF_FRFMSB_904_MHZ 0xE2 +#define RF_FRFMID_904_MHZ 0x00 +#define RF_FRFLSB_904_MHZ 0x00 +#define RF_FRFMSB_905_MHZ 0xE2 +#define RF_FRFMID_905_MHZ 0x40 +#define RF_FRFLSB_905_MHZ 0x00 +#define RF_FRFMSB_906_MHZ 0xE2 +#define RF_FRFMID_906_MHZ 0x80 +#define RF_FRFLSB_906_MHZ 0x00 +#define RF_FRFMSB_907_MHZ 0xE2 +#define RF_FRFMID_907_MHZ 0xC0 +#define RF_FRFLSB_907_MHZ 0x00 +#define RF_FRFMSB_908_MHZ 0xE3 +#define RF_FRFMID_908_MHZ 0x00 +#define RF_FRFLSB_908_MHZ 0x00 +#define RF_FRFMSB_909_MHZ 0xE3 +#define RF_FRFMID_909_MHZ 0x40 +#define RF_FRFLSB_909_MHZ 0x00 +#define RF_FRFMSB_910_MHZ 0xE3 +#define RF_FRFMID_910_MHZ 0x80 +#define RF_FRFLSB_910_MHZ 0x00 +#define RF_FRFMSB_911_MHZ 0xE3 +#define RF_FRFMID_911_MHZ 0xC0 +#define RF_FRFLSB_911_MHZ 0x00 +#define RF_FRFMSB_912_MHZ 0xE4 +#define RF_FRFMID_912_MHZ 0x00 +#define RF_FRFLSB_912_MHZ 0x00 +#define RF_FRFMSB_913_MHZ 0xE4 +#define RF_FRFMID_913_MHZ 0x40 +#define RF_FRFLSB_913_MHZ 0x00 +#define RF_FRFMSB_914_MHZ 0xE4 +#define RF_FRFMID_914_MHZ 0x80 +#define RF_FRFLSB_914_MHZ 0x00 +#define RF_FRFMSB_915_MHZ 0xE4 // Default +#define RF_FRFMID_915_MHZ 0xC0 // Default +#define RF_FRFLSB_915_MHZ 0x00 // Default +#define RF_FRFMSB_916_MHZ 0xE5 +#define RF_FRFMID_916_MHZ 0x00 +#define RF_FRFLSB_916_MHZ 0x00 +#define RF_FRFMSB_917_MHZ 0xE5 +#define RF_FRFMID_917_MHZ 0x40 +#define RF_FRFLSB_917_MHZ 0x00 +#define RF_FRFMSB_918_MHZ 0xE5 +#define RF_FRFMID_918_MHZ 0x80 +#define RF_FRFLSB_918_MHZ 0x00 +#define RF_FRFMSB_919_MHZ 0xE5 +#define RF_FRFMID_919_MHZ 0xC0 +#define RF_FRFLSB_919_MHZ 0x00 +#define RF_FRFMSB_920_MHZ 0xE6 +#define RF_FRFMID_920_MHZ 0x00 +#define RF_FRFLSB_920_MHZ 0x00 +#define RF_FRFMSB_921_MHZ 0xE6 +#define RF_FRFMID_921_MHZ 0x40 +#define RF_FRFLSB_921_MHZ 0x00 +#define RF_FRFMSB_922_MHZ 0xE6 +#define RF_FRFMID_922_MHZ 0x80 +#define RF_FRFLSB_922_MHZ 0x00 +#define RF_FRFMSB_923_MHZ 0xE6 +#define RF_FRFMID_923_MHZ 0xC0 +#define RF_FRFLSB_923_MHZ 0x00 +#define RF_FRFMSB_924_MHZ 0xE7 +#define RF_FRFMID_924_MHZ 0x00 +#define RF_FRFLSB_924_MHZ 0x00 +#define RF_FRFMSB_925_MHZ 0xE7 +#define RF_FRFMID_925_MHZ 0x40 +#define RF_FRFLSB_925_MHZ 0x00 +#define RF_FRFMSB_926_MHZ 0xE7 +#define RF_FRFMID_926_MHZ 0x80 +#define RF_FRFLSB_926_MHZ 0x00 +#define RF_FRFMSB_927_MHZ 0xE7 +#define RF_FRFMID_927_MHZ 0xC0 +#define RF_FRFLSB_927_MHZ 0x00 +#define RF_FRFMSB_928_MHZ 0xE8 +#define RF_FRFMID_928_MHZ 0x00 +#define RF_FRFLSB_928_MHZ 0x00 + +/*! + * RegPaConfig + */ +#define RF_PACONFIG_PASELECT_MASK 0x7F +#define RF_PACONFIG_PASELECT_PABOOST 0x80 +#define RF_PACONFIG_PASELECT_RFO 0x00 // Default + +#define RF_PACONFIG_MAX_POWER_MASK 0x8F + +#define RF_PACONFIG_OUTPUTPOWER_MASK 0xF0 + +/*! + * RegPaRamp + */ +#define RF_PARAMP_MODULATIONSHAPING_MASK 0x9F +#define RF_PARAMP_MODULATIONSHAPING_00 0x00 // Default +#define RF_PARAMP_MODULATIONSHAPING_01 0x20 +#define RF_PARAMP_MODULATIONSHAPING_10 0x40 +#define RF_PARAMP_MODULATIONSHAPING_11 0x60 + +#define RF_PARAMP_TXBANDFORCE_MASK 0xEF +#define RF_PARAMP_TXBANDFORCE_BAND_SEL 0x10 +#define RF_PARAMP_TXBANDFORCE_AUTO 0x00 // Default + +#define RF_PARAMP_MASK 0xF0 +#define RF_PARAMP_3400_US 0x00 +#define RF_PARAMP_2000_US 0x01 +#define RF_PARAMP_1000_US 0x02 +#define RF_PARAMP_0500_US 0x03 +#define RF_PARAMP_0250_US 0x04 +#define RF_PARAMP_0125_US 0x05 +#define RF_PARAMP_0100_US 0x06 +#define RF_PARAMP_0062_US 0x07 +#define RF_PARAMP_0050_US 0x08 +#define RF_PARAMP_0040_US 0x09 // Default +#define RF_PARAMP_0031_US 0x0A +#define RF_PARAMP_0025_US 0x0B +#define RF_PARAMP_0020_US 0x0C +#define RF_PARAMP_0015_US 0x0D +#define RF_PARAMP_0012_US 0x0E +#define RF_PARAMP_0010_US 0x0F + +/*! + * RegOcp + */ +#define RF_OCP_MASK 0xDF +#define RF_OCP_ON 0x20 // Default +#define RF_OCP_OFF 0x00 + +#define RF_OCP_TRIM_MASK 0xE0 +#define RF_OCP_TRIM_045_MA 0x00 +#define RF_OCP_TRIM_050_MA 0x01 +#define RF_OCP_TRIM_055_MA 0x02 +#define RF_OCP_TRIM_060_MA 0x03 +#define RF_OCP_TRIM_065_MA 0x04 +#define RF_OCP_TRIM_070_MA 0x05 +#define RF_OCP_TRIM_075_MA 0x06 +#define RF_OCP_TRIM_080_MA 0x07 +#define RF_OCP_TRIM_085_MA 0x08 +#define RF_OCP_TRIM_090_MA 0x09 +#define RF_OCP_TRIM_095_MA 0x0A +#define RF_OCP_TRIM_100_MA 0x0B // Default +#define RF_OCP_TRIM_105_MA 0x0C +#define RF_OCP_TRIM_110_MA 0x0D +#define RF_OCP_TRIM_115_MA 0x0E +#define RF_OCP_TRIM_120_MA 0x0F +#define RF_OCP_TRIM_130_MA 0x10 +#define RF_OCP_TRIM_140_MA 0x11 +#define RF_OCP_TRIM_150_MA 0x12 +#define RF_OCP_TRIM_160_MA 0x13 +#define RF_OCP_TRIM_170_MA 0x14 +#define RF_OCP_TRIM_180_MA 0x15 +#define RF_OCP_TRIM_190_MA 0x16 +#define RF_OCP_TRIM_200_MA 0x17 +#define RF_OCP_TRIM_210_MA 0x18 +#define RF_OCP_TRIM_220_MA 0x19 +#define RF_OCP_TRIM_230_MA 0x1A +#define RF_OCP_TRIM_240_MA 0x1B + +/*! + * RegLna + */ +#define RF_LNA_GAIN_MASK 0x1F +#define RF_LNA_GAIN_G1 0x20 // Default +#define RF_LNA_GAIN_G2 0x40 +#define RF_LNA_GAIN_G3 0x60 +#define RF_LNA_GAIN_G4 0x80 +#define RF_LNA_GAIN_G5 0xA0 +#define RF_LNA_GAIN_G6 0xC0 + +#define RF_LNA_BOOST_LF_MASK 0xE7 +#define RF_LNA_BOOST_LF_DEFAULT 0x00 // Default +#define RF_LNA_BOOST_LF_GAIN 0x08 +#define RF_LNA_BOOST_LF_IP3 0x10 +#define RF_LNA_BOOST_LF_BOOST 0x18 + +#define RF_LNA_RXBANDFORCE_MASK 0xFB +#define RF_LNA_RXBANDFORCE_BAND_SEL 0x04 +#define RF_LNA_RXBANDFORCE_AUTO 0x00 // Default + +#define RF_LNA_BOOST_HF_MASK 0xFC +#define RF_LNA_BOOST_HF_OFF 0x00 // Default +#define RF_LNA_BOOST_HF_ON 0x03 + +/*! + * RegRxConfig + */ +#define RF_RXCONFIG_RESTARTRXONCOLLISION_MASK 0x7F +#define RF_RXCONFIG_RESTARTRXONCOLLISION_ON 0x80 +#define RF_RXCONFIG_RESTARTRXONCOLLISION_OFF 0x00 // Default + +#define RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK 0x40 // Write only + +#define RF_RXCONFIG_RESTARTRXWITHPLLLOCK 0x20 // Write only + +#define RF_RXCONFIG_AFCAUTO_MASK 0xEF +#define RF_RXCONFIG_AFCAUTO_ON 0x10 +#define RF_RXCONFIG_AFCAUTO_OFF 0x00 // Default + +#define RF_RXCONFIG_AGCAUTO_MASK 0xF7 +#define RF_RXCONFIG_AGCAUTO_ON 0x08 // Default +#define RF_RXCONFIG_AGCAUTO_OFF 0x00 + +#define RF_RXCONFIG_RXTRIGER_MASK 0xF8 +#define RF_RXCONFIG_RXTRIGER_OFF 0x00 +#define RF_RXCONFIG_RXTRIGER_RSSI 0x01 +#define RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT 0x06 // Default +#define RF_RXCONFIG_RXTRIGER_RSSI_PREAMBLEDETECT 0x07 + +/*! + * RegRssiConfig + */ +#define RF_RSSICONFIG_OFFSET_MASK 0x07 +#define RF_RSSICONFIG_OFFSET_P_00_DB 0x00 // Default +#define RF_RSSICONFIG_OFFSET_P_01_DB 0x08 +#define RF_RSSICONFIG_OFFSET_P_02_DB 0x10 +#define RF_RSSICONFIG_OFFSET_P_03_DB 0x18 +#define RF_RSSICONFIG_OFFSET_P_04_DB 0x20 +#define RF_RSSICONFIG_OFFSET_P_05_DB 0x28 +#define RF_RSSICONFIG_OFFSET_P_06_DB 0x30 +#define RF_RSSICONFIG_OFFSET_P_07_DB 0x38 +#define RF_RSSICONFIG_OFFSET_P_08_DB 0x40 +#define RF_RSSICONFIG_OFFSET_P_09_DB 0x48 +#define RF_RSSICONFIG_OFFSET_P_10_DB 0x50 +#define RF_RSSICONFIG_OFFSET_P_11_DB 0x58 +#define RF_RSSICONFIG_OFFSET_P_12_DB 0x60 +#define RF_RSSICONFIG_OFFSET_P_13_DB 0x68 +#define RF_RSSICONFIG_OFFSET_P_14_DB 0x70 +#define RF_RSSICONFIG_OFFSET_P_15_DB 0x78 +#define RF_RSSICONFIG_OFFSET_M_16_DB 0x80 +#define RF_RSSICONFIG_OFFSET_M_15_DB 0x88 +#define RF_RSSICONFIG_OFFSET_M_14_DB 0x90 +#define RF_RSSICONFIG_OFFSET_M_13_DB 0x98 +#define RF_RSSICONFIG_OFFSET_M_12_DB 0xA0 +#define RF_RSSICONFIG_OFFSET_M_11_DB 0xA8 +#define RF_RSSICONFIG_OFFSET_M_10_DB 0xB0 +#define RF_RSSICONFIG_OFFSET_M_09_DB 0xB8 +#define RF_RSSICONFIG_OFFSET_M_08_DB 0xC0 +#define RF_RSSICONFIG_OFFSET_M_07_DB 0xC8 +#define RF_RSSICONFIG_OFFSET_M_06_DB 0xD0 +#define RF_RSSICONFIG_OFFSET_M_05_DB 0xD8 +#define RF_RSSICONFIG_OFFSET_M_04_DB 0xE0 +#define RF_RSSICONFIG_OFFSET_M_03_DB 0xE8 +#define RF_RSSICONFIG_OFFSET_M_02_DB 0xF0 +#define RF_RSSICONFIG_OFFSET_M_01_DB 0xF8 + +#define RF_RSSICONFIG_SMOOTHING_MASK 0xF8 +#define RF_RSSICONFIG_SMOOTHING_2 0x00 +#define RF_RSSICONFIG_SMOOTHING_4 0x01 +#define RF_RSSICONFIG_SMOOTHING_8 0x02 // Default +#define RF_RSSICONFIG_SMOOTHING_16 0x03 +#define RF_RSSICONFIG_SMOOTHING_32 0x04 +#define RF_RSSICONFIG_SMOOTHING_64 0x05 +#define RF_RSSICONFIG_SMOOTHING_128 0x06 +#define RF_RSSICONFIG_SMOOTHING_256 0x07 + +/*! + * RegRssiCollision + */ +#define RF_RSSICOLISION_THRESHOLD 0x0A // Default + +/*! + * RegRssiThresh + */ +#define RF_RSSITHRESH_THRESHOLD 0xFF // Default + +/*! + * RegRssiValue (Read Only) + */ + +/*! + * RegRxBw + */ +#define RF_RXBW_MANT_MASK 0xE7 +#define RF_RXBW_MANT_16 0x00 +#define RF_RXBW_MANT_20 0x08 +#define RF_RXBW_MANT_24 0x10 // Default + +#define RF_RXBW_EXP_MASK 0xF8 +#define RF_RXBW_EXP_0 0x00 +#define RF_RXBW_EXP_1 0x01 +#define RF_RXBW_EXP_2 0x02 +#define RF_RXBW_EXP_3 0x03 +#define RF_RXBW_EXP_4 0x04 +#define RF_RXBW_EXP_5 0x05 // Default +#define RF_RXBW_EXP_6 0x06 +#define RF_RXBW_EXP_7 0x07 + +/*! + * RegAfcBw + */ +#define RF_AFCBW_MANTAFC_MASK 0xE7 +#define RF_AFCBW_MANTAFC_16 0x00 +#define RF_AFCBW_MANTAFC_20 0x08 // Default +#define RF_AFCBW_MANTAFC_24 0x10 + +#define RF_AFCBW_EXPAFC_MASK 0xF8 +#define RF_AFCBW_EXPAFC_0 0x00 +#define RF_AFCBW_EXPAFC_1 0x01 +#define RF_AFCBW_EXPAFC_2 0x02 +#define RF_AFCBW_EXPAFC_3 0x03 // Default +#define RF_AFCBW_EXPAFC_4 0x04 +#define RF_AFCBW_EXPAFC_5 0x05 +#define RF_AFCBW_EXPAFC_6 0x06 +#define RF_AFCBW_EXPAFC_7 0x07 + +/*! + * RegOokPeak + */ +#define RF_OOKPEAK_BITSYNC_MASK 0xDF // Default +#define RF_OOKPEAK_BITSYNC_ON 0x20 // Default +#define RF_OOKPEAK_BITSYNC_OFF 0x00 + +#define RF_OOKPEAK_OOKTHRESHTYPE_MASK 0xE7 +#define RF_OOKPEAK_OOKTHRESHTYPE_FIXED 0x00 +#define RF_OOKPEAK_OOKTHRESHTYPE_PEAK 0x08 // Default +#define RF_OOKPEAK_OOKTHRESHTYPE_AVERAGE 0x10 + +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_MASK 0xF8 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_0_5_DB 0x00 // Default +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_0_DB 0x01 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_5_DB 0x02 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_2_0_DB 0x03 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_3_0_DB 0x04 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_4_0_DB 0x05 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_5_0_DB 0x06 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_6_0_DB 0x07 + +/*! + * RegOokFix + */ +#define RF_OOKFIX_OOKFIXEDTHRESHOLD 0x0C // Default + +/*! + * RegOokAvg + */ +#define RF_OOKAVG_OOKPEAKTHRESHDEC_MASK 0x1F +#define RF_OOKAVG_OOKPEAKTHRESHDEC_000 0x00 // Default +#define RF_OOKAVG_OOKPEAKTHRESHDEC_001 0x20 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_010 0x40 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_011 0x60 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_100 0x80 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_101 0xA0 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_110 0xC0 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_111 0xE0 + +#define RF_OOKAVG_AVERAGEOFFSET_MASK 0xF3 +#define RF_OOKAVG_AVERAGEOFFSET_0_DB 0x00 // Default +#define RF_OOKAVG_AVERAGEOFFSET_2_DB 0x04 +#define RF_OOKAVG_AVERAGEOFFSET_4_DB 0x08 +#define RF_OOKAVG_AVERAGEOFFSET_6_DB 0x0C + +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_MASK 0xFC +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_00 0x00 +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_01 0x01 +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_10 0x02 // Default +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_11 0x03 + +/*! + * RegAfcFei + */ +#define RF_AFCFEI_AGCSTART 0x10 + +#define RF_AFCFEI_AFCCLEAR 0x02 + +#define RF_AFCFEI_AFCAUTOCLEAR_MASK 0xFE +#define RF_AFCFEI_AFCAUTOCLEAR_ON 0x01 +#define RF_AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default + +/*! + * RegAfcMsb (Read Only) + */ + +/*! + * RegAfcLsb (Read Only) + */ + +/*! + * RegFeiMsb (Read Only) + */ + +/*! + * RegFeiLsb (Read Only) + */ + +/*! + * RegPreambleDetect + */ +#define RF_PREAMBLEDETECT_DETECTOR_MASK 0x7F +#define RF_PREAMBLEDETECT_DETECTOR_ON 0x80 // Default +#define RF_PREAMBLEDETECT_DETECTOR_OFF 0x00 + +#define RF_PREAMBLEDETECT_DETECTORSIZE_MASK 0x9F +#define RF_PREAMBLEDETECT_DETECTORSIZE_1 0x00 +#define RF_PREAMBLEDETECT_DETECTORSIZE_2 0x20 // Default +#define RF_PREAMBLEDETECT_DETECTORSIZE_3 0x40 +#define RF_PREAMBLEDETECT_DETECTORSIZE_4 0x60 + +#define RF_PREAMBLEDETECT_DETECTORTOL_MASK 0xE0 +#define RF_PREAMBLEDETECT_DETECTORTOL_0 0x00 +#define RF_PREAMBLEDETECT_DETECTORTOL_1 0x01 +#define RF_PREAMBLEDETECT_DETECTORTOL_2 0x02 +#define RF_PREAMBLEDETECT_DETECTORTOL_3 0x03 +#define RF_PREAMBLEDETECT_DETECTORTOL_4 0x04 +#define RF_PREAMBLEDETECT_DETECTORTOL_5 0x05 +#define RF_PREAMBLEDETECT_DETECTORTOL_6 0x06 +#define RF_PREAMBLEDETECT_DETECTORTOL_7 0x07 +#define RF_PREAMBLEDETECT_DETECTORTOL_8 0x08 +#define RF_PREAMBLEDETECT_DETECTORTOL_9 0x09 +#define RF_PREAMBLEDETECT_DETECTORTOL_10 0x0A // Default +#define RF_PREAMBLEDETECT_DETECTORTOL_11 0x0B +#define RF_PREAMBLEDETECT_DETECTORTOL_12 0x0C +#define RF_PREAMBLEDETECT_DETECTORTOL_13 0x0D +#define RF_PREAMBLEDETECT_DETECTORTOL_14 0x0E +#define RF_PREAMBLEDETECT_DETECTORTOL_15 0x0F +#define RF_PREAMBLEDETECT_DETECTORTOL_16 0x10 +#define RF_PREAMBLEDETECT_DETECTORTOL_17 0x11 +#define RF_PREAMBLEDETECT_DETECTORTOL_18 0x12 +#define RF_PREAMBLEDETECT_DETECTORTOL_19 0x13 +#define RF_PREAMBLEDETECT_DETECTORTOL_20 0x14 +#define RF_PREAMBLEDETECT_DETECTORTOL_21 0x15 +#define RF_PREAMBLEDETECT_DETECTORTOL_22 0x16 +#define RF_PREAMBLEDETECT_DETECTORTOL_23 0x17 +#define RF_PREAMBLEDETECT_DETECTORTOL_24 0x18 +#define RF_PREAMBLEDETECT_DETECTORTOL_25 0x19 +#define RF_PREAMBLEDETECT_DETECTORTOL_26 0x1A +#define RF_PREAMBLEDETECT_DETECTORTOL_27 0x1B +#define RF_PREAMBLEDETECT_DETECTORTOL_28 0x1C +#define RF_PREAMBLEDETECT_DETECTORTOL_29 0x1D +#define RF_PREAMBLEDETECT_DETECTORTOL_30 0x1E +#define RF_PREAMBLEDETECT_DETECTORTOL_31 0x1F + +/*! + * RegRxTimeout1 + */ +#define RF_RXTIMEOUT1_TIMEOUTRXRSSI 0x00 // Default + +/*! + * RegRxTimeout2 + */ +#define RF_RXTIMEOUT2_TIMEOUTRXPREAMBLE 0x00 // Default + +/*! + * RegRxTimeout3 + */ +#define RF_RXTIMEOUT3_TIMEOUTSIGNALSYNC 0x00 // Default + +/*! + * RegRxDelay + */ +#define RF_RXDELAY_INTERPACKETRXDELAY 0x00 // Default + +/*! + * RegOsc + */ +#define RF_OSC_RCCALSTART 0x08 + +#define RF_OSC_CLKOUT_MASK 0xF8 +#define RF_OSC_CLKOUT_32_MHZ 0x00 +#define RF_OSC_CLKOUT_16_MHZ 0x01 +#define RF_OSC_CLKOUT_8_MHZ 0x02 +#define RF_OSC_CLKOUT_4_MHZ 0x03 +#define RF_OSC_CLKOUT_2_MHZ 0x04 +#define RF_OSC_CLKOUT_1_MHZ 0x05 // Default +#define RF_OSC_CLKOUT_RC 0x06 +#define RF_OSC_CLKOUT_OFF 0x07 + +/*! + * RegPreambleMsb/RegPreambleLsb + */ +#define RF_PREAMBLEMSB_SIZE 0x00 // Default +#define RF_PREAMBLELSB_SIZE 0x03 // Default + +/*! + * RegSyncConfig + */ +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_MASK 0x3F +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON 0x80 // Default +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_OFF 0x40 +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_OFF 0x00 + + +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_MASK 0xDF +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_55 0x20 +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_AA 0x00 // Default + +#define RF_SYNCCONFIG_SYNC_MASK 0xEF +#define RF_SYNCCONFIG_SYNC_ON 0x10 // Default +#define RF_SYNCCONFIG_SYNC_OFF 0x00 + + +#define RF_SYNCCONFIG_SYNCSIZE_MASK 0xF8 +#define RF_SYNCCONFIG_SYNCSIZE_1 0x00 +#define RF_SYNCCONFIG_SYNCSIZE_2 0x01 +#define RF_SYNCCONFIG_SYNCSIZE_3 0x02 +#define RF_SYNCCONFIG_SYNCSIZE_4 0x03 // Default +#define RF_SYNCCONFIG_SYNCSIZE_5 0x04 +#define RF_SYNCCONFIG_SYNCSIZE_6 0x05 +#define RF_SYNCCONFIG_SYNCSIZE_7 0x06 +#define RF_SYNCCONFIG_SYNCSIZE_8 0x07 + +/*! + * RegSyncValue1-8 + */ +#define RF_SYNCVALUE1_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE2_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE3_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE4_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE5_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE6_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE7_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE8_SYNCVALUE 0x01 // Default + +/*! + * RegPacketConfig1 + */ +#define RF_PACKETCONFIG1_PACKETFORMAT_MASK 0x7F +#define RF_PACKETCONFIG1_PACKETFORMAT_FIXED 0x00 +#define RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE 0x80 // Default + +#define RF_PACKETCONFIG1_DCFREE_MASK 0x9F +#define RF_PACKETCONFIG1_DCFREE_OFF 0x00 // Default +#define RF_PACKETCONFIG1_DCFREE_MANCHESTER 0x20 +#define RF_PACKETCONFIG1_DCFREE_WHITENING 0x40 + +#define RF_PACKETCONFIG1_CRC_MASK 0xEF +#define RF_PACKETCONFIG1_CRC_ON 0x10 // Default +#define RF_PACKETCONFIG1_CRC_OFF 0x00 + +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_MASK 0xF7 +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_ON 0x00 // Default +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_OFF 0x08 + +#define RF_PACKETCONFIG1_ADDRSFILTERING_MASK 0xF9 +#define RF_PACKETCONFIG1_ADDRSFILTERING_OFF 0x00 // Default +#define RF_PACKETCONFIG1_ADDRSFILTERING_NODE 0x02 +#define RF_PACKETCONFIG1_ADDRSFILTERING_NODEBROADCAST 0x04 + +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_MASK 0xFE +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT 0x00 // Default +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_IBM 0x01 + +/*! + * RegPacketConfig2 + */ + +#define RF_PACKETCONFIG2_WMBUS_CRC_ENABLE_MASK 0x7F +#define RF_PACKETCONFIG2_WMBUS_CRC_ENABLE 0x80 +#define RF_PACKETCONFIG2_WMBUS_CRC_DISABLE 0x00 // Default + +#define RF_PACKETCONFIG2_DATAMODE_MASK 0xBF +#define RF_PACKETCONFIG2_DATAMODE_CONTINUOUS 0x00 +#define RF_PACKETCONFIG2_DATAMODE_PACKET 0x40 // Default + +#define RF_PACKETCONFIG2_IOHOME_MASK 0xDF +#define RF_PACKETCONFIG2_IOHOME_ON 0x20 +#define RF_PACKETCONFIG2_IOHOME_OFF 0x00 // Default + +#define RF_PACKETCONFIG2_BEACON_MASK 0xF7 +#define RF_PACKETCONFIG2_BEACON_ON 0x08 +#define RF_PACKETCONFIG2_BEACON_OFF 0x00 // Default + +#define RF_PACKETCONFIG2_PAYLOADLENGTH_MSB_MASK 0xF8 + +/*! + * RegPayloadLength + */ +#define RF_PAYLOADLENGTH_LENGTH 0x40 // Default + +/*! + * RegNodeAdrs + */ +#define RF_NODEADDRESS_ADDRESS 0x00 + +/*! + * RegBroadcastAdrs + */ +#define RF_BROADCASTADDRESS_ADDRESS 0x00 + +/*! + * RegFifoThresh + */ +#define RF_FIFOTHRESH_TXSTARTCONDITION_MASK 0x7F +#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFOTHRESH 0x00 // Default +#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY 0x80 + +#define RF_FIFOTHRESH_FIFOTHRESHOLD_MASK 0xC0 +#define RF_FIFOTHRESH_FIFOTHRESHOLD_THRESHOLD 0x0F // Default + +/*! + * RegSeqConfig1 + */ +#define RF_SEQCONFIG1_SEQUENCER_START 0x80 + +#define RF_SEQCONFIG1_SEQUENCER_STOP 0x40 + +#define RF_SEQCONFIG1_IDLEMODE_MASK 0xDF +#define RF_SEQCONFIG1_IDLEMODE_SLEEP 0x20 +#define RF_SEQCONFIG1_IDLEMODE_STANDBY 0x00 // Default + +#define RF_SEQCONFIG1_FROMSTART_MASK 0xE7 +#define RF_SEQCONFIG1_FROMSTART_TOLPS 0x00 // Default +#define RF_SEQCONFIG1_FROMSTART_TORX 0x08 +#define RF_SEQCONFIG1_FROMSTART_TOTX 0x10 +#define RF_SEQCONFIG1_FROMSTART_TOTX_ONFIFOLEVEL 0x18 + +#define RF_SEQCONFIG1_LPS_MASK 0xFB +#define RF_SEQCONFIG1_LPS_SEQUENCER_OFF 0x00 // Default +#define RF_SEQCONFIG1_LPS_IDLE 0x04 + +#define RF_SEQCONFIG1_FROMIDLE_MASK 0xFD +#define RF_SEQCONFIG1_FROMIDLE_TOTX 0x00 // Default +#define RF_SEQCONFIG1_FROMIDLE_TORX 0x02 + +#define RF_SEQCONFIG1_FROMTX_MASK 0xFE +#define RF_SEQCONFIG1_FROMTX_TOLPS 0x00 // Default +#define RF_SEQCONFIG1_FROMTX_TORX 0x01 + +/*! + * RegSeqConfig2 + */ +#define RF_SEQCONFIG2_FROMRX_MASK 0x1F +#define RF_SEQCONFIG2_FROMRX_TOUNUSED_000 0x00 // Default +#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONPLDRDY 0x20 +#define RF_SEQCONFIG2_FROMRX_TOLPS_ONPLDRDY 0x40 +#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONCRCOK 0x60 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONRSSI 0x80 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONSYNC 0xA0 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONPREAMBLE 0xC0 +#define RF_SEQCONFIG2_FROMRX_TOUNUSED_111 0xE0 + +#define RF_SEQCONFIG2_FROMRXTIMEOUT_MASK 0xE7 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TORXRESTART 0x00 // Default +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOTX 0x08 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOLPS 0x10 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOSEQUENCEROFF 0x18 + +#define RF_SEQCONFIG2_FROMRXPKT_MASK 0xF8 +#define RF_SEQCONFIG2_FROMRXPKT_TOSEQUENCEROFF 0x00 // Default +#define RF_SEQCONFIG2_FROMRXPKT_TOTX_ONFIFOEMPTY 0x01 +#define RF_SEQCONFIG2_FROMRXPKT_TOLPS 0x02 +#define RF_SEQCONFIG2_FROMRXPKT_TOSYNTHESIZERRX 0x03 +#define RF_SEQCONFIG2_FROMRXPKT_TORX 0x04 + +/*! + * RegTimerResol + */ +#define RF_TIMERRESOL_TIMER1RESOL_MASK 0xF3 +#define RF_TIMERRESOL_TIMER1RESOL_OFF 0x00 // Default +#define RF_TIMERRESOL_TIMER1RESOL_000064_US 0x04 +#define RF_TIMERRESOL_TIMER1RESOL_004100_US 0x08 +#define RF_TIMERRESOL_TIMER1RESOL_262000_US 0x0C + +#define RF_TIMERRESOL_TIMER2RESOL_MASK 0xFC +#define RF_TIMERRESOL_TIMER2RESOL_OFF 0x00 // Default +#define RF_TIMERRESOL_TIMER2RESOL_000064_US 0x01 +#define RF_TIMERRESOL_TIMER2RESOL_004100_US 0x02 +#define RF_TIMERRESOL_TIMER2RESOL_262000_US 0x03 + +/*! + * RegTimer1Coef + */ +#define RF_TIMER1COEF_TIMER1COEFFICIENT 0xF5 // Default + +/*! + * RegTimer2Coef + */ +#define RF_TIMER2COEF_TIMER2COEFFICIENT 0x20 // Default + +/*! + * RegImageCal + */ +#define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F +#define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80 +#define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default + +#define RF_IMAGECAL_IMAGECAL_MASK 0xBF +#define RF_IMAGECAL_IMAGECAL_START 0x40 + +#define RF_IMAGECAL_IMAGECAL_RUNNING 0x20 +#define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default + +#define RF_IMAGECAL_TEMPCHANGE_HIGHER 0x08 +#define RF_IMAGECAL_TEMPCHANGE_LOWER 0x00 + +#define RF_IMAGECAL_TEMPTHRESHOLD_MASK 0xF9 +#define RF_IMAGECAL_TEMPTHRESHOLD_05 0x00 +#define RF_IMAGECAL_TEMPTHRESHOLD_10 0x02 // Default +#define RF_IMAGECAL_TEMPTHRESHOLD_15 0x04 +#define RF_IMAGECAL_TEMPTHRESHOLD_20 0x06 + +#define RF_IMAGECAL_TEMPMONITOR_MASK 0xFE +#define RF_IMAGECAL_TEMPMONITOR_ON 0x00 // Default +#define RF_IMAGECAL_TEMPMONITOR_OFF 0x01 + +/*! + * RegTemp (Read Only) + */ + +/*! + * RegLowBat + */ +#define RF_LOWBAT_MASK 0xF7 +#define RF_LOWBAT_ON 0x08 +#define RF_LOWBAT_OFF 0x00 // Default + +#define RF_LOWBAT_TRIM_MASK 0xF8 +#define RF_LOWBAT_TRIM_1695 0x00 +#define RF_LOWBAT_TRIM_1764 0x01 +#define RF_LOWBAT_TRIM_1835 0x02 // Default +#define RF_LOWBAT_TRIM_1905 0x03 +#define RF_LOWBAT_TRIM_1976 0x04 +#define RF_LOWBAT_TRIM_2045 0x05 +#define RF_LOWBAT_TRIM_2116 0x06 +#define RF_LOWBAT_TRIM_2185 0x07 + +/*! + * RegIrqFlags1 + */ +#define RF_IRQFLAGS1_MODEREADY 0x80 + +#define RF_IRQFLAGS1_RXREADY 0x40 + +#define RF_IRQFLAGS1_TXREADY 0x20 + +#define RF_IRQFLAGS1_PLLLOCK 0x10 + +#define RF_IRQFLAGS1_RSSI 0x08 + +#define RF_IRQFLAGS1_TIMEOUT 0x04 + +#define RF_IRQFLAGS1_PREAMBLEDETECT 0x02 + +#define RF_IRQFLAGS1_SYNCADDRESSMATCH 0x01 + +/*! + * RegIrqFlags2 + */ +#define RF_IRQFLAGS2_FIFOFULL 0x80 + +#define RF_IRQFLAGS2_FIFOEMPTY 0x40 + +#define RF_IRQFLAGS2_FIFOLEVEL 0x20 + +#define RF_IRQFLAGS2_FIFOOVERRUN 0x10 + +#define RF_IRQFLAGS2_PACKETSENT 0x08 + +#define RF_IRQFLAGS2_PAYLOADREADY 0x04 + +#define RF_IRQFLAGS2_CRCOK 0x02 + +#define RF_IRQFLAGS2_LOWBAT 0x01 + +/*! + * RegDioMapping1 + */ +#define RF_DIOMAPPING1_DIO0_MASK 0x3F +#define RF_DIOMAPPING1_DIO0_00 0x00 // Default +#define RF_DIOMAPPING1_DIO0_01 0x40 +#define RF_DIOMAPPING1_DIO0_10 0x80 +#define RF_DIOMAPPING1_DIO0_11 0xC0 + +#define RF_DIOMAPPING1_DIO1_MASK 0xCF +#define RF_DIOMAPPING1_DIO1_00 0x00 // Default +#define RF_DIOMAPPING1_DIO1_01 0x10 +#define RF_DIOMAPPING1_DIO1_10 0x20 +#define RF_DIOMAPPING1_DIO1_11 0x30 + +#define RF_DIOMAPPING1_DIO2_MASK 0xF3 +#define RF_DIOMAPPING1_DIO2_00 0x00 // Default +#define RF_DIOMAPPING1_DIO2_01 0x04 +#define RF_DIOMAPPING1_DIO2_10 0x08 +#define RF_DIOMAPPING1_DIO2_11 0x0C + +#define RF_DIOMAPPING1_DIO3_MASK 0xFC +#define RF_DIOMAPPING1_DIO3_00 0x00 // Default +#define RF_DIOMAPPING1_DIO3_01 0x01 +#define RF_DIOMAPPING1_DIO3_10 0x02 +#define RF_DIOMAPPING1_DIO3_11 0x03 + +/*! + * RegDioMapping2 + */ +#define RF_DIOMAPPING2_DIO4_MASK 0x3F +#define RF_DIOMAPPING2_DIO4_00 0x00 // Default +#define RF_DIOMAPPING2_DIO4_01 0x40 +#define RF_DIOMAPPING2_DIO4_10 0x80 +#define RF_DIOMAPPING2_DIO4_11 0xC0 + +#define RF_DIOMAPPING2_DIO5_MASK 0xCF +#define RF_DIOMAPPING2_DIO5_00 0x00 // Default +#define RF_DIOMAPPING2_DIO5_01 0x10 +#define RF_DIOMAPPING2_DIO5_10 0x20 +#define RF_DIOMAPPING2_DIO5_11 0x30 + +#define RF_DIOMAPPING2_MAP_MASK 0xFE +#define RF_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 +#define RF_DIOMAPPING2_MAP_RSSI 0x00 // Default + +/*! + * RegVersion (Read Only) + */ + +/*! + * RegAgcRef + */ + +/*! + * RegAgcThresh1 + */ + +/*! + * RegAgcThresh2 + */ + +/*! + * RegAgcThresh3 + */ + +/*! + * RegPllHop + */ +#define RF_PLLHOP_FASTHOP_MASK 0x7F +#define RF_PLLHOP_FASTHOP_ON 0x80 +#define RF_PLLHOP_FASTHOP_OFF 0x00 // Default + +/*! + * RegTcxo + */ +#define RF_TCXO_TCXOINPUT_MASK 0xEF +#define RF_TCXO_TCXOINPUT_ON 0x10 +#define RF_TCXO_TCXOINPUT_OFF 0x00 // Default + +/*! + * RegPaDac + */ +#define RF_PADAC_20DBM_MASK 0xF8 +#define RF_PADAC_20DBM_ON 0x07 +#define RF_PADAC_20DBM_OFF 0x04 // Default + +/*! + * RegPll + */ +#define RF_PLL_BANDWIDTH_MASK 0x3F +#define RF_PLL_BANDWIDTH_75 0x00 +#define RF_PLL_BANDWIDTH_150 0x40 +#define RF_PLL_BANDWIDTH_225 0x80 +#define RF_PLL_BANDWIDTH_300 0xC0 // Default + +/*! + * RegPllLowPn + */ +#define RF_PLLLOWPN_BANDWIDTH_MASK 0x3F +#define RF_PLLLOWPN_BANDWIDTH_75 0x00 +#define RF_PLLLOWPN_BANDWIDTH_150 0x40 +#define RF_PLLLOWPN_BANDWIDTH_225 0x80 +#define RF_PLLLOWPN_BANDWIDTH_300 0xC0 // Default + +/*! + * RegFormerTemp + */ + +/*! + * RegBitrateFrac + */ +#define RF_BITRATEFRAC_MASK 0xF0 + +typedef struct sSX1276 +{ + uint8_t RegFifo; // 0x00 + // Common settings + uint8_t RegOpMode; // 0x01 + uint8_t RegBitrateMsb; // 0x02 + uint8_t RegBitrateLsb; // 0x03 + uint8_t RegFdevMsb; // 0x04 + uint8_t RegFdevLsb; // 0x05 + uint8_t RegFrfMsb; // 0x06 + uint8_t RegFrfMid; // 0x07 + uint8_t RegFrfLsb; // 0x08 + // Tx settings + uint8_t RegPaConfig; // 0x09 + uint8_t RegPaRamp; // 0x0A + uint8_t RegOcp; // 0x0B + // Rx settings + uint8_t RegLna; // 0x0C + uint8_t RegRxConfig; // 0x0D + uint8_t RegRssiConfig; // 0x0E + uint8_t RegRssiCollision; // 0x0F + uint8_t RegRssiThresh; // 0x10 + uint8_t RegRssiValue; // 0x11 + uint8_t RegRxBw; // 0x12 + uint8_t RegAfcBw; // 0x13 + uint8_t RegOokPeak; // 0x14 + uint8_t RegOokFix; // 0x15 + uint8_t RegOokAvg; // 0x16 + uint8_t RegRes17; // 0x17 + uint8_t RegRes18; // 0x18 + uint8_t RegRes19; // 0x19 + uint8_t RegAfcFei; // 0x1A + uint8_t RegAfcMsb; // 0x1B + uint8_t RegAfcLsb; // 0x1C + uint8_t RegFeiMsb; // 0x1D + uint8_t RegFeiLsb; // 0x1E + uint8_t RegPreambleDetect; // 0x1F + uint8_t RegRxTimeout1; // 0x20 + uint8_t RegRxTimeout2; // 0x21 + uint8_t RegRxTimeout3; // 0x22 + uint8_t RegRxDelay; // 0x23 + // Oscillator settings + uint8_t RegOsc; // 0x24 + // Packet handler settings + uint8_t RegPreambleMsb; // 0x25 + uint8_t RegPreambleLsb; // 0x26 + uint8_t RegSyncConfig; // 0x27 + uint8_t RegSyncValue1; // 0x28 + uint8_t RegSyncValue2; // 0x29 + uint8_t RegSyncValue3; // 0x2A + uint8_t RegSyncValue4; // 0x2B + uint8_t RegSyncValue5; // 0x2C + uint8_t RegSyncValue6; // 0x2D + uint8_t RegSyncValue7; // 0x2E + uint8_t RegSyncValue8; // 0x2F + uint8_t RegPacketConfig1; // 0x30 + uint8_t RegPacketConfig2; // 0x31 + uint8_t RegPayloadLength; // 0x32 + uint8_t RegNodeAdrs; // 0x33 + uint8_t RegBroadcastAdrs; // 0x34 + uint8_t RegFifoThresh; // 0x35 + // Sequencer settings + uint8_t RegSeqConfig1; // 0x36 + uint8_t RegSeqConfig2; // 0x37 + uint8_t RegTimerResol; // 0x38 + uint8_t RegTimer1Coef; // 0x39 + uint8_t RegTimer2Coef; // 0x3A + // Service settings + uint8_t RegImageCal; // 0x3B + uint8_t RegTemp; // 0x3C + uint8_t RegLowBat; // 0x3D + // Status + uint8_t RegIrqFlags1; // 0x3E + uint8_t RegIrqFlags2; // 0x3F + // I/O settings + uint8_t RegDioMapping1; // 0x40 + uint8_t RegDioMapping2; // 0x41 + // Version + uint8_t RegVersion; // 0x42 + // Additional settings + uint8_t RegAgcRef; // 0x43 + uint8_t RegAgcThresh1; // 0x44 + uint8_t RegAgcThresh2; // 0x45 + uint8_t RegAgcThresh3; // 0x46 + // Test + uint8_t RegTestReserved47[0x4B - 0x47]; // 0x47-0x4A + // Additional settings + uint8_t RegPllHop; // 0x4B + uint8_t RegTestReserved4C; // 0x4C + uint8_t RegPaDac; // 0x4D + // Test + uint8_t RegTestReserved4E[0x58-0x4E]; // 0x4E-0x57 + // Additional settings + uint8_t RegTcxo; // 0x58 + // Test + uint8_t RegTestReserved59; // 0x59 + // Test + uint8_t RegTestReserved5B; // 0x5B + // Additional settings + uint8_t RegPll; // 0x5C + // Test + uint8_t RegTestReserved5D; // 0x5D + // Additional settings + uint8_t RegPllLowPn; // 0x5E + // Test + uint8_t RegTestReserved5F[0x6C - 0x5F]; // 0x5F-0x6B + // Additional settings + uint8_t RegFormerTemp; // 0x6C + // Test + uint8_t RegTestReserved6D[0x70 - 0x6D]; // 0x6D-0x6F + // Additional settings + uint8_t RegBitrateFrac; // 0x70 +}tSX1276; + +extern tSX1276* SX1276; + +/*! + * \brief Initializes the SX1276 + */ +void SX1276FskInit( void ); + +/*! + * \brief Sets the SX1276 to datasheet default values + */ +void SX1276FskSetDefaults( void ); + +/*! + * \brief Resets the SX1276 + */ +void SX1276FskReset( void ); + +/*! + * \brief Enables/Disables the LoRa modem + * + * \param [IN]: enable [true, false] + */ +void SX1276FskSetLoRaOn( bool enable ); + +/*! + * \brief Sets the SX1276 operating mode + * + * \param [IN] opMode New operating mode + */ +void SX1276FskSetOpMode( uint8_t opMode ); + +/*! + * \brief Gets the SX1276 operating mode + * + * \retval opMode Current operating mode + */ +uint8_t SX1276FskGetOpMode( void ); + +/*! + * \brief Trigs and reads the FEI + * + * \retval feiValue Frequency error value. + */ +int32_t SX1276FskReadFei( void ); + +/*! + * \brief Reads the current AFC value + * + * \retval afcValue Frequency offset value. + */ +int32_t SX1276FskReadAfc( void ); + +/*! + * \brief Reads the current Rx gain setting + * + * \retval rxGain Current gain setting + */ +uint8_t SX1276FskReadRxGain( void ); + +/*! + * \brief Trigs and reads the current RSSI value + * + * \retval rssiValue Current RSSI value in [dBm] + */ +double SX1276FskReadRssi( void ); + +/*! + * \brief Gets the Rx gain value measured while receiving the packet + * + * \retval rxGainValue Current Rx gain value + */ +uint8_t SX1276FskGetPacketRxGain( void ); + +/*! + * \brief Gets the RSSI value measured while receiving the packet + * + * \retval rssiValue Current RSSI value in [dBm] + */ +double SX1276FskGetPacketRssi( void ); + +/*! + * \brief Gets the AFC value measured while receiving the packet + * + * \retval afcValue Current AFC value in [Hz] + */ +uint32_t SX1276FskGetPacketAfc( void ); + +/*! + * \brief Sets the radio in Rx mode. Waiting for a packet + */ +void SX1276FskStartRx( void ); + +/*! + * \brief Gets a copy of the current received buffer + * + * \param [IN]: buffer Buffer pointer + * \param [IN]: size Buffer size + */ +void SX1276FskGetRxPacket( void *buffer, uint16_t *size ); + +/*! + * \brief Sets a copy of the buffer to be transmitted and starts the + * transmission + * + * \param [IN]: buffer Buffer pointer + * \param [IN]: size Buffer size + */ +void SX1276FskSetTxPacket( const void *buffer, uint16_t size ); + +/*! + * \brief Gets the current RFState + * + * \retval rfState Current RF state [RF_IDLE, RF_BUSY, + * RF_RX_DONE, RF_RX_TIMEOUT, + * RF_TX_DONE, RF_TX_TIMEOUT] + */ +uint8_t SX1276FskGetRFState( void ); + +/*! + * \brief Sets the new state of the RF state machine + * + * \param [IN]: state New RF state machine state + */ +void SX1276FskSetRFState( uint8_t state ); + +/*! + * \brief Process the FSK modem Rx and Tx state machines depending on the + * SX1276 operating mode. + * + * \retval rfState Current RF state [RF_IDLE, RF_BUSY, + * RF_RX_DONE, RF_RX_TIMEOUT, + * RF_TX_DONE, RF_TX_TIMEOUT] + */ +uint32_t SX1276FskProcess( void ); + +#endif //__SX1276_FSK_H__ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.c new file mode 100644 index 000000000..4e6eca88b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.c @@ -0,0 +1,532 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276-FskMisc.c + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-FskMisc.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#include + +#include "platform.h" + +#if defined( USE_SX1276_RADIO ) + +#include "sx1276-Hal.h" +#include "sx1276.h" + +#include "sx1276-Fsk.h" +#include "sx1276-FskMisc.h" + +extern tFskSettings FskSettings; + +void SX1276FskSetRFFrequency( uint32_t freq ) +{ + FskSettings.RFFrequency = freq; + + freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP ); + SX1276->RegFrfMsb = ( uint8_t )( ( freq >> 16 ) & 0xFF ); + SX1276->RegFrfMid = ( uint8_t )( ( freq >> 8 ) & 0xFF ); + SX1276->RegFrfLsb = ( uint8_t )( freq & 0xFF ); + SX1276WriteBuffer( REG_FRFMSB, &SX1276->RegFrfMsb, 3 ); +} + +uint32_t SX1276FskGetRFFrequency( void ) +{ + SX1276ReadBuffer( REG_FRFMSB, &SX1276->RegFrfMsb, 3 ); + FskSettings.RFFrequency = ( ( uint32_t )SX1276->RegFrfMsb << 16 ) | ( ( uint32_t )SX1276->RegFrfMid << 8 ) | ( ( uint32_t )SX1276->RegFrfLsb ); + FskSettings.RFFrequency = ( uint32_t )( ( double )FskSettings.RFFrequency * ( double )FREQ_STEP ); + + return FskSettings.RFFrequency; +} + +void SX1276FskRxCalibrate( void ) +{ + // the function RadioRxCalibrate is called just after the reset so all register are at their default values + uint8_t regPaConfigInitVal; + uint32_t initialFreq; + + // save register values; + SX1276Read( REG_PACONFIG, ®PaConfigInitVal ); + initialFreq = SX1276FskGetRFFrequency( ); + + // Cut the PA just in case + SX1276->RegPaConfig = 0x00; // RFO output, power = -1 dBm + SX1276Write( REG_PACONFIG, SX1276->RegPaConfig ); + + // Set Frequency in HF band + SX1276FskSetRFFrequency( 860000000 ); + + // Rx chain re-calibration workaround + SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal ); + SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START; + SX1276Write( REG_IMAGECAL, SX1276->RegImageCal ); + + SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal ); + // rx_cal_run goes low when calibration in finished + while( ( SX1276->RegImageCal & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING ) + { + SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal ); + } + + // reload saved values into the registers + SX1276->RegPaConfig = regPaConfigInitVal; + SX1276Write( REG_PACONFIG, SX1276->RegPaConfig ); + + SX1276FskSetRFFrequency( initialFreq ); + +} + +void SX1276FskSetBitrate( uint32_t bitrate ) +{ + FskSettings.Bitrate = bitrate; + + bitrate = ( uint16_t )( ( double )XTAL_FREQ / ( double )bitrate ); + SX1276->RegBitrateMsb = ( uint8_t )( bitrate >> 8 ); + SX1276->RegBitrateLsb = ( uint8_t )( bitrate & 0xFF ); + SX1276WriteBuffer( REG_BITRATEMSB, &SX1276->RegBitrateMsb, 2 ); +} + +uint32_t SX1276FskGetBitrate( void ) +{ + SX1276ReadBuffer( REG_BITRATEMSB, &SX1276->RegBitrateMsb, 2 ); + FskSettings.Bitrate = ( ( ( uint32_t )SX1276->RegBitrateMsb << 8 ) | ( ( uint32_t )SX1276->RegBitrateLsb ) ); + FskSettings.Bitrate = ( uint16_t )( ( double )XTAL_FREQ / ( double )FskSettings.Bitrate ); + + return FskSettings.Bitrate; +} + +void SX1276FskSetFdev( uint32_t fdev ) +{ + FskSettings.Fdev = fdev; + + SX1276Read( REG_FDEVMSB, &SX1276->RegFdevMsb ); + + fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP ); + SX1276->RegFdevMsb = ( ( SX1276->RegFdevMsb & RF_FDEVMSB_FDEV_MASK ) | ( ( ( uint8_t )( fdev >> 8 ) ) & ~RF_FDEVMSB_FDEV_MASK ) ); + SX1276->RegFdevLsb = ( uint8_t )( fdev & 0xFF ); + SX1276WriteBuffer( REG_FDEVMSB, &SX1276->RegFdevMsb, 2 ); +} + +uint32_t SX1276FskGetFdev( void ) +{ + SX1276ReadBuffer( REG_FDEVMSB, &SX1276->RegFdevMsb, 2 ); + FskSettings.Fdev = ( ( ( uint32_t )( ( SX1276->RegFdevMsb << 8 ) & ~RF_FDEVMSB_FDEV_MASK ) ) | ( ( uint32_t )SX1276->RegFdevLsb ) ); + FskSettings.Fdev = ( uint16_t )( ( double )FskSettings.Fdev * ( double )FREQ_STEP ); + + return FskSettings.Fdev; +} + +void SX1276FskSetRFPower( int8_t power ) +{ + SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig ); + SX1276Read( REG_PADAC, &SX1276->RegPaDac ); + + if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) + { + if( ( SX1276->RegPaDac & 0x87 ) == 0x87 ) + { + if( power < 5 ) + { + power = 5; + } + if( power > 20 ) + { + power = 20; + } + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F ); + } + else + { + if( power < 2 ) + { + power = 2; + } + if( power > 17 ) + { + power = 17; + } + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F ); + } + } + else + { + if( power < -1 ) + { + power = -1; + } + if( power > 14 ) + { + power = 14; + } + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F ); + } + SX1276Write( REG_PACONFIG, SX1276->RegPaConfig ); + FskSettings.Power = power; +} + +int8_t SX1276FskGetRFPower( void ) +{ + SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig ); + SX1276Read( REG_PADAC, &SX1276->RegPaDac ); + + if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) + { + if( ( SX1276->RegPaDac & 0x07 ) == 0x07 ) + { + FskSettings.Power = 5 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK ); + } + else + { + FskSettings.Power = 2 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK ); + } + } + else + { + FskSettings.Power = -1 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK ); + } + return FskSettings.Power; +} + +/*! + * \brief Computes the Rx bandwidth with the mantisse and exponent + * + * \param [IN] mantisse Mantisse of the bandwidth value + * \param [IN] exponent Exponent of the bandwidth value + * \retval bandwidth Computed bandwidth + */ +static uint32_t SX1276FskComputeRxBw( uint8_t mantisse, uint8_t exponent ) +{ + // rxBw + if( ( SX1276->RegOpMode & RF_OPMODE_MODULATIONTYPE_FSK ) == RF_OPMODE_MODULATIONTYPE_FSK ) + { + return ( uint32_t )( ( double )XTAL_FREQ / ( mantisse * ( double )pow( 2, exponent + 2 ) ) ); + } + else + { + return ( uint32_t )( ( double )XTAL_FREQ / ( mantisse * ( double )pow( 2, exponent + 3 ) ) ); + } +} + +/*! + * \brief Computes the mantisse and exponent from the bandwitdh value + * + * \param [IN] rxBwValue Bandwidth value + * \param [OUT] mantisse Mantisse of the bandwidth value + * \param [OUT] exponent Exponent of the bandwidth value + */ +static void SX1276FskComputeRxBwMantExp( uint32_t rxBwValue, uint8_t* mantisse, uint8_t* exponent ) +{ + uint8_t tmpExp = 0; + uint8_t tmpMant = 0; + + double tmpRxBw = 0; + double rxBwMin = 10e6; + + for( tmpExp = 0; tmpExp < 8; tmpExp++ ) + { + for( tmpMant = 16; tmpMant <= 24; tmpMant += 4 ) + { + if( ( SX1276->RegOpMode & RF_OPMODE_MODULATIONTYPE_FSK ) == RF_OPMODE_MODULATIONTYPE_FSK ) + { + tmpRxBw = ( double )XTAL_FREQ / ( tmpMant * ( double )pow( 2, tmpExp + 2 ) ); + } + else + { + tmpRxBw = ( double )XTAL_FREQ / ( tmpMant * ( double )pow( 2, tmpExp + 3 ) ); + } + if( fabs( tmpRxBw - rxBwValue ) < rxBwMin ) + { + rxBwMin = fabs( tmpRxBw - rxBwValue ); + *mantisse = tmpMant; + *exponent = tmpExp; + } + } + } +} + +void SX1276FskSetDccBw( uint8_t* reg, uint32_t dccValue, uint32_t rxBwValue ) +{ + uint8_t mantisse = 0; + uint8_t exponent = 0; + + if( reg == &SX1276->RegRxBw ) + { + *reg = ( uint8_t )dccValue & 0x60; + } + else + { + *reg = 0; + } + + SX1276FskComputeRxBwMantExp( rxBwValue, &mantisse, &exponent ); + + switch( mantisse ) + { + case 16: + *reg |= ( uint8_t )( 0x00 | ( exponent & 0x07 ) ); + break; + case 20: + *reg |= ( uint8_t )( 0x08 | ( exponent & 0x07 ) ); + break; + case 24: + *reg |= ( uint8_t )( 0x10 | ( exponent & 0x07 ) ); + break; + default: + // Something went terribely wrong + break; + } + + if( reg == &SX1276->RegRxBw ) + { + SX1276Write( REG_RXBW, *reg ); + FskSettings.RxBw = rxBwValue; + } + else + { + SX1276Write( REG_AFCBW, *reg ); + FskSettings.RxBwAfc = rxBwValue; + } +} + +uint32_t SX1276FskGetBw( uint8_t* reg ) +{ + uint32_t rxBwValue = 0; + uint8_t mantisse = 0; + switch( ( *reg & 0x18 ) >> 3 ) + { + case 0: + mantisse = 16; + break; + case 1: + mantisse = 20; + break; + case 2: + mantisse = 24; + break; + default: + break; + } + rxBwValue = SX1276FskComputeRxBw( mantisse, ( uint8_t )*reg & 0x07 ); + if( reg == &SX1276->RegRxBw ) + { + return FskSettings.RxBw = rxBwValue; + } + else + { + return FskSettings.RxBwAfc = rxBwValue; + } +} + +void SX1276FskSetPacketCrcOn( bool enable ) +{ + SX1276Read( REG_PACKETCONFIG1, &SX1276->RegPacketConfig1 ); + SX1276->RegPacketConfig1 = ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_MASK ) | ( enable << 4 ); + SX1276Write( REG_PACKETCONFIG1, SX1276->RegPacketConfig1 ); + FskSettings.CrcOn = enable; +} + +bool SX1276FskGetPacketCrcOn( void ) +{ + SX1276Read( REG_PACKETCONFIG1, &SX1276->RegPacketConfig1 ); + FskSettings.CrcOn = ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_ON ) >> 4; + return FskSettings.CrcOn; +} + +void SX1276FskSetAfcOn( bool enable ) +{ + SX1276Read( REG_RXCONFIG, &SX1276->RegRxConfig ); + SX1276->RegRxConfig = ( SX1276->RegRxConfig & RF_RXCONFIG_AFCAUTO_MASK ) | ( enable << 4 ); + SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig ); + FskSettings.AfcOn = enable; +} + +bool SX1276FskGetAfcOn( void ) +{ + SX1276Read( REG_RXCONFIG, &SX1276->RegRxConfig ); + FskSettings.AfcOn = ( SX1276->RegRxConfig & RF_RXCONFIG_AFCAUTO_ON ) >> 4; + return FskSettings.AfcOn; +} + +void SX1276FskSetPayloadLength( uint8_t value ) +{ + SX1276->RegPayloadLength = value; + SX1276Write( REG_PAYLOADLENGTH, SX1276->RegPayloadLength ); + FskSettings.PayloadLength = value; +} + +uint8_t SX1276FskGetPayloadLength( void ) +{ + SX1276Read( REG_PAYLOADLENGTH, &SX1276->RegPayloadLength ); + FskSettings.PayloadLength = SX1276->RegPayloadLength; + return FskSettings.PayloadLength; +} + +void SX1276FskSetPa20dBm( bool enale ) +{ + SX1276Read( REG_PADAC, &SX1276->RegPaDac ); + SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig ); + + if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) + { + if( enale == true ) + { + SX1276->RegPaDac = 0x87; + } + } + else + { + SX1276->RegPaDac = 0x84; + } + SX1276Write( REG_PADAC, SX1276->RegPaDac ); +} + +bool SX1276FskGetPa20dBm( void ) +{ + SX1276Read( REG_PADAC, &SX1276->RegPaDac ); + + return ( ( SX1276->RegPaDac & 0x07 ) == 0x07 ) ? true : false; +} + +void SX1276FskSetPAOutput( uint8_t outputPin ) +{ + SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig ); + SX1276->RegPaConfig = (SX1276->RegPaConfig & RF_PACONFIG_PASELECT_MASK ) | outputPin; + SX1276Write( REG_PACONFIG, SX1276->RegPaConfig ); +} + +uint8_t SX1276FskGetPAOutput( void ) +{ + SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig ); + return SX1276->RegPaConfig & ~RF_PACONFIG_PASELECT_MASK; +} + + +void SX1276FskSetPaRamp( uint8_t value ) +{ + SX1276Read( REG_PARAMP, &SX1276->RegPaRamp ); + SX1276->RegPaRamp = ( SX1276->RegPaRamp & RF_PARAMP_MASK ) | ( value & ~RF_PARAMP_MASK ); + SX1276Write( REG_PARAMP, SX1276->RegPaRamp ); +} + +uint8_t SX1276FskGetPaRamp( void ) +{ + SX1276Read( REG_PARAMP, &SX1276->RegPaRamp ); + return SX1276->RegPaRamp & ~RF_PARAMP_MASK; +} + +void SX1276FskSetRssiOffset( int8_t offset ) +{ + SX1276Read( REG_RSSICONFIG, &SX1276->RegRssiConfig ); + if( offset < 0 ) + { + offset = ( ~offset & 0x1F ); + offset += 1; + offset = -offset; + } + SX1276->RegRssiConfig |= ( uint8_t )( ( offset & 0x1F ) << 3 ); + SX1276Write( REG_RSSICONFIG, SX1276->RegRssiConfig ); +} + +int8_t SX1276FskGetRssiOffset( void ) +{ + int8_t offset; + SX1276Read( REG_RSSICONFIG, &SX1276->RegRssiConfig ); + offset = SX1276->RegRssiConfig >> 3; + if( ( offset & 0x10 ) == 0x10 ) + { + offset = ( ~offset & 0x1F ); + offset += 1; + offset = -offset; + } + return offset; +} + +int8_t SX1276FskGetRawTemp( void ) +{ + int8_t temp = 0; + uint8_t previousOpMode; + uint32_t startTick; + + // Enable Temperature reading + SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal ); + SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_ON; + SX1276Write( REG_IMAGECAL, SX1276->RegImageCal ); + + // save current Op Mode + SX1276Read( REG_OPMODE, &SX1276->RegOpMode ); + previousOpMode = SX1276->RegOpMode; + + // put device in FSK RxSynth + SX1276->RegOpMode = RF_OPMODE_SYNTHESIZER_RX; + SX1276Write( REG_OPMODE, SX1276->RegOpMode ); + + // Wait 1ms + startTick = GET_TICK_COUNT( ); + while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 1 ) ); + + // Disable Temperature reading + SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal ); + SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_OFF; + SX1276Write( REG_IMAGECAL, SX1276->RegImageCal ); + + // Read temperature + SX1276Read( REG_TEMP, &SX1276->RegTemp ); + + temp = SX1276->RegTemp & 0x7F; + + if( ( SX1276->RegTemp & 0x80 ) == 0x80 ) + { + temp *= -1; + } + + // Reload previous Op Mode + SX1276Write( REG_OPMODE, previousOpMode ); + + return temp; +} + +int8_t SX1276FskCalibreateTemp( int8_t actualTemp ) +{ + return actualTemp - SX1276FskGetRawTemp( ); +} + +int8_t SX1276FskGetTemp( int8_t compensationFactor ) +{ + return SX1276FskGetRawTemp( ) + compensationFactor; +} + +#endif // USE_SX1276_RADIO diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.h new file mode 100644 index 000000000..583264bca --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.h @@ -0,0 +1,251 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276-FskMisc.h + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.B2 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-FskMisc.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#ifndef __SX1276_FSK_MISC_H__ +#define __SX1276_FSK_MISC_H__ + +/*! + * \brief Writes the new RF frequency value + * + * \param [IN] freq New RF frequency value in [Hz] + */ +void SX1276FskSetRFFrequency( uint32_t freq ); + +/*! + * \brief Reads the current RF frequency value + * + * \retval freq Current RF frequency value in [Hz] + */ +uint32_t SX1276FskGetRFFrequency( void ); + +/*! + * \brief Calibrate RSSI and I/Q mismatch for HF + * + * \retval none + */ +void SX1276FskRxCalibrate( void ); + +/*! + * \brief Writes the new bitrate value + * + * \param [IN] bitrate New bitrate value in [bps] + */ +void SX1276FskSetBitrate( uint32_t bitrate ); + +/*! + * \brief Reads the current bitrate value + * + * \retval bitrate Current bitrate value in [bps] + */ +uint32_t SX1276FskGetBitrate( void ); + +/*! + * \brief Writes the new frequency deviation value + * + * \param [IN] fdev New frequency deviation value in [Hz] + */ +void SX1276FskSetFdev( uint32_t fdev ); + +/*! + * \brief Reads the current frequency deviation value + * + * \retval fdev Current frequency deviation value in [Hz] + */ +uint32_t SX1276FskGetFdev( void ); + +/*! + * \brief Writes the new RF output power value + * + * \param [IN] power New output power value in [dBm] + */ +void SX1276FskSetRFPower( int8_t power ); + +/*! + * \brief Reads the current RF output power value + * + * \retval power Current output power value in [dBm] + */ +int8_t SX1276FskGetRFPower( void ); + +/*! + * \brief Writes the DC offset canceller and Rx bandwidth values + * + * \remark For SX1276 there is no DCC setting. dccValue should be 0 + * ie: SX1276SetDccBw( &SX1276.RegRxBw, 0, 62500 ); + * + * \param [IN] reg Register pointer to either SX1231.RegRxBw or SX1231.RegAfcBw + * \param [IN] dccValue New DC offset canceller value in [Hz] ( SX1231 only ) + * \param [IN] rxBwValue New Rx bandwidth value in [Hz] + */ +void SX1276FskSetDccBw( uint8_t* reg, uint32_t dccValue, uint32_t rxBwValue ); + +/*! + * \brief Reads the current bandwidth setting + * + * \param [IN] reg Register pointer to either SX1231.RegRxBw or SX1231.RegAfcBw + * + * \retval bandwidth Bandwidth value + */ +uint32_t SX1276FskGetBw( uint8_t* reg ); + +/*! + * \brief Enables/Disables CRC + * + * \param [IN] enable CRC enable/disable + */ +void SX1276FskSetPacketCrcOn( bool enable ); + +/*! + * \brief Reads the current CRC Enable/Disbale value + * + * \retval enable Current CRC Enable/Disbale value + */ +bool SX1276FskGetPacketCrcOn( void ); + +/*! + * \brief Enables/Disables AFC + * + * \param [IN] enable AFC enable/disable + */ +void SX1276FskSetAfcOn( bool enable ); + +/*! + * \brief Reads the current AFC Enable/Disbale value + * + * \retval enable Current AFC Enable/Disbale value + */ +bool SX1276FskGetAfcOn( void ); + +/*! + * \brief Writes the new payload length value + * + * \param [IN] value New payload length value + */ +void SX1276FskSetPayloadLength( uint8_t value ); + +/*! + * \brief Reads the current payload length value + * + * \retval value Current payload length value + */ +uint8_t SX1276FskGetPayloadLength( void ); + +/*! + * \brief Enables/Disables the 20 dBm PA + * + * \param [IN] enable [true, false] + */ +void SX1276FskSetPa20dBm( bool enale ); + +/*! + * \brief Gets the current 20 dBm PA status + * + * \retval enable [true, false] + */ +bool SX1276FskGetPa20dBm( void ); + +/*! + * \brief Set the RF Output pin + * + * \param [IN] RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO + */ +void SX1276FskSetPAOutput( uint8_t outputPin ); + +/*! + * \brief Gets the used RF Ouptu pin + * + * \retval RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO + */ +uint8_t SX1276FskGetPAOutput( void ); + +/*! + * \brief Writes the new PA rise/fall time of ramp up/down value + * + * \param [IN] value New PaRamp value + */ +void SX1276FskSetPaRamp( uint8_t value ); + +/*! + * \brief Reads the current PA rise/fall time of ramp up/down value + * + * \retval value Current PaRamp value + */ +uint8_t SX1276FskGetPaRamp( void ); + +/*! + * \brief Applies an offset to the RSSI. Compensates board components + * + * \param [IN] offset Offset to be applied (+/-) + */ +void SX1276FskSetRssiOffset( int8_t offset ); + +/*! + * \brief Gets the current RSSI offset. + * + * \retval offset Current offset (+/-) + */ +int8_t SX1276FskGetRssiOffset( void ); + +/*! + * \brief Writes the new value for the preamble size + * + * \param [IN] size New value of pramble size + */ +void SX1276FskSetPreambleSize( uint16_t size ); + +/*! + * Reads the raw temperature + * \retval temperature New raw temperature reading in 2's complement format + */ +int8_t SX1276FskGetRawTemp( void ); + +/*! + * Computes the temperature compensation factor + * \param [IN] actualTemp Actual temperature measured by an external device + * \retval compensationFactor Computed compensation factor + */ +int8_t SX1276FskCalibreateTemp( int8_t actualTemp ); + +/*! + * Gets the actual compensated temperature + * \param [IN] compensationFactor Return value of the calibration function + * \retval New compensated temperature value + */ +int8_t SX1276FskGetTemp( int8_t compensationFactor ); + +#endif //__SX1276_FSK_MISC_H__ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Hal.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Hal.h new file mode 100644 index 000000000..cc21c3b54 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Hal.h @@ -0,0 +1,170 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276-Hal.h + * \brief SX1276 Hardware Abstraction Layer + * + * \version 2.0.B2 + * \date Nov 21 2012 + * \author Miguel Luis + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-Hal.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#ifndef __SX1276_HAL_H__ +#define __SX1276_HAL_H__ +#include "platform.h" + +/*! + * DIO state read functions mapping + */ +#define DIO0 SX1276ReadDio0( ) +#define DIO1 SX1276ReadDio1( ) +#define DIO2 SX1276ReadDio2( ) +#define DIO3 SX1276ReadDio3( ) +#define DIO4 SX1276ReadDio4( ) +#define DIO5 SX1276ReadDio5( ) + +// RXTX pin control see errata note +#define RXTX( txEnable ) SX1276WriteRxTx( txEnable ); + +#define GET_TICK_COUNT( ) CurrentTicksGain() +#define TICK_RATE_MS( ms ) ( ms ) + +typedef enum +{ + RADIO_RESET_OFF, + RADIO_RESET_ON, +}tRadioResetState; + +/*! + * \brief Initializes the radio interface I/Os + */ +void SX1276InitIo( void ); + +/*! + * \brief Set the radio reset pin state + * + * \param state New reset pin state + */ +void SX1276SetReset( uint8_t state ); + +/*! + * \brief Writes the radio register at the specified address + * + * \param [IN]: addr Register address + * \param [IN]: data New register value + */ +void SX1276Write( uint8_t addr, uint8_t data ); + +/*! + * \brief Reads the radio register at the specified address + * + * \param [IN]: addr Register address + * \param [OUT]: data Register value + */ +void SX1276Read( uint8_t addr, uint8_t *data ); + +/*! + * \brief Writes multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [IN] buffer Buffer containing the new register's values + * \param [IN] size Number of registers to be written + */ +void SX1276WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Reads multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [OUT] buffer Buffer where to copy the registers data + * \param [IN] size Number of registers to be read + */ +void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Writes the buffer contents to the radio FIFO + * + * \param [IN] buffer Buffer containing data to be put on the FIFO. + * \param [IN] size Number of bytes to be written to the FIFO + */ +void SX1276WriteFifo( uint8_t *buffer, uint8_t size ); + +/*! + * \brief Reads the contents of the radio FIFO + * + * \param [OUT] buffer Buffer where to copy the FIFO read data. + * \param [IN] size Number of bytes to be read from the FIFO + */ +void SX1276ReadFifo( uint8_t *buffer, uint8_t size ); + +/*! + * \brief Gets the SX1276 DIO0 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio0( void ); + +/*! + * \brief Ge// USE_SX1276_RADIOts the SX1276 DIO1 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio1( void ); + +/*! + * \brief Gets the SX1276 DIO2 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio2( void ); + +/*! + * \brief Gets the SX1276 DIO3 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio3( void ); + +/*! + * \brief Gets the SX1276 DIO4 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio4( void ); + +/*! + * \brief Gets the SX1276 DIO5 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio5( void ); + +/*! + * \brief Writes the external RxTx pin value + * + * \remark see errata note + * + * \param [IN] txEnable [1: Tx, 0: Rx] + */ +inline void SX1276WriteRxTx( uint8_t txEnable ); + +#endif //__SX1276_HAL_H__ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.c new file mode 100644 index 000000000..60d9b5e61 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.c @@ -0,0 +1,723 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Original Copyright (C) SEMTECH S.A. + * Modified Copyright (C) 2020 AIIT XUOS Lab + */ +/*! + * \file sx1276-LoRa.c + * \brief SX1276 RF chip driver mode LoRa + * + * \version 2.0.0 + * \date Nov 21 2012 + * \author Miguel Luis + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-LoRa.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#include + +#include "platform.h" + +#if defined( USE_SX1276_RADIO ) +#include "radio.h" +#include "sx1276-Hal.h" +#include "sx1276.h" +#include "sx1276-LoRaMisc.h" +#include "sx1276-LoRa.h" + +#define LoRa_FREQENCY 433000000 + +#define RSSI_OFFSET_LF -155.0 +#define RSSI_OFFSET_HF -150.0 + +#define NOISE_ABSOLUTE_ZERO -174.0 +#define NOISE_FIGURE_LF 4.0 +#define NOISE_FIGURE_HF 6.0 + +volatile uint32 TickCounter = 0; + +uint32 Tx_Time_Start,Tx_Time_End; +uint32 Rx_Time_Start,Rx_Time_End; +//Signal bandwidth, used to calculate RSSI +const double SignalBwLog[] = +{ + 3.8927900303521316335038277369285, // 7.8 kHz + 4.0177301567005500940384239336392, // 10.4 kHz + 4.193820026016112828717566631653, // 15.6 kHz + 4.31875866931372901183597627752391, // 20.8 kHz + 4.4948500216800940239313055263775, // 31.2 kHz + 4.6197891057238405255051280399961, // 41.6 kHz + 4.795880017344075219145044421102, // 62.5 kHz + 5.0969100130080564143587833158265, // 125 kHz + 5.397940008672037609572522210551, // 250 kHz + 5.6989700043360188047862611052755 // 500 kHz +}; + +//These values need testing +const double RssiOffsetLF[] = +{ + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, +}; + +//These values need testing +const double RssiOffsetHF[] = +{ + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, +}; + +/*! + * Frequency hopping frequencies table + */ +const int32_t HoppingFrequencies[] = +{ + 916500000, + 923500000, + 906500000, + 917500000, + 917500000, + 909000000, + 903000000, + 916000000, + 912500000, + 926000000, + 925000000, + 909500000, + 913000000, + 918500000, + 918500000, + 902500000, + 911500000, + 926500000, + 902500000, + 922000000, + 924000000, + 903500000, + 913000000, + 922000000, + 926000000, + 910000000, + 920000000, + 922500000, + 911000000, + 922000000, + 909500000, + 926000000, + 922000000, + 918000000, + 925500000, + 908000000, + 917500000, + 926500000, + 908500000, + 916000000, + 905500000, + 916000000, + 903000000, + 905000000, + 915000000, + 913000000, + 907000000, + 910000000, + 926500000, + 925500000, + 911000000, +}; + +// Default settings +tLoRaSettings LoRaSettings = +{ + LoRa_FREQENCY , // RFFrequency + 20, // Power + 9, // SignalBw [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved] + 12, // SpreadingFactor [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips] + 2, // ErrorCoding [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + true, // CrcOn [0: OFF, 1: ON] + false, // ImplicitHeaderOn [0: OFF, 1: ON] + 0, // RxSingleOn [0: Continuous, 1 Single] + 0, // FreqHopOn [0: OFF, 1: ON] + 4, // HopPeriod Hops every frequency hopping period symbols + 1000, // TxPacketTimeout + 1000, // RxPacketTimeout + 128, // PayloadLength (used for implicit header mode) +}; + +/*! + * SX1276 LoRa registers variable + */ +tSX1276LR* SX1276LR; + +/*! + * Local RF buffer for communication support + */ +static uint8_t RFBuffer[RF_BUFFER_SIZE]; +static uint8_t TFBuffer[RF_BUFFER_SIZE]; + +/*! + * RF state machine variable + */ +static uint8_t RFLRState = RFLR_STATE_IDLE; + +/*! + * Rx management support variables + */ +static uint16_t RxPacketSize = 0; +static int8_t RxPacketSnrEstimate; +static double RxPacketRssiValue; +static uint8_t RxGain = 1; +static uint32_t RxTimeoutTimer = 0; + +/*! + * PacketTimeout Stores the Rx window time value for packet reception + */ +static uint32_t PacketTimeout; + +/*! + * Tx management support variables + */ +static uint16_t TxPacketSize = 0; + + +void SX1276LoRaInit( void ) +{ + RFLRState = RFLR_STATE_IDLE; + + SX1276LoRaSetDefaults(); + + SX1276ReadBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 ); + + //SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP ); + + SX1276LR->RegLna = RFLR_LNA_GAIN_G1; + SX1276WriteBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 ); + + // set the RF settings + SX1276LoRaSetRFFrequency( LoRaSettings.RFFrequency ); + SX1276LoRaSetSpreadingFactor( LoRaSettings.SpreadingFactor ); + SX1276LoRaSetErrorCoding( LoRaSettings.ErrorCoding ); + SX1276LoRaSetPacketCrcOn( LoRaSettings.CrcOn ); + SX1276LoRaSetSignalBandwidth( LoRaSettings.SignalBw ); + SX1276LoRaSetImplicitHeaderOn( LoRaSettings.ImplicitHeaderOn ); + + SX1276LoRaSetSymbTimeout(0x3FF); + SX1276LoRaSetPayloadLength( LoRaSettings.PayloadLength ); + SX1276LoRaSetLowDatarateOptimize( true ); + + #if( ( MODULE_SX1276RF1IAS == 1 ) || ( MODULE_SX1276RF1KAS == 1 ) ) + if( LoRaSettings.RFFrequency > 860000000 ) + { + SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_RFO ); + SX1276LoRaSetPa20dBm( false ); + LoRaSettings.Power = 14; + SX1276LoRaSetRFPower( LoRaSettings.Power ); + } + else + { + //SX1276Write( REG_LR_OCP, 0x3f ); + SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_PABOOST ); + SX1276LoRaSetPa20dBm( true ); + LoRaSettings.Power = 20; + SX1276LoRaSetRFPower( LoRaSettings.Power ); + } + #elif( MODULE_SX1276RF1JAS == 1 ) + if( LoRaSettings.RFFrequency > 380000000 ) + { + SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_PABOOST ); + SX1276LoRaSetPa20dBm( true ); + LoRaSettings.Power = 20; + SX1276LoRaSetRFPower( LoRaSettings.Power ); + } + else + { + SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_RFO ); + SX1276LoRaSetPa20dBm( false ); + LoRaSettings.Power = 14; + SX1276LoRaSetRFPower( LoRaSettings.Power ); + } + #endif + SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY ); + + SX1276ReadBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 ); +} + +void SX1276LoRaSetDefaults( void ) +{ + // REMARK: See SX1276 datasheet for modified default values. + + // Sets IF frequency selection manual + SX1276Read( REG_LR_VERSION, &SX1276LR->RegVersion ); +} + +void SX1276LoRaReset( void ) +{ + uint32_t startTick; + + SX1276SetReset( RADIO_RESET_ON ); + + // Wait 1ms + startTick = GET_TICK_COUNT( ); + while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 1 ) ); + + SX1276SetReset( RADIO_RESET_OFF ); + + // Wait 6ms + startTick = GET_TICK_COUNT( ); + while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 6 ) ); +} + +void SX1276LoRaSetOpMode( uint8_t opMode ) +{ + static uint8_t opModePrev = RFLR_OPMODE_STANDBY; + static bool antennaSwitchTxOnPrev = true; + bool antennaSwitchTxOn = false; + opModePrev = SX1276LR->RegOpMode & ~RFLR_OPMODE_MASK; + if( opMode != opModePrev ) + { + if( opMode == RFLR_OPMODE_TRANSMITTER ) + { + antennaSwitchTxOn = true; + } + else + { + antennaSwitchTxOn = false; + } + if( antennaSwitchTxOn != antennaSwitchTxOnPrev ) + { + antennaSwitchTxOnPrev = antennaSwitchTxOn; // Antenna switch control + RXTX( antennaSwitchTxOn ); + } + SX1276LR->RegOpMode = ( SX1276LR->RegOpMode & RFLR_OPMODE_MASK ) | opMode | RFLR_OPMODE_FREQMODE_ACCESS_LF; + + SX1276Write( REG_LR_OPMODE, SX1276LR->RegOpMode ); + } +} + +uint8_t SX1276LoRaGetOpMode( void ) +{ + SX1276Read( REG_LR_OPMODE, &SX1276LR->RegOpMode ); + + return SX1276LR->RegOpMode & ~RFLR_OPMODE_MASK; +} + +uint8_t SX1276LoRaReadRxGain( void ) +{ + + SX1276Read( REG_LR_LNA, &SX1276LR->RegLna ); + return( SX1276LR->RegLna >> 5 ) & 0x07; +} + +double SX1276LoRaReadRssi( void ) +{ + // Reads the RSSI value + SX1276Read( REG_LR_RSSIVALUE, &SX1276LR->RegRssiValue ); + + if( LoRaSettings.RFFrequency < 860000000 ) + { + return RssiOffsetLF[LoRaSettings.SignalBw] + ( double )SX1276LR->RegRssiValue; + } + else + { + return RssiOffsetHF[LoRaSettings.SignalBw] + ( double )SX1276LR->RegRssiValue; + } +} + +uint8_t SX1276LoRaGetPacketRxGain( void ) +{ + return RxGain; +} + +int8_t SX1276LoRaGetPacketSnr( void ) +{ + return RxPacketSnrEstimate; +} + +double SX1276LoRaGetPacketRssi( void ) +{ + return RxPacketRssiValue; +} + +void SX1276LoRaStartRx( void ) +{ + SX1276LoRaSetRFState( RFLR_STATE_RX_INIT ); +} + +void SX1276LoRaGetRxPacket( void *buffer, uint16_t *size ) +{ + *size = RxPacketSize; + RxPacketSize = 0; + memcpy( (void*)buffer, (void*)RFBuffer, (size_t)*size ); +} + +void SX1276LoRaSetTxPacket( const void *buffer, uint16_t size ) +{ + if( LoRaSettings.FreqHopOn == false ) + { + TxPacketSize = size; + } + else + { + TxPacketSize = 255; + } + memcpy( ( void * )TFBuffer, buffer, ( size_t )TxPacketSize ); + + RFLRState = RFLR_STATE_TX_INIT; +} + +uint8_t SX1276LoRaGetRFState( void ) +{ + return RFLRState; +} + +void SX1276LoRaSetRFState( uint8_t state ) +{ + RFLRState = state; +} + +/*! + * \brief Process the LoRa modem Rx and Tx state machines depending on the + * SX1276 operating mode. + * + * \retval rfState Current RF state [RF_IDLE, RF_BUSY, + * RF_RX_DONE, RF_RX_TIMEOUT, + * RF_TX_DONE, RF_TX_TIMEOUT] + */ +uint32_t SX1276LoRaProcess( void ) +{ + uint32_t result = RF_BUSY; + uint8_t regValue = 0; + + switch( RFLRState ) + { + case RFLR_STATE_IDLE: + break; + case RFLR_STATE_RX_INIT: + SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY); + SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT | + //RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | + RFLR_IRQFLAGS_CADDETECTED; + SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask ); + + if(LoRaSettings.FreqHopOn == true ) + { + SX1276LR->RegHopPeriod = LoRaSettings.HopPeriod; + + SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel ); + SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); + } + else + { + SX1276LR->RegHopPeriod = 255; + } + + SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod ); + + if( LoRaSettings.RxSingleOn == true ) // Rx single mode + { + SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER_SINGLE ); + } + else // Rx continuous mode + { + SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxBaseAddr; + + SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr ); + SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER ); + } + memset( RFBuffer, 0, ( size_t )RF_BUFFER_SIZE ); + Rx_Time_Start=TickCounter; + PacketTimeout = LoRaSettings.RxPacketTimeout; + RxTimeoutTimer = GET_TICK_COUNT( ); + RFLRState = RFLR_STATE_RX_RUNNING; + break; + case RFLR_STATE_RX_RUNNING: + SX1276Read(0x12, ®Value); + // RxDone + if(regValue & (1<<6)) + { + RxTimeoutTimer = GET_TICK_COUNT( ); + if( LoRaSettings.FreqHopOn == true ) + { + SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel ); + SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); + } + // Clear Irq + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE ); + RFLRState = RFLR_STATE_RX_DONE; + } + // FHSS Changed Channel + if(regValue & (1<<1)) + { + RxTimeoutTimer = GET_TICK_COUNT( ); + if( LoRaSettings.FreqHopOn == true ) + { + SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel ); + SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); + } + // Clear Irq + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); + //RxGain = SX1276LoRaReadRxGain( ); + } + if( LoRaSettings.RxSingleOn == true ) // Rx single mode + { + if( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ) + { + RFLRState = RFLR_STATE_RX_TIMEOUT; + } + } + break; + case RFLR_STATE_RX_DONE: + SX1276Read( REG_LR_IRQFLAGS, &SX1276LR->RegIrqFlags ); + if( ( SX1276LR->RegIrqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR ) == RFLR_IRQFLAGS_PAYLOADCRCERROR ) + { + // Clear Irq + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR ); + if( LoRaSettings.RxSingleOn == true ) // Rx single mode + { + RFLRState = RFLR_STATE_RX_INIT; + } + else + { + RFLRState = RFLR_STATE_RX_RUNNING; + } + break; + } + + if( LoRaSettings.RxSingleOn == true ) // Rx single mode + { + SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxBaseAddr; + SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr ); + if( LoRaSettings.ImplicitHeaderOn == true ) + { + RxPacketSize = SX1276LR->RegPayloadLength; + SX1276ReadFifo( RFBuffer, SX1276LR->RegPayloadLength ); + } + else + { + SX1276Read( REG_LR_NBRXBYTES, &SX1276LR->RegNbRxBytes ); + RxPacketSize = SX1276LR->RegNbRxBytes; + SX1276ReadFifo( RFBuffer, SX1276LR->RegNbRxBytes ); + } + } + else // Rx continuous mode + { + SX1276Read( REG_LR_FIFORXCURRENTADDR, &SX1276LR->RegFifoRxCurrentAddr ); + if( LoRaSettings.ImplicitHeaderOn == true ) + { + RxPacketSize = SX1276LR->RegPayloadLength; + SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxCurrentAddr; + SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr ); + SX1276ReadFifo( RFBuffer, SX1276LR->RegPayloadLength ); + } + else + { + SX1276Read( REG_LR_NBRXBYTES, &SX1276LR->RegNbRxBytes ); + RxPacketSize = SX1276LR->RegNbRxBytes; + SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxCurrentAddr; + SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr ); + SX1276ReadFifo( RFBuffer, SX1276LR->RegNbRxBytes ); + } + } + if( LoRaSettings.RxSingleOn == true ) // Rx single mode + { + RFLRState = RFLR_STATE_RX_INIT; + } + else // Rx continuous mode + { + RFLRState = RFLR_STATE_RX_RUNNING; + } + Rx_Time_End=TickCounter; + result = RF_RX_DONE; + break; + case RFLR_STATE_RX_TIMEOUT: + RFLRState = RFLR_STATE_RX_INIT; + result = RF_RX_TIMEOUT; + break; + case RFLR_STATE_TX_INIT: + Tx_Time_Start = TickCounter; + + // Initializes the payload size + SX1276LR->RegPayloadLength = TxPacketSize; + SX1276Write( REG_LR_PAYLOADLENGTH, SX1276LR->RegPayloadLength ); + + SX1276LR->RegFifoTxBaseAddr = 0x00; // Full buffer used for Tx + SX1276Write( REG_LR_FIFOTXBASEADDR, SX1276LR->RegFifoTxBaseAddr ); + + SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoTxBaseAddr; + SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr ); + + SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY ); + + // Write payload buffer to LORA modem + SX1276WriteFifo( TFBuffer, SX1276LR->RegPayloadLength ); + + if( LoRaSettings.FreqHopOn == true ) + { + SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + //RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | + RFLR_IRQFLAGS_CADDETECTED; + SX1276LR->RegHopPeriod = LoRaSettings.HopPeriod; + SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel ); + SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); + } + else + { + SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + //RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | + RFLR_IRQFLAGS_CADDETECTED; + SX1276LR->RegHopPeriod = 0; + } + SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod ); + SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask ); + + SX1276Write( REG_LR_DIOMAPPING1, ( regValue & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );//DIO0设置为TXdone中断 + + SX1276LoRaSetOpMode( RFLR_OPMODE_TRANSMITTER ); + + RFLRState = RFLR_STATE_TX_RUNNING; + break; + case RFLR_STATE_TX_RUNNING: + SX1276Read(0x12, ®Value); + if(regValue & (1<<3)) + { + // Clear Irq + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE ); + RFLRState = RFLR_STATE_TX_DONE; + } + // FHSS Changed Channel + if(regValue & (1<<3)) + { + if( LoRaSettings.FreqHopOn == true ) + { + SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel ); + SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); + } + // Clear Irq + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); + } + break; + case RFLR_STATE_TX_DONE: + Tx_Time_End=TickCounter; + SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY ); + RFLRState = RFLR_STATE_IDLE; + result = RF_TX_DONE; + break; + case RFLR_STATE_CAD_INIT: + // optimize the power consumption by switching off the transmitter as soon as the packet has been sent + SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY ); + SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_TXDONE | + //RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL; + //RFLR_IRQFLAGS_CADDETECTED; + SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask ); + + SX1276LoRaSetOpMode( RFLR_OPMODE_CAD ); + RFLRState = RFLR_STATE_CAD_RUNNING; + + break; + case RFLR_STATE_CAD_RUNNING: + SX1276Read(0x12,®Value); + int cad_done = regValue & (1<<2); + int cad_detected = regValue & (1<<0); + + if( cad_done ) //CAD Done interrupt + { + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE ); + if( cad_detected ) // CAD Detected interrupt + { + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED ); + //CAD detected, we have a LoRa preamble + RFLRState = RFLR_STATE_RX_INIT; + result = RF_CHANNEL_ACTIVITY_DETECTED; + } + else + { + // The device goes in Standby Mode automatically + RFLRState = RFLR_STATE_IDLE; + result = RF_CHANNEL_EMPTY; + } + } + break; + default: + break; + } + return result; +} + +uint32_t SX1276LoraChannelEmpty( void ) +{ + uint32_t result = 0; + RFLRState = RFLR_STATE_CAD_INIT; + SX1276LoRaProcess(); + while(RFLRState == RFLR_STATE_CAD_RUNNING) + { + //KPrintf("\nLora--SX1276LoRaProcess()"); + result = SX1276LoRaProcess(); + } + + if(result == RF_CHANNEL_EMPTY) + { + KPrintf("\nLora--RF_CHANNEL_EMPTY\n"); + return 0; + } + else if(result == RF_CHANNEL_ACTIVITY_DETECTED) + { + KPrintf("\nLora--RF_CHANNEL_ACTIVITY_DETECTED\n"); + return 1; + } + else + { + return 2; + } +} + +#endif // USE_SX1276_RADIO \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.h new file mode 100644 index 000000000..76400e6b8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.h @@ -0,0 +1,820 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Original Copyright (C) SEMTECH S.A. + * Modified Copyright (C) 2020 AIIT XUOS Lab + */ +/*! + * \file sx1276-LoRa.h + * \brief SX1276 RF chip driver mode LoRa + * + * \version 2.0.0 + * \date Nov 21 2012 + * \author Miguel Luis + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-LoRa.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#ifndef __SX1276_LORA_H__ +#define __SX1276_LORA_H__ + +#include "stdint.h" +#include "stdbool.h" + + +//SX1276一些配置参数设置 +typedef struct sLoRaSettings +{ + uint32_t RFFrequency; //无线通信频率 + int8_t Power; //功率 + uint8_t SignalBw; //LORA 带宽[0: 7.8 kHz, 1: 10.4 kHz, 2: 15.6 kHz, 3: 20.8 kHz, 4: 31.2 kHz, + //5: 41.6 kHz, 6: 62.5 kHz, 7: 125 kHz, 8: 250 kHz, 9: 500 kHz, other: Reserved] + uint8_t SpreadingFactor; //扩频因子 LORA [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips] + uint8_t ErrorCoding; //LORA 纠错码 [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + bool CrcOn; //CRC效验开关 [0: OFF, 1: ON] + bool ImplicitHeaderOn; //隐藏头部信息开关 [0: OFF, 1: ON] + bool RxSingleOn; //接收单次模式\连续模式配置[0: Continuous, 1 Single] + bool FreqHopOn; //跳频模式开关 [0: OFF, 1: ON] + uint8_t HopPeriod; //跳频之间的周期长度 Hops every frequency hopping period symbols + uint32_t TxPacketTimeout; //最大发送时间 + uint32_t RxPacketTimeout; //最大接收时间 + uint8_t PayloadLength; //数据长度 +}tLoRaSettings; + +//RF数据包大小(模块配备了256Byte的RAM缓存,该缓存仅能通过LoRa模式访问) +#define RF_BUFFER_SIZE_MAX 256 +#define RF_BUFFER_SIZE 256 + + +//LoRa的返回值 +typedef enum +{ + RFLR_STATE_IDLE, + RFLR_STATE_RX_INIT, + RFLR_STATE_RX_RUNNING, + RFLR_STATE_RX_DONE, + RFLR_STATE_RX_TIMEOUT, + RFLR_STATE_TX_INIT, + RFLR_STATE_TX_RUNNING, + RFLR_STATE_TX_DONE, + RFLR_STATE_TX_TIMEOUT, + RFLR_STATE_CAD_INIT, + RFLR_STATE_CAD_RUNNING, +}tRFLRStates; + + +//SX1276 definitions +#define XTAL_FREQ 32000000 +#define FREQ_STEP 61.03515625 + +/*LoRa模式寄存器映射*/ +//SX1276内部寄存器地址 +#define REG_LR_FIFO 0x00 //FIFO 数据输入/输出。当器件处于睡眠模式时,FIFO被清零,无法访问。 + +//通用寄存器 +#define REG_LR_OPMODE 0x01 //关于模式选择相关的寄存器 +#define REG_LR_BANDSETTING 0x04 +#define REG_LR_FRFMSB 0x06 //RF 载波频率最高有效位 +#define REG_LR_FRFMID 0x07 //RF 载波频率中间有效位 +#define REG_LR_FRFLSB 0x08 //RF 载波频率最低有效位 + +//RF模块寄存器 +#define REG_LR_PACONFIG 0x09 +#define REG_LR_PARAMP 0x0A +#define REG_LR_OCP 0x0B +#define REG_LR_LNA 0x0C + +//LoRa页面寄存器 +#define REG_LR_FIFOADDRPTR 0x0D +#define REG_LR_FIFOTXBASEADDR 0x0E +#define REG_LR_FIFORXBASEADDR 0x0F +#define REG_LR_FIFORXCURRENTADDR 0x10 +#define REG_LR_IRQFLAGSMASK 0x11 //IAQ标志屏蔽 +#define REG_LR_IRQFLAGS 0x12 +#define REG_LR_NBRXBYTES 0x13 +#define REG_LR_RXHEADERCNTVALUEMSB 0x14 +#define REG_LR_RXHEADERCNTVALUELSB 0x15 +#define REG_LR_RXPACKETCNTVALUEMSB 0x16 +#define REG_LR_RXPACKETCNTVALUELSB 0x17 +#define REG_LR_MODEMSTAT 0x18 +#define REG_LR_PKTSNRVALUE 0x19 +#define REG_LR_PKTRSSIVALUE 0x1A +#define REG_LR_RSSIVALUE 0x1B +#define REG_LR_HOPCHANNEL 0x1C +#define REG_LR_MODEMCONFIG1 0x1D +#define REG_LR_MODEMCONFIG2 0x1E +#define REG_LR_SYMBTIMEOUTLSB 0x1F +#define REG_LR_PREAMBLEMSB 0x20 +#define REG_LR_PREAMBLELSB 0x21 +#define REG_LR_PAYLOADLENGTH 0x22 +#define REG_LR_PAYLOADMAXLENGTH 0x23 +#define REG_LR_HOPPERIOD 0x24 +#define REG_LR_FIFORXBYTEADDR 0x25 +#define REG_LR_MODEMCONFIG3 0x26 +/*以上是LoRa模式寄存器映射*/ + +//IO控制寄存器(关于DI00-DI05的映射设置) +#define REG_LR_DIOMAPPING1 0x40 +#define REG_LR_DIOMAPPING2 0x41 + +//版本寄存器 +#define REG_LR_VERSION 0x42 + +//附加寄存器 +#define REG_LR_PLLHOP 0x44 +#define REG_LR_TCXO 0x4B +#define REG_LR_PADAC 0x4D +#define REG_LR_FORMERTEMP 0x5B +#define REG_LR_BITRATEFRAC 0x5D +#define REG_LR_AGCREF 0x61 +#define REG_LR_AGCTHRESH1 0x62 +#define REG_LR_AGCTHRESH2 0x63 +#define REG_LR_AGCTHRESH3 0x64 + +//与模式选择相关的宏定义 RegOpMode(寄存器地址0X01) +#define RFLR_OPMODE_LONGRANGEMODE_MASK 0x7F +#define RFLR_OPMODE_LONGRANGEMODE_OFF 0x00 // Default +#define RFLR_OPMODE_LONGRANGEMODE_ON 0x80 + +#define RFLR_OPMODE_ACCESSSHAREDREG_MASK 0xBF +#define RFLR_OPMODE_ACCESSSHAREDREG_ENABLE 0x40 +#define RFLR_OPMODE_ACCESSSHAREDREG_DISABLE 0x00 // Default + +#define RFLR_OPMODE_FREQMODE_ACCESS_MASK 0xF7 +#define RFLR_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default +#define RFLR_OPMODE_FREQMODE_ACCESS_HF 0x00 + +#define RFLR_OPMODE_MASK 0xF8 +#define RFLR_OPMODE_SLEEP 0x00 //睡眠模式 +#define RFLR_OPMODE_STANDBY 0x01 //待机模式 +#define RFLR_OPMODE_SYNTHESIZER_TX 0x02 //频率合成器转换至Tx频率 +#define RFLR_OPMODE_TRANSMITTER 0x03 //发送模式 +#define RFLR_OPMODE_SYNTHESIZER_RX 0x04 //频率合成器转换至Rx频率 +#define RFLR_OPMODE_RECEIVER 0x05 //接收模式 + +#define RFLR_OPMODE_RECEIVER_SINGLE 0x06 //单次接收模式 +#define RFLR_OPMODE_CAD 0x07 //CAD模式 + +//与位带操作相关的宏定义 +#define RFLR_BANDSETTING_MASK 0x3F +#define RFLR_BANDSETTING_AUTO 0x00 // Default +#define RFLR_BANDSETTING_DIV_BY_1 0x40 +#define RFLR_BANDSETTING_DIV_BY_2 0x80 +#define RFLR_BANDSETTING_DIV_BY_6 0xC0 + +//射频载波频率设置相关宏定义 RegFrf (MHz)(寄存器地址0x06,0x07,0x08) +#define RFLR_FRFMSB_434_MHZ 0x6C // Default +#define RFLR_FRFMID_434_MHZ 0x80 // Default +#define RFLR_FRFLSB_434_MHZ 0x00 // Default + +#define RFLR_FRFMSB_470_MHZ 0x73 // Default +#define RFLR_FRFMID_470_MHZ 0xBB // Default +#define RFLR_FRFLSB_470_MHZ 0xBB // Default + +#define RFLR_FRFMSB_863_MHZ 0xD7 +#define RFLR_FRFMID_863_MHZ 0xC0 +#define RFLR_FRFLSB_863_MHZ 0x00 +#define RFLR_FRFMSB_864_MHZ 0xD8 +#define RFLR_FRFMID_864_MHZ 0x00 +#define RFLR_FRFLSB_864_MHZ 0x00 +#define RFLR_FRFMSB_865_MHZ 0xD8 +#define RFLR_FRFMID_865_MHZ 0x40 +#define RFLR_FRFLSB_865_MHZ 0x00 +#define RFLR_FRFMSB_866_MHZ 0xD8 +#define RFLR_FRFMID_866_MHZ 0x80 +#define RFLR_FRFLSB_866_MHZ 0x00 +#define RFLR_FRFMSB_867_MHZ 0xD8 +#define RFLR_FRFMID_867_MHZ 0xC0 +#define RFLR_FRFLSB_867_MHZ 0x00 +#define RFLR_FRFMSB_868_MHZ 0xD9 +#define RFLR_FRFMID_868_MHZ 0x00 +#define RFLR_FRFLSB_868_MHZ 0x00 +#define RFLR_FRFMSB_869_MHZ 0xD9 +#define RFLR_FRFMID_869_MHZ 0x40 +#define RFLR_FRFLSB_869_MHZ 0x00 +#define RFLR_FRFMSB_870_MHZ 0xD9 +#define RFLR_FRFMID_870_MHZ 0x80 +#define RFLR_FRFLSB_870_MHZ 0x00 + +#define RFLR_FRFMSB_902_MHZ 0xE1 +#define RFLR_FRFMID_902_MHZ 0x80 +#define RFLR_FRFLSB_902_MHZ 0x00 +#define RFLR_FRFMSB_903_MHZ 0xE1 +#define RFLR_FRFMID_903_MHZ 0xC0 +#define RFLR_FRFLSB_903_MHZ 0x00 +#define RFLR_FRFMSB_904_MHZ 0xE2 +#define RFLR_FRFMID_904_MHZ 0x00 +#define RFLR_FRFLSB_904_MHZ 0x00 +#define RFLR_FRFMSB_905_MHZ 0xE2 +#define RFLR_FRFMID_905_MHZ 0x40 +#define RFLR_FRFLSB_905_MHZ 0x00 +#define RFLR_FRFMSB_906_MHZ 0xE2 +#define RFLR_FRFMID_906_MHZ 0x80 +#define RFLR_FRFLSB_906_MHZ 0x00 +#define RFLR_FRFMSB_907_MHZ 0xE2 +#define RFLR_FRFMID_907_MHZ 0xC0 +#define RFLR_FRFLSB_907_MHZ 0x00 +#define RFLR_FRFMSB_908_MHZ 0xE3 +#define RFLR_FRFMID_908_MHZ 0x00 +#define RFLR_FRFLSB_908_MHZ 0x00 +#define RFLR_FRFMSB_909_MHZ 0xE3 +#define RFLR_FRFMID_909_MHZ 0x40 +#define RFLR_FRFLSB_909_MHZ 0x00 +#define RFLR_FRFMSB_910_MHZ 0xE3 +#define RFLR_FRFMID_910_MHZ 0x80 +#define RFLR_FRFLSB_910_MHZ 0x00 +#define RFLR_FRFMSB_911_MHZ 0xE3 +#define RFLR_FRFMID_911_MHZ 0xC0 +#define RFLR_FRFLSB_911_MHZ 0x00 +#define RFLR_FRFMSB_912_MHZ 0xE4 +#define RFLR_FRFMID_912_MHZ 0x00 +#define RFLR_FRFLSB_912_MHZ 0x00 +#define RFLR_FRFMSB_913_MHZ 0xE4 +#define RFLR_FRFMID_913_MHZ 0x40 +#define RFLR_FRFLSB_913_MHZ 0x00 +#define RFLR_FRFMSB_914_MHZ 0xE4 +#define RFLR_FRFMID_914_MHZ 0x80 +#define RFLR_FRFLSB_914_MHZ 0x00 +#define RFLR_FRFMSB_915_MHZ 0xE4 // Default +#define RFLR_FRFMID_915_MHZ 0xC0 // Default +#define RFLR_FRFLSB_915_MHZ 0x00 // Default +#define RFLR_FRFMSB_916_MHZ 0xE5 +#define RFLR_FRFMID_916_MHZ 0x00 +#define RFLR_FRFLSB_916_MHZ 0x00 +#define RFLR_FRFMSB_917_MHZ 0xE5 +#define RFLR_FRFMID_917_MHZ 0x40 +#define RFLR_FRFLSB_917_MHZ 0x00 +#define RFLR_FRFMSB_918_MHZ 0xE5 +#define RFLR_FRFMID_918_MHZ 0x80 +#define RFLR_FRFLSB_918_MHZ 0x00 +#define RFLR_FRFMSB_919_MHZ 0xE5 +#define RFLR_FRFMID_919_MHZ 0xC0 +#define RFLR_FRFLSB_919_MHZ 0x00 +#define RFLR_FRFMSB_920_MHZ 0xE6 +#define RFLR_FRFMID_920_MHZ 0x00 +#define RFLR_FRFLSB_920_MHZ 0x00 +#define RFLR_FRFMSB_921_MHZ 0xE6 +#define RFLR_FRFMID_921_MHZ 0x40 +#define RFLR_FRFLSB_921_MHZ 0x00 +#define RFLR_FRFMSB_922_MHZ 0xE6 +#define RFLR_FRFMID_922_MHZ 0x80 +#define RFLR_FRFLSB_922_MHZ 0x00 +#define RFLR_FRFMSB_923_MHZ 0xE6 +#define RFLR_FRFMID_923_MHZ 0xC0 +#define RFLR_FRFLSB_923_MHZ 0x00 +#define RFLR_FRFMSB_924_MHZ 0xE7 +#define RFLR_FRFMID_924_MHZ 0x00 +#define RFLR_FRFLSB_924_MHZ 0x00 +#define RFLR_FRFMSB_925_MHZ 0xE7 +#define RFLR_FRFMID_925_MHZ 0x40 +#define RFLR_FRFLSB_925_MHZ 0x00 +#define RFLR_FRFMSB_926_MHZ 0xE7 +#define RFLR_FRFMID_926_MHZ 0x80 +#define RFLR_FRFLSB_926_MHZ 0x00 +#define RFLR_FRFMSB_927_MHZ 0xE7 +#define RFLR_FRFMID_927_MHZ 0xC0 +#define RFLR_FRFLSB_927_MHZ 0x00 +#define RFLR_FRFMSB_928_MHZ 0xE8 +#define RFLR_FRFMID_928_MHZ 0x00 +#define RFLR_FRFLSB_928_MHZ 0x00 + +//PA(功率放大器) 选择和输出功率控制设置相关宏定义 RegPaConfig(寄存器地址0X09) +#define RFLR_PACONFIG_PASELECT_MASK 0x7F +#define RFLR_PACONFIG_PASELECT_PABOOST 0x80 +#define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default + +#define RFLR_PACONFIG_MAX_POWER_MASK 0x8F + +#define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0 + +//PA(功率放大器) 斜升/斜降时间和低相噪设置相关定义 RegPaRamp(寄存器地址0X0A) +#define RFLR_PARAMP_TXBANDFORCE_MASK 0xEF +#define RFLR_PARAMP_TXBANDFORCE_BAND_SEL 0x10 +#define RFLR_PARAMP_TXBANDFORCE_AUTO 0x00 // Default + +#define RFLR_PARAMP_MASK 0xF0 +#define RFLR_PARAMP_3400_US 0x00 +#define RFLR_PARAMP_2000_US 0x01 +#define RFLR_PARAMP_1000_US 0x02 +#define RFLR_PARAMP_0500_US 0x03 +#define RFLR_PARAMP_0250_US 0x04 +#define RFLR_PARAMP_0125_US 0x05 +#define RFLR_PARAMP_0100_US 0x06 +#define RFLR_PARAMP_0062_US 0x07 +#define RFLR_PARAMP_0050_US 0x08 +#define RFLR_PARAMP_0040_US 0x09 // Default +#define RFLR_PARAMP_0031_US 0x0A +#define RFLR_PARAMP_0025_US 0x0B +#define RFLR_PARAMP_0020_US 0x0C +#define RFLR_PARAMP_0015_US 0x0D +#define RFLR_PARAMP_0012_US 0x0E +#define RFLR_PARAMP_0010_US 0x0F + +//过流保护控制设置相关宏定义 RegOcp(寄存器地址0X0B) +#define RFLR_OCP_MASK 0xDF +#define RFLR_OCP_ON 0x20 // Default +#define RFLR_OCP_OFF 0x00 + +#define RFLR_OCP_TRIM_MASK 0xE0 +#define RFLR_OCP_TRIM_045_MA 0x00 +#define RFLR_OCP_TRIM_050_MA 0x01 +#define RFLR_OCP_TRIM_055_MA 0x02 +#define RFLR_OCP_TRIM_060_MA 0x03 +#define RFLR_OCP_TRIM_065_MA 0x04 +#define RFLR_OCP_TRIM_070_MA 0x05 +#define RFLR_OCP_TRIM_075_MA 0x06 +#define RFLR_OCP_TRIM_080_MA 0x07 +#define RFLR_OCP_TRIM_085_MA 0x08 +#define RFLR_OCP_TRIM_090_MA 0x09 +#define RFLR_OCP_TRIM_095_MA 0x0A +#define RFLR_OCP_TRIM_100_MA 0x0B // Default +#define RFLR_OCP_TRIM_105_MA 0x0C +#define RFLR_OCP_TRIM_110_MA 0x0D +#define RFLR_OCP_TRIM_115_MA 0x0E +#define RFLR_OCP_TRIM_120_MA 0x0F +#define RFLR_OCP_TRIM_130_MA 0x10 +#define RFLR_OCP_TRIM_140_MA 0x11 +#define RFLR_OCP_TRIM_150_MA 0x12 +#define RFLR_OCP_TRIM_160_MA 0x13 +#define RFLR_OCP_TRIM_170_MA 0x14 +#define RFLR_OCP_TRIM_180_MA 0x15 +#define RFLR_OCP_TRIM_190_MA 0x16 +#define RFLR_OCP_TRIM_200_MA 0x17 +#define RFLR_OCP_TRIM_210_MA 0x18 +#define RFLR_OCP_TRIM_220_MA 0x19 +#define RFLR_OCP_TRIM_230_MA 0x1A +#define RFLR_OCP_TRIM_240_MA 0x1B + +//LNA(低噪声放大器 )设置相关宏定义 RegLna(寄存器地址0X0C) +#define RFLR_LNA_GAIN_MASK 0x1F +#define RFLR_LNA_GAIN_G1 0x20 // Default +#define RFLR_LNA_GAIN_G2 0x40 +#define RFLR_LNA_GAIN_G3 0x60 +#define RFLR_LNA_GAIN_G4 0x80 +#define RFLR_LNA_GAIN_G5 0xA0 +#define RFLR_LNA_GAIN_G6 0xC0 + +#define RFLR_LNA_BOOST_LF_MASK 0xE7 +#define RFLR_LNA_BOOST_LF_DEFAULT 0x00 // Default +#define RFLR_LNA_BOOST_LF_GAIN 0x08 +#define RFLR_LNA_BOOST_LF_IP3 0x10 +#define RFLR_LNA_BOOST_LF_BOOST 0x18 + +#define RFLR_LNA_RXBANDFORCE_MASK 0xFB +#define RFLR_LNA_RXBANDFORCE_BAND_SEL 0x04 +#define RFLR_LNA_RXBANDFORCE_AUTO 0x00 // Default + +#define RFLR_LNA_BOOST_HF_MASK 0xFC +#define RFLR_LNA_BOOST_HF_OFF 0x00 // Default +#define RFLR_LNA_BOOST_HF_ON 0x03 + + +//FIFO 数据缓冲区中 SPI 接口地址指针(寄存器地址0X0D) +#define RFLR_FIFOADDRPTR 0x00 // Default + +//发送信息的起始位置 +#define RFLR_FIFOTXBASEADDR 0x80 // Default + +//接收信息的起始位置 +#define RFLR_FIFORXBASEADDR 0x00 // Default + +/*! + * RegFifoRxCurrentAddr (Read Only) + */ + +//关于中断屏蔽相关的宏定义 +#define RFLR_IRQFLAGS_RXTIMEOUT_MASK 0x80 +#define RFLR_IRQFLAGS_RXDONE_MASK 0x40 +#define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK 0x20 +#define RFLR_IRQFLAGS_VALIDHEADER_MASK 0x10 +#define RFLR_IRQFLAGS_TXDONE_MASK 0x08 +#define RFLR_IRQFLAGS_CADDONE_MASK 0x04 +#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK 0x02 +#define RFLR_IRQFLAGS_CADDETECTED_MASK 0x01 + +//关于中断打开相关的宏定义 +#define RFLR_IRQFLAGS_RXTIMEOUT 0x80 +#define RFLR_IRQFLAGS_RXDONE 0x40 +#define RFLR_IRQFLAGS_PAYLOADCRCERROR 0x20 +#define RFLR_IRQFLAGS_VALIDHEADER 0x10 +#define RFLR_IRQFLAGS_TXDONE 0x08 +#define RFLR_IRQFLAGS_CADDONE 0x04 +#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL 0x02 +#define RFLR_IRQFLAGS_CADDETECTED 0x01 + + + +/*! + * RegFifoRxNbBytes (Read Only) // + */ + + + /*! + * RegRxHeaderCntValueMsb (Read Only) // + */ + + + /*! + * RegRxHeaderCntValueLsb (Read Only) // + */ + + +/*! + * RegRxPacketCntValueMsb (Read Only) // + */ + + + /*! + * RegRxPacketCntValueLsb (Read Only) // + */ + + + /*! + * RegModemStat (Read Only) // + */ +#define RFLR_MODEMSTAT_RX_CR_MASK 0x1F +#define RFLR_MODEMSTAT_MODEM_STATUS_MASK 0xE0 + +/*! + * RegPktSnrValue (Read Only) // + */ + + + /*! + * RegPktRssiValue (Read Only) // + */ + + +/*! + * RegRssiValue (Read Only) // + */ + + +//与信号宽度,纠错编码率,是否显示报头有关宏定义(寄存器位置0X1D) +#define RFLR_MODEMCONFIG1_BW_MASK 0x0F + +#define RFLR_MODEMCONFIG1_BW_7_81_KHZ 0x00 +#define RFLR_MODEMCONFIG1_BW_10_41_KHZ 0x10 +#define RFLR_MODEMCONFIG1_BW_15_62_KHZ 0x20 +#define RFLR_MODEMCONFIG1_BW_20_83_KHZ 0x30 +#define RFLR_MODEMCONFIG1_BW_31_25_KHZ 0x40 +#define RFLR_MODEMCONFIG1_BW_41_66_KHZ 0x50 +#define RFLR_MODEMCONFIG1_BW_62_50_KHZ 0x60 +#define RFLR_MODEMCONFIG1_BW_125_KHZ 0x70 // Default +#define RFLR_MODEMCONFIG1_BW_250_KHZ 0x80 +#define RFLR_MODEMCONFIG1_BW_500_KHZ 0x90 + +#define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xF1 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x02 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x04 // Default +#define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x06 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x08 + +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFE +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x01 +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default + +//与扩频因子,接收模式,发送CRC开启,RX超时相关宏定义 +#define RFLR_MODEMCONFIG2_SF_MASK 0x0F +#define RFLR_MODEMCONFIG2_SF_6 0x60 +#define RFLR_MODEMCONFIG2_SF_7 0x70 // Default +#define RFLR_MODEMCONFIG2_SF_8 0x80 +#define RFLR_MODEMCONFIG2_SF_9 0x90 +#define RFLR_MODEMCONFIG2_SF_10 0xA0 +#define RFLR_MODEMCONFIG2_SF_11 0xB0 +#define RFLR_MODEMCONFIG2_SF_12 0xC0 + +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK 0xF7 +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON 0x08 +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF 0x00 + +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK 0xFB +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON 0x04 +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF 0x00 // Default + +#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC +#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default + + +/*! + * RegHopChannel (Read Only) + */ +#define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK 0x7F +#define RFLR_HOPCHANNEL_PLL_LOCK_FAIL 0x80 +#define RFLR_HOPCHANNEL_PLL_LOCK_SUCCEED 0x00 // Default + +#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_MASK 0xBF +#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_ON 0x40 +#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_OFF 0x00 // Default + +#define RFLR_HOPCHANNEL_CHANNEL_MASK 0x3F + + +/*! + * RegSymbTimeoutLsb + */ +#define RFLR_SYMBTIMEOUTLSB_SYMBTIMEOUT 0x64 // Default + +/*! + * RegPreambleLengthMsb + */ +#define RFLR_PREAMBLELENGTHMSB 0x00 // Default + +/*! + * RegPreambleLengthLsb + */ +#define RFLR_PREAMBLELENGTHLSB 0x08 // Default + +/*! + * RegPayloadLength + */ +#define RFLR_PAYLOADLENGTH 0x0E // Default + +/*! + * RegPayloadMaxLength + */ +#define RFLR_PAYLOADMAXLENGTH 0xFF // Default + +/*! + * RegHopPeriod + */ +#define RFLR_HOPPERIOD_FREQFOPPINGPERIOD 0x00 // Default + + +/*! + * RegDioMapping1 + */ +#define RFLR_DIOMAPPING1_DIO0_MASK 0x3F +#define RFLR_DIOMAPPING1_DIO0_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO0_01 0x40 +#define RFLR_DIOMAPPING1_DIO0_10 0x80 +#define RFLR_DIOMAPPING1_DIO0_11 0xC0 + +#define RFLR_DIOMAPPING1_DIO1_MASK 0xCF +#define RFLR_DIOMAPPING1_DIO1_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO1_01 0x10 +#define RFLR_DIOMAPPING1_DIO1_10 0x20 +#define RFLR_DIOMAPPING1_DIO1_11 0x30 + +#define RFLR_DIOMAPPING1_DIO2_MASK 0xF3 +#define RFLR_DIOMAPPING1_DIO2_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO2_01 0x04 +#define RFLR_DIOMAPPING1_DIO2_10 0x08 +#define RFLR_DIOMAPPING1_DIO2_11 0x0C + +#define RFLR_DIOMAPPING1_DIO3_MASK 0xFC +#define RFLR_DIOMAPPING1_DIO3_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO3_01 0x01 +#define RFLR_DIOMAPPING1_DIO3_10 0x02 +#define RFLR_DIOMAPPING1_DIO3_11 0x03 + +/*! + * RegDioMapping2 + */ +#define RFLR_DIOMAPPING2_DIO4_MASK 0x3F +#define RFLR_DIOMAPPING2_DIO4_00 0x00 // Default +#define RFLR_DIOMAPPING2_DIO4_01 0x40 +#define RFLR_DIOMAPPING2_DIO4_10 0x80 +#define RFLR_DIOMAPPING2_DIO4_11 0xC0 + +#define RFLR_DIOMAPPING2_DIO5_MASK 0xCF +#define RFLR_DIOMAPPING2_DIO5_00 0x00 // Default +#define RFLR_DIOMAPPING2_DIO5_01 0x10 +#define RFLR_DIOMAPPING2_DIO5_10 0x20 +#define RFLR_DIOMAPPING2_DIO5_11 0x30 + +#define RFLR_DIOMAPPING2_MAP_MASK 0xFE +#define RFLR_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 +#define RFLR_DIOMAPPING2_MAP_RSSI 0x00 // Default + +/*! + * RegVersion (Read Only) + */ + +/*! + * RegAgcRef + */ + +/*! + * RegAgcThresh1 + */ + +/*! + * RegAgcThresh2 + */ + +/*! + * RegAgcThresh3 + */ + +/*! + * RegFifoRxByteAddr (Read Only) + */ + +/*! + * RegPllHop + */ +#define RFLR_PLLHOP_FASTHOP_MASK 0x7F +#define RFLR_PLLHOP_FASTHOP_ON 0x80 +#define RFLR_PLLHOP_FASTHOP_OFF 0x00 // Default + +/*! + * RegTcxo + */ +#define RFLR_TCXO_TCXOINPUT_MASK 0xEF +#define RFLR_TCXO_TCXOINPUT_ON 0x10 +#define RFLR_TCXO_TCXOINPUT_OFF 0x00 // Default + +/*! + * RegPaDac + */ +#define RFLR_PADAC_20DBM_MASK 0xF8 +#define RFLR_PADAC_20DBM_ON 0x07 +#define RFLR_PADAC_20DBM_OFF 0x04 // Default + +/*! + * RegPll + */ +#define RFLR_PLL_BANDWIDTH_MASK 0x3F +#define RFLR_PLL_BANDWIDTH_75 0x00 +#define RFLR_PLL_BANDWIDTH_150 0x40 +#define RFLR_PLL_BANDWIDTH_225 0x80 +#define RFLR_PLL_BANDWIDTH_300 0xC0 // Default + +/*! + * RegPllLowPn + */ +#define RFLR_PLLLOWPN_BANDWIDTH_MASK 0x3F +#define RFLR_PLLLOWPN_BANDWIDTH_75 0x00 +#define RFLR_PLLLOWPN_BANDWIDTH_150 0x40 +#define RFLR_PLLLOWPN_BANDWIDTH_225 0x80 +#define RFLR_PLLLOWPN_BANDWIDTH_300 0xC0 // Default + +/*! + * RegModemConfig3 + */ +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK 0xF7 +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON 0x08 +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_OFF 0x00 // Default + +#define RFLR_MODEMCONFIG3_AGCAUTO_MASK 0xFB +#define RFLR_MODEMCONFIG3_AGCAUTO_ON 0x04 // Default +#define RFLR_MODEMCONFIG3_AGCAUTO_OFF 0x00 + +/*! + * RegFormerTemp + */ + +typedef struct sSX1276LR +{ + uint8_t RegFifo; // 0x00 + // Common settings + uint8_t RegOpMode; // 0x01 + uint8_t RegRes02; // 0x02 + uint8_t RegRes03; // 0x03 + uint8_t RegBandSetting; // 0x04 + uint8_t RegRes05; // 0x05 + uint8_t RegFrfMsb; // 0x06 + uint8_t RegFrfMid; // 0x07 + uint8_t RegFrfLsb; // 0x08 + // Tx settings + uint8_t RegPaConfig; // 0x09 + uint8_t RegPaRamp; // 0x0A + uint8_t RegOcp; // 0x0B + // Rx settings + uint8_t RegLna; // 0x0C + // LoRa registers + uint8_t RegFifoAddrPtr; // 0x0D + uint8_t RegFifoTxBaseAddr; // 0x0E + uint8_t RegFifoRxBaseAddr; // 0x0F + uint8_t RegFifoRxCurrentAddr; // 0x10 + uint8_t RegIrqFlagsMask; // 0x11 + uint8_t RegIrqFlags; // 0x12 + uint8_t RegNbRxBytes; // 0x13 + uint8_t RegRxHeaderCntValueMsb; // 0x14 + uint8_t RegRxHeaderCntValueLsb; // 0x15 + uint8_t RegRxPacketCntValueMsb; // 0x16 + uint8_t RegRxPacketCntValueLsb; // 0x17 + uint8_t RegModemStat; // 0x18 + uint8_t RegPktSnrValue; // 0x19 + uint8_t RegPktRssiValue; // 0x1A + uint8_t RegRssiValue; // 0x1B + uint8_t RegHopChannel; // 0x1C + uint8_t RegModemConfig1; // 0x1D + uint8_t RegModemConfig2; // 0x1E + uint8_t RegSymbTimeoutLsb; // 0x1F + uint8_t RegPreambleMsb; // 0x20 + uint8_t RegPreambleLsb; // 0x21 + uint8_t RegPayloadLength; // 0x22 + uint8_t RegMaxPayloadLength; // 0x23 + uint8_t RegHopPeriod; // 0x24 跳频周期 + uint8_t RegFifoRxByteAddr; // 0x25 + uint8_t RegModemConfig3; // 0x26 + uint8_t RegTestReserved27[0x30 - 0x27]; // 0x27-0x30 + uint8_t RegTestReserved31; // 0x31 + uint8_t RegTestReserved32[0x40 - 0x32]; // 0x32-0x40 + // I/O settings + uint8_t RegDioMapping1; // 0x40 + uint8_t RegDioMapping2; // 0x41 + // Version + uint8_t RegVersion; // 0x42 + // Additional settings + uint8_t RegAgcRef; // 0x43 + uint8_t RegAgcThresh1; // 0x44 + uint8_t RegAgcThresh2; // 0x45 + uint8_t RegAgcThresh3; // 0x46 + // Test + uint8_t RegTestReserved47[0x4B - 0x47]; // 0x47-0x4A + // Additional settings + uint8_t RegPllHop; // 0x4B + uint8_t RegTestReserved4C; // 0x4C + uint8_t RegPaDac; // 0x4D + // Test + uint8_t RegTestReserved4E[0x58-0x4E]; // 0x4E-0x57 + // Additional settings + uint8_t RegTcxo; // 0x58 + // Test + uint8_t RegTestReserved59; // 0x59 + // Test + uint8_t RegTestReserved5B; // 0x5B + // Additional settings + uint8_t RegPll; // 0x5C + // Test + uint8_t RegTestReserved5D; // 0x5D + // Additional settings + uint8_t RegPllLowPn; // 0x5E + // Test + uint8_t RegTestReserved5F[0x6C - 0x5F]; // 0x5F-0x6B + // Additional settings + uint8_t RegFormerTemp; // 0x6C + // Test + uint8_t RegTestReserved6D[0x71 - 0x6D]; // 0x6D-0x70 +}tSX1276LR; + +extern tSX1276LR* SX1276LR; + +//初始化SX1276LoRa模式 +void SX1276LoRaInit( void ); + +//读SX1276的版本号 +void SX1276LoRaSetDefaults( void ); + +//启用/禁用LoRa模式 +void SX1276LoRaSetLoRaOn( bool enable ); + +//设置SX1276操作模式 +void SX1276LoRaSetOpMode( uint8_t opMode ); + +//获取SX1276操作模式 +uint8_t SX1276LoRaGetOpMode( void ); + +//读取SX1276低噪声放大器(信号放大)的增益, +uint8_t SX1276LoRaReadRxGain( void ); + +//读取lora模式下无线信号强度 +double SX1276LoRaReadRssi( void ); + +//获取数据时的增益值 +uint8_t SX1276LoRaGetPacketRxGain( void ); + +//获取数据时的信噪比值,信号和噪声的比值,信噪比越高,说明信号干扰越小。 +int8_t SX1276LoRaGetPacketSnr( void ); + +//获取数据时的无线信号强度 +double SX1276LoRaGetPacketRssi( void ); + +//开始接收 +void SX1276LoRaStartRx( void ); + +//接收数据 +void SX1276LoRaGetRxPacket( void *buffer, uint16_t *size ); + +//发送数据 +void SX1276LoRaSetTxPacket( const void *buffer, uint16_t size ); + +//得到RFLRState状态 +uint8_t SX1276LoRaGetRFState( void ); + +//设置RFLRState状态,RFLRState的值决定了下面的函数处理哪一步的代码 +void SX1276LoRaSetRFState( uint8_t state ); + +//SX1276模块接发收数据的处理函数 +uint32_t SX1276LoRaProcess( void ); + +uint32_t SX1276LoraChannelEmpty( void ); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.c new file mode 100644 index 000000000..6a472f8c7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.c @@ -0,0 +1,420 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276-LoRaMisc.c + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-LoRaMisc.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ +#include "platform.h" + +#if defined( USE_SX1276_RADIO ) + +#include "sx1276-Hal.h" +#include "sx1276.h" + +#include "sx1276-LoRa.h" +#include "sx1276-LoRaMisc.h" + +/*! + * SX1276 definitions + */ +#define XTAL_FREQ 32000000 +#define FREQ_STEP 61.03515625 + +extern tLoRaSettings LoRaSettings; + +void SX1276LoRaSetRFFrequency( uint32_t freq ) +{ + LoRaSettings.RFFrequency = freq; + + freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP ); + SX1276LR->RegFrfMsb = ( uint8_t )( ( freq >> 16 ) & 0xFF ); + SX1276LR->RegFrfMid = ( uint8_t )( ( freq >> 8 ) & 0xFF ); + SX1276LR->RegFrfLsb = ( uint8_t )( freq & 0xFF ); + SX1276WriteBuffer( REG_LR_FRFMSB, &SX1276LR->RegFrfMsb, 3 ); +} + +uint32_t SX1276LoRaGetRFFrequency( void ) +{ + SX1276ReadBuffer( REG_LR_FRFMSB, &SX1276LR->RegFrfMsb, 3 ); + LoRaSettings.RFFrequency = ( ( uint32_t )SX1276LR->RegFrfMsb << 16 ) | ( ( uint32_t )SX1276LR->RegFrfMid << 8 ) | ( ( uint32_t )SX1276LR->RegFrfLsb ); + LoRaSettings.RFFrequency = ( uint32_t )( ( double )LoRaSettings.RFFrequency * ( double )FREQ_STEP ); + + return LoRaSettings.RFFrequency; +} + +void SX1276LoRaSetRFPower( int8_t power ) +{ + SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig ); + SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac ); + + if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST ) + { + if( ( SX1276LR->RegPaDac & 0x87 ) == 0x87 ) + { + if( power < 5 ) + { + power = 5; + } + if( power > 20 ) + { + power = 20; + } + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F ); + } + else + { + if( power < 2 ) + { + power = 2; + } + if( power > 17 ) + { + power = 17; + } + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F ); + } + } + else + { + if( power < -1 ) + { + power = -1; + } + if( power > 14 ) + { + power = 14; + } + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F ); + } + SX1276Write( REG_LR_PACONFIG, SX1276LR->RegPaConfig ); + LoRaSettings.Power = power; +} + +int8_t SX1276LoRaGetRFPower( void ) +{ + SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig ); + SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac ); + + if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST ) + { + if( ( SX1276LR->RegPaDac & 0x07 ) == 0x07 ) + { + LoRaSettings.Power = 5 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK ); + } + else + { + LoRaSettings.Power = 2 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK ); + } + } + else + { + LoRaSettings.Power = -1 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK ); + } + return LoRaSettings.Power; +} + +void SX1276LoRaSetSignalBandwidth( uint8_t bw ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_BW_MASK ) | ( bw << 4 ); + SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 ); + LoRaSettings.SignalBw = bw; +} + +uint8_t SX1276LoRaGetSignalBandwidth( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + LoRaSettings.SignalBw = ( SX1276LR->RegModemConfig1 & ~RFLR_MODEMCONFIG1_BW_MASK ) >> 4; + return LoRaSettings.SignalBw; +} + +void SX1276LoRaSetSpreadingFactor( uint8_t factor ) +{ + + if( factor > 12 ) + { + factor = 12; + } + else if( factor < 6 ) + { + factor = 6; + } + + if( factor == 6 ) + { + SX1276LoRaSetNbTrigPeaks( 5 ); + } + else + { + SX1276LoRaSetNbTrigPeaks( 3 ); + } + + SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 ); + SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_SF_MASK ) | ( factor << 4 ); + SX1276Write( REG_LR_MODEMCONFIG2, SX1276LR->RegModemConfig2 ); + LoRaSettings.SpreadingFactor = factor; +} + +uint8_t SX1276LoRaGetSpreadingFactor( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 ); + LoRaSettings.SpreadingFactor = ( SX1276LR->RegModemConfig2 & ~RFLR_MODEMCONFIG2_SF_MASK ) >> 4; + return LoRaSettings.SpreadingFactor; +} + +void SX1276LoRaSetErrorCoding( uint8_t value ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_CODINGRATE_MASK ) | ( value << 1 ); + SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 ); + LoRaSettings.ErrorCoding = value; +} + +uint8_t SX1276LoRaGetErrorCoding( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + LoRaSettings.ErrorCoding = ( SX1276LR->RegModemConfig1 & ~RFLR_MODEMCONFIG1_CODINGRATE_MASK ) >> 1; + return LoRaSettings.ErrorCoding; +} + +void SX1276LoRaSetPacketCrcOn( bool enable ) +{ + SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 ); + SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK ) | ( enable << 2 ); + SX1276Write( REG_LR_MODEMCONFIG2, SX1276LR->RegModemConfig2 ); + LoRaSettings.CrcOn = enable; +} + +void SX1276LoRaSetPreambleLength( uint16_t value ) +{ + SX1276ReadBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 ); + + SX1276LR->RegPreambleMsb = ( value >> 8 ) & 0x00FF; + SX1276LR->RegPreambleLsb = value & 0xFF; + SX1276WriteBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 ); +} + +uint16_t SX1276LoRaGetPreambleLength( void ) +{ + SX1276ReadBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 ); + return ( ( SX1276LR->RegPreambleMsb & 0x00FF ) << 8 ) | SX1276LR->RegPreambleLsb; +} + +bool SX1276LoRaGetPacketCrcOn( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 ); + LoRaSettings.CrcOn = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON ) >> 1; + return LoRaSettings.CrcOn; +} + +void SX1276LoRaSetImplicitHeaderOn( bool enable ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) | ( enable ); + SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 ); + LoRaSettings.ImplicitHeaderOn = enable; +} + +bool SX1276LoRaGetImplicitHeaderOn( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + LoRaSettings.ImplicitHeaderOn = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_IMPLICITHEADER_ON ); + return LoRaSettings.ImplicitHeaderOn; +} + +void SX1276LoRaSetRxSingleOn( bool enable ) +{ + LoRaSettings.RxSingleOn = enable; +} + +bool SX1276LoRaGetRxSingleOn( void ) +{ + return LoRaSettings.RxSingleOn; +} + +void SX1276LoRaSetFreqHopOn( bool enable ) +{ + LoRaSettings.FreqHopOn = enable; +} + +bool SX1276LoRaGetFreqHopOn( void ) +{ + return LoRaSettings.FreqHopOn; +} + +void SX1276LoRaSetHopPeriod( uint8_t value ) +{ + SX1276LR->RegHopPeriod = value; + SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod ); + LoRaSettings.HopPeriod = value; +} + +uint8_t SX1276LoRaGetHopPeriod( void ) +{ + SX1276Read( REG_LR_HOPPERIOD, &SX1276LR->RegHopPeriod ); + LoRaSettings.HopPeriod = SX1276LR->RegHopPeriod; + return LoRaSettings.HopPeriod; +} + +void SX1276LoRaSetTxPacketTimeout( uint32_t value ) +{ + LoRaSettings.TxPacketTimeout = value; +} + +uint32_t SX1276LoRaGetTxPacketTimeout( void ) +{ + return LoRaSettings.TxPacketTimeout; +} + +void SX1276LoRaSetRxPacketTimeout( uint32_t value ) +{ + LoRaSettings.RxPacketTimeout = value; +} + +uint32_t SX1276LoRaGetRxPacketTimeout( void ) +{ + return LoRaSettings.RxPacketTimeout; +} + +void SX1276LoRaSetPayloadLength( uint8_t value ) +{ + SX1276LR->RegPayloadLength = value; + SX1276Write( REG_LR_PAYLOADLENGTH, SX1276LR->RegPayloadLength ); + LoRaSettings.PayloadLength = value; +} + +uint8_t SX1276LoRaGetPayloadLength( void ) +{ + SX1276Read( REG_LR_PAYLOADLENGTH, &SX1276LR->RegPayloadLength ); + LoRaSettings.PayloadLength = SX1276LR->RegPayloadLength; + return LoRaSettings.PayloadLength; +} + +void SX1276LoRaSetPa20dBm( bool enale ) +{ + SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac ); + SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig ); + + if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST ) + { + if( enale == true ) + { + SX1276LR->RegPaDac = 0x87; + } + } + else + { + SX1276LR->RegPaDac = 0x84; + } + SX1276Write( REG_LR_PADAC, SX1276LR->RegPaDac ); +} + +bool SX1276LoRaGetPa20dBm( void ) +{ + SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac ); + + return ( ( SX1276LR->RegPaDac & 0x07 ) == 0x07 ) ? true : false; +} + +void SX1276LoRaSetPAOutput( uint8_t outputPin ) +{ + SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig ); + SX1276LR->RegPaConfig = (SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_MASK ) | outputPin; + SX1276Write( REG_LR_PACONFIG, SX1276LR->RegPaConfig ); +} + +uint8_t SX1276LoRaGetPAOutput( void ) +{ + SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig ); + return SX1276LR->RegPaConfig & ~RFLR_PACONFIG_PASELECT_MASK; +} + +void SX1276LoRaSetPaRamp( uint8_t value ) +{ + SX1276Read( REG_LR_PARAMP, &SX1276LR->RegPaRamp ); + SX1276LR->RegPaRamp = ( SX1276LR->RegPaRamp & RFLR_PARAMP_MASK ) | ( value & ~RFLR_PARAMP_MASK ); + SX1276Write( REG_LR_PARAMP, SX1276LR->RegPaRamp ); +} + +uint8_t SX1276LoRaGetPaRamp( void ) +{ + SX1276Read( REG_LR_PARAMP, &SX1276LR->RegPaRamp ); + return SX1276LR->RegPaRamp & ~RFLR_PARAMP_MASK; +} + +void SX1276LoRaSetSymbTimeout( uint16_t value ) +{ + SX1276ReadBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 ); + + SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) | ( ( value >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ); + SX1276LR->RegSymbTimeoutLsb = value & 0xFF; + SX1276WriteBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 ); +} + +uint16_t SX1276LoRaGetSymbTimeout( void ) +{ + SX1276ReadBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 ); + return ( ( SX1276LR->RegModemConfig2 & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) << 8 ) | SX1276LR->RegSymbTimeoutLsb; +} + +void SX1276LoRaSetLowDatarateOptimize( bool enable ) +{ + SX1276Read( REG_LR_MODEMCONFIG3, &SX1276LR->RegModemConfig3 ); + SX1276LR->RegModemConfig3 = ( SX1276LR->RegModemConfig3 & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) | ( enable << 3 ); + SX1276Write( REG_LR_MODEMCONFIG3, SX1276LR->RegModemConfig3 ); +} + +bool SX1276LoRaGetLowDatarateOptimize( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG3, &SX1276LR->RegModemConfig3 ); + return ( ( SX1276LR->RegModemConfig3 & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON ) >> 3 ); +} + +void SX1276LoRaSetNbTrigPeaks( uint8_t value ) +{ + SX1276Read( 0x31, &SX1276LR->RegTestReserved31 ); + SX1276LR->RegTestReserved31 = ( SX1276LR->RegTestReserved31 & 0xF8 ) | value;//数据包长度最高有效位 0x31 bit2 1 0 + SX1276Write( 0x31, SX1276LR->RegTestReserved31 ); +} + +uint8_t SX1276LoRaGetNbTrigPeaks( void ) +{ + SX1276Read( 0x31, &SX1276LR->RegTestReserved31 ); + return ( SX1276LR->RegTestReserved31 & 0x07 ); +} + +#endif // USE_SX1276_RADIO diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.h new file mode 100644 index 000000000..b6bc148c9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.h @@ -0,0 +1,324 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276-LoRaMisc.h + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-LoRaMisc.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ +#ifndef __SX1276_LORA_MISC_H__ +#define __SX1276_LORA_MISC_H__ +#include "stdint.h" +#include "stdbool.h" +/*! + * \brief Writes the new RF frequency value + * + * \param [IN] freq New RF frequency value in [Hz] + */ +void SX1276LoRaSetRFFrequency( uint32_t freq ); + +/*! + * \brief Reads the current RF frequency value + * + * \retval freq Current RF frequency value in [Hz] + */ +uint32_t SX1276LoRaGetRFFrequency( void ); + +/*! + * \brief Writes the new RF output power value + * + * \param [IN] power New output power value in [dBm] + */ +void SX1276LoRaSetRFPower( int8_t power ); + +/*! + * \brief Reads the current RF output power value + * + * \retval power Current output power value in [dBm] + */ +int8_t SX1276LoRaGetRFPower( void ); + +/*! + * \brief Writes the new Signal Bandwidth value + * + * \remark This function sets the IF frequency according to the datasheet + * + * \param [IN] factor New Signal Bandwidth value [0: 125 kHz, 1: 250 kHz, 2: 500 kHz] + */ +void SX1276LoRaSetSignalBandwidth( uint8_t bw ); + +/*! + * \brief Reads the current Signal Bandwidth value + * + * \retval factor Current Signal Bandwidth value [0: 125 kHz, 1: 250 kHz, 2: 500 kHz] + */ +uint8_t SX1276LoRaGetSignalBandwidth( void ); + +/*! + * \brief Writes the new Spreading Factor value + * + * \param [IN] factor New Spreading Factor value [7, 8, 9, 10, 11, 12] + */ +void SX1276LoRaSetSpreadingFactor( uint8_t factor ); + +/*! + * \brief Reads the current Spreading Factor value + * + * \retval factor Current Spreading Factor value [7, 8, 9, 10, 11, 12] + */ +uint8_t SX1276LoRaGetSpreadingFactor( void ); + +/*! + * \brief Writes the new Error Coding value + * + * \param [IN] value New Error Coding value [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + */ +void SX1276LoRaSetErrorCoding( uint8_t value ); + +/*! + * \brief Reads the current Error Coding value + * + * \retval value Current Error Coding value [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + */ +uint8_t SX1276LoRaGetErrorCoding( void ); + +/*! + * \brief Enables/Disables the packet CRC generation + * + * \param [IN] enaable [true, false] + */ +void SX1276LoRaSetPacketCrcOn( bool enable ); + +/*! + * \brief Reads the current packet CRC generation status + * + * \retval enable [true, false] + */ +bool SX1276LoRaGetPacketCrcOn( void ); + +/*! + * \brief Enables/Disables the Implicit Header mode in LoRa + * + * \param [IN] enable [true, false] + */ +void SX1276LoRaSetImplicitHeaderOn( bool enable ); + +/*! + * \brief Check if implicit header mode in LoRa in enabled or disabled + * + * \retval enable [true, false] + */ +bool SX1276LoRaGetImplicitHeaderOn( void ); + +/*! + * \brief Enables/Disables Rx single instead of Rx continuous + * + * \param [IN] enable [true, false] + */ +void SX1276LoRaSetRxSingleOn( bool enable ); + +/*! + * \brief Check if LoRa is in Rx Single mode + * + * \retval enable [true, false] + */ +bool SX1276LoRaGetRxSingleOn( void ); + +/*! + * \brief Enables/Disables the frequency hopping + * + * \param [IN] enable [true, false] + */ + +void SX1276LoRaSetFreqHopOn( bool enable ); + +/*! + * \brief Get the frequency hopping status + * + * \param [IN] enable [true, false] + */ +bool SX1276LoRaGetFreqHopOn( void ); + +/*! + * \brief Set symbol period between frequency hops + * + * \param [IN] value + */ +void SX1276LoRaSetHopPeriod( uint8_t value ); + +/*! + * \brief Get symbol period between frequency hops + * + * \retval value symbol period between frequency hops + */ +uint8_t SX1276LoRaGetHopPeriod( void ); + +/*! + * \brief Set timeout Tx packet (based on MCU timer, timeout between Tx Mode entry Tx Done IRQ) + * + * \param [IN] value timeout (ms) + */ +void SX1276LoRaSetTxPacketTimeout( uint32_t value ); + +/*! + * \brief Get timeout between Tx packet (based on MCU timer, timeout between Tx Mode entry Tx Done IRQ) + * + * \retval value timeout (ms) + */ +uint32_t SX1276LoRaGetTxPacketTimeout( void ); + +/*! + * \brief Set timeout Rx packet (based on MCU timer, timeout between Rx Mode entry and Rx Done IRQ) + * + * \param [IN] value timeout (ms) + */ +void SX1276LoRaSetRxPacketTimeout( uint32_t value ); + +/*! + * \brief Get timeout Rx packet (based on MCU timer, timeout between Rx Mode entry and Rx Done IRQ) + * + * \retval value timeout (ms) + */ +uint32_t SX1276LoRaGetRxPacketTimeout( void ); + +/*! + * \brief Set payload length + * + * \param [IN] value payload length + */ +void SX1276LoRaSetPayloadLength( uint8_t value ); + +/*! + * \brief Get payload length + * + * \retval value payload length + */ +uint8_t SX1276LoRaGetPayloadLength( void ); + +/*! + * \brief Enables/Disables the 20 dBm PA + * + * \param [IN] enable [true, false] + */ +void SX1276LoRaSetPa20dBm( bool enale ); + +/*! + * \brief Gets the current 20 dBm PA status + * + * \retval enable [true, false] + */ +bool SX1276LoRaGetPa20dBm( void ); + +/*! + * \brief Set the RF Output pin + * + * \param [IN] RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO + */ +void SX1276LoRaSetPAOutput( uint8_t outputPin ); + +/*! + * \brief Gets the used RF Ouptut pin + * + * \retval RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO + */ +uint8_t SX1276LoRaGetPAOutput( void ); + +/*! + * \brief Writes the new PA rise/fall time of ramp up/down value + * + * \param [IN] value New PaRamp value + */ +void SX1276LoRaSetPaRamp( uint8_t value ); + +/*! + * \brief Reads the current PA rise/fall time of ramp up/down value + * + * \retval freq Current PaRamp value + */ +uint8_t SX1276LoRaGetPaRamp( void ); + +/*! + * \brief Set Symbol Timeout based on symbol length + * + * \param [IN] value number of symbol + */ +void SX1276LoRaSetSymbTimeout( uint16_t value ); + +/*! + * \brief Get Symbol Timeout based on symbol length + * + * \retval value number of symbol + */ +uint16_t SX1276LoRaGetSymbTimeout( void ); + +/*! + * \brief Configure the device to optimize low datarate transfers + * + * \param [IN] enable Enables/Disables the low datarate optimization + */ +void SX1276LoRaSetLowDatarateOptimize( bool enable ); + +/*! + * \brief Get the status of optimize low datarate transfers + * + * \retval LowDatarateOptimize enable or disable + */ +bool SX1276LoRaGetLowDatarateOptimize( void ); + +/*! + * \brief Get the preamble length + * + * \retval value preamble length + */ +uint16_t SX1276LoRaGetPreambleLength( void ); + +/*! + * \brief Set the preamble length + * + * \param [IN] value preamble length + */ +void SX1276LoRaSetPreambleLength( uint16_t value ); + +/*! + * \brief Set the number or rolling preamble symbol needed for detection + * + * \param [IN] value number of preamble symbol + */ +void SX1276LoRaSetNbTrigPeaks( uint8_t value ); + +/*! + * \brief Get the number or rolling preamble symbol needed for detection + * + * \retval value number of preamble symbol + */ +uint8_t SX1276LoRaGetNbTrigPeaks( void ); +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.c new file mode 100644 index 000000000..e694f2b75 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.c @@ -0,0 +1,282 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276.c + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#include "platform.h" +#include "radio.h" + +#if defined(USE_SX1276_RADIO) +#include "sx1276.h" +#include "sx1276-Hal.h" +#include "sx1276-Fsk.h" +#include "sx1276-LoRa.h" + +uint8_t SX1276Regs[0x70]; + +static bool LoRaOn = true; +static bool LoRaOnState = false; + +void SX1276Reset(void) +{ + uint32_t startTick; + + SX1276SetReset(RADIO_RESET_ON); + + DDL_DelayMS(1); + + SX1276SetReset(RADIO_RESET_OFF); + + DDL_DelayMS(6); +} + +void SX1276_SetLoRaOn(bool enable) +{ + if(LoRaOnState == enable) { + return; + } + + LoRaOnState = enable; + LoRaOn = enable; + + if(LoRaOn == true) { + SX1276LoRaSetOpMode(RFLR_OPMODE_SLEEP); + + SX1276LR->RegOpMode = (SX1276LR->RegOpMode & RFLR_OPMODE_LONGRANGEMODE_MASK) | RFLR_OPMODE_LONGRANGEMODE_ON; + SX1276Write(REG_LR_OPMODE, SX1276LR->RegOpMode); + + SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY); + + // RxDone RxTimeout FhssChangeChannel CadDone + SX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00; + // CadDetected ModeReady + SX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00; + SX1276WriteBuffer(REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2); + + SX1276ReadBuffer(REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1); + } else { + SX1276LoRaSetOpMode(RFLR_OPMODE_SLEEP); + + SX1276LR->RegOpMode = (SX1276LR->RegOpMode & RFLR_OPMODE_LONGRANGEMODE_MASK) | RFLR_OPMODE_LONGRANGEMODE_OFF; + SX1276Write(REG_LR_OPMODE, SX1276LR->RegOpMode); + + SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY); + + SX1276ReadBuffer(REG_OPMODE, SX1276Regs + 1, 0x70 - 1); + } +} + +bool SX1276_GetLoRaOn(void) +{ + return LoRaOn; +} + +void SX1276SetOpMode(uint8_t opMode) +{ + if(LoRaOn == false) { + SX1276FskSetOpMode(opMode); + } else { + SX1276LoRaSetOpMode(opMode); + } +} + +uint8_t SX1276_GetOpMode(void) +{ + if(LoRaOn == false) { + return SX1276FskGetOpMode(); + } else { + return SX1276LoRaGetOpMode(); + } +} + +double SX1276ReadRssi(void) +{ + if(LoRaOn == false) { + return SX1276FskReadRssi(); + } else { + return SX1276LoRaReadRssi(); + } +} + +uint8_t SX1276_ReadRxGain(void) +{ + if(LoRaOn == false) { + return SX1276FskReadRxGain(); + } else { + return SX1276LoRaReadRxGain(); + } +} + +uint8_t SX1276_GetPacketRxGain(void) +{ + if(LoRaOn == false) { + return SX1276FskGetPacketRxGain(); + } else { + return SX1276LoRaGetPacketRxGain(); + } +} + +int8_t SX1276_GetPacketSnr(void) +{ + if(LoRaOn == false) { + while(1) { + // Useless in FSK mode + // Block program here + } + } else { + return SX1276LoRaGetPacketSnr(); + } +} + +double SX1276_GetPacketRssi(void) +{ + if(LoRaOn == false) { + return SX1276FskGetPacketRssi(); + } else { + return SX1276LoRaGetPacketRssi(); + } +} + +uint32_t SX1276GetPacketAfc(void) +{ + if(LoRaOn == false) { + return SX1276FskGetPacketAfc(); + } else { + while(1) { + // Useless in LoRa mode + // Block program here + } + } +} + +void SX1276StartRx(void) +{ + if(LoRaOn == false) { + SX1276FskSetRFState(RF_STATE_RX_INIT); + } else { + SX1276LoRaSetRFState(RFLR_STATE_RX_INIT); + } +} + +void SX1276GetRxPacket(void *buffer, uint16_t *size) +{ + if(LoRaOn == false) { + SX1276FskGetRxPacket(buffer, size); + } else { + SX1276LoRaGetRxPacket(buffer, size); + } +} + +void SX1276SetTxPacket(const void *buffer, uint16_t size) +{ + if(LoRaOn == false) { + SX1276FskSetTxPacket(buffer, size); + } else { + SX1276LoRaSetTxPacket(buffer, size); + } +} + +uint8_t SX1276GetRFState(void) +{ + if(LoRaOn == false) { + return SX1276FskGetRFState(); + } else { + return SX1276LoRaGetRFState(); + } +} + +void SX1276SetRFState(uint8_t state) +{ + if(LoRaOn == false) { + SX1276FskSetRFState(state); + } else { + SX1276LoRaSetRFState(state); + } +} + +uint32_t SX1276Process(void) +{ + if(LoRaOn == false) { + return SX1276FskProcess(); + } else { + return SX1276LoRaProcess(); + } +} + +uint32_t SX1276ChannelEmpty(void) +{ + if(LoRaOn == false) { + return true; + } else { + SX1276LoraChannelEmpty(); + } +} + +void SX1276Init(void) +{ + uint8_t TempReg; + + SX1276 = (tSX1276 *)SX1276Regs; + SX1276LR = (tSX1276LR *)SX1276Regs; + + SX1276InitIo(); + + SX1276Reset(); + + SX1276Read(0x06, &TempReg); + + if(TempReg != 0x6C) { + KPrintf("Hard SPI Err!\r\n"); + } + + SX1276Read(0x42, &TempReg); + + if(TempReg != 0x12) { + KPrintf("Hard SPI Err! version 0x%x\r\n", TempReg); + } + + #if (LORA == 0) + LoRaOn = false; + SX1276_SetLoRaOn(LoRaOn); + SX1276FskInit(); + #else + LoRaOn = true; + SX1276_SetLoRaOn(LoRaOn); + SX1276LoRaInit(); + #endif +} + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.h new file mode 100644 index 000000000..0230420ca --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.h @@ -0,0 +1,93 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276.h + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + + +#ifndef __SX1276_H__ +#define __SX1276_H__ + +#include +#include + +extern uint8_t SX1276Regs[0x70]; //SX1276寄存器数组 + +void SX1276Init( void ); //初始化SX1276 + +void SX1276Reset( void ); //重置SX1276 + +/*以下函数都没有被使用到,因为在sx1276-LoRa.h里面又定义了一系列与下面作用相同的函数*/ +void SX1276_SetLoRaOn( bool enable ); //启用LoRa调制解调器或FSK调制解调器 + +bool SX1276_GetLoRaOn( void ); //获取LoRa调制解调器状态 + +void SX1276SetOpMode( uint8_t opMode ); //设置SX1276操作模式 + +uint8_t SX1276_GetOpMode( void ); //获取SX1276操作模式 + +uint8_t SX1276_ReadRxGain( void ); //读取当前Rx增益设置 + +double SX1276ReadRssi( void ); //读取无线信号强度 + +uint8_t SX1276_GetPacketRxGain( void ); //获取数据时的增益值 + +int8_t SX1276_GetPacketSnr( void ); //获取数据时的信噪比值,信号和噪声的比值,信噪比越高,说明信号干扰越小。 + +double SX1276_GetPacketRssi( void ); //获取数据是的无线信号强度 + +/*! + * \brief Gets the AFC value measured while receiving the packet + * + * \retval afcValue Current AFC value in [Hz] + */ +uint32_t SX1276GetPacketAfc( void ); //此函数不知道作用 + + +void SX1276StartRx( void ); //开始接收 + +void SX1276GetRxPacket( void *buffer, uint16_t *size ); //得到接收的数据 + +void SX1276SetTxPacket( const void *buffer, uint16_t size ); //发送数据 + +uint8_t SX1276GetRFState( void ); //得到RFLRState状态 + +void SX1276SetRFState( uint8_t state ); //设置RFLRState状态,RFLRState的值决定了下面的函数处理哪一步的代码 + +uint32_t SX1276Process( void ); //SX1276模块接发收数据的处理函数 + +uint32_t SX1276ChannelEmpty( void ); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usart/connect_usart.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usart/connect_usart.c index 58f29fbe8..6552514ec 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usart/connect_usart.c +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usart/connect_usart.c @@ -104,12 +104,22 @@ struct SerialHardwareDevice serial_device_3; void Uart3RxIrqHandler(void) { + x_base lock = 0; + lock = DISABLE_INTERRUPT(); + SerialSetIsr(&serial_device_3, SERIAL_EVENT_RX_IND); + + ENABLE_INTERRUPT(lock); } void Uart3RxErrIrqHandler(void) { + x_base lock = 0; + lock = DISABLE_INTERRUPT(); + UartRxErrIsr(&serial_bus_3, &serial_driver_3, &serial_device_3); + + ENABLE_INTERRUPT(lock); } #endif @@ -120,12 +130,22 @@ struct SerialHardwareDevice serial_device_6; void Uart6RxIrqHandler(void) { + x_base lock = 0; + lock = DISABLE_INTERRUPT(); + SerialSetIsr(&serial_device_6, SERIAL_EVENT_RX_IND); + + ENABLE_INTERRUPT(lock); } void Uart6RxErrIrqHandler(void) { + x_base lock = 0; + lock = DISABLE_INTERRUPT(); + UartRxErrIsr(&serial_bus_6, &serial_driver_6, &serial_device_6); + + ENABLE_INTERRUPT(lock); } #endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Kconfig new file mode 100644 index 000000000..cebb2f422 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Kconfig @@ -0,0 +1,25 @@ +config BSP_USING_HC32_USBH + bool "Using usb host by HC32 library" + default y + if BSP_USING_HC32_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" + config MOUNT_USB_FS + bool "mount usb file system : if y then not support sdcard-mount-fs" + default y + select MOUNT_USB + + if MOUNT_USB_FS + config MOUNT_USB_FS_TYPE + int "choose file system type : FATFS(0)" + default 0 + endif + endif + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Makefile new file mode 100644 index 000000000..b24203a36 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Makefile @@ -0,0 +1,5 @@ +SRC_DIR := hc32_usb_driver + +SRC_FILES := connect_usb.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/connect_usb.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/connect_usb.c new file mode 100644 index 000000000..3c1853b10 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/connect_usb.c @@ -0,0 +1,235 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_usb.c +* @brief support hc32f4a0-board usb function and register to bus framework +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-07 +*/ + +/************************************************* +File name: connect_usb.c +Description: support hc32f4a0-board usb function and register to bus framework +Others: +History: +1. Date: 2022-11-07 +Author: AIIT XUOS Lab +Modification: +1. support hc32f4a0-board usb configure, write and read +2. support hc32f4a0-board usb bus device and driver register +*************************************************/ + +#include + +usb_core_instance usb_app_instance; +USBH_HOST usb_app_host; + +static void UsbHostTask(void *parameter); + +#if defined(FS_VFS) +void UsbMountFileSystem() +{ + if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, FSTYPE_FATFS, UDISK_MOUNTPOINT) == 0) + KPrintf("Mount FAT on Udisk successful.\n"); + else + KPrintf("Mount FAT on Udisk failed.\n"); +} + +void UsbUnmountFileSystem() +{ + UnmountFileSystem(UDISK_MOUNTPOINT); +} + +#ifdef MOUNT_USB +int MountUsb(void) +{ + int32 usb_host_task = 0; + usb_host_task = KTaskCreate("usbh", UsbHostTask, NONE, + USB_HOST_STACK_SIZE, 8); + if(usb_host_task < 0) { + KPrintf("usb_host_task create failed ...%s %d.\n", __FUNCTION__, __LINE__); + return ERROR; + } + + StartupKTask(usb_host_task); + + return 0; +} +#endif +#endif + +static uint32 UsbHostOpen(void *dev) +{ + return EOK; +} + +static uint32 UsbHostClose(void *dev) +{ + return EOK; +} + +static uint32 UsbHostRead(void *dev, struct BusBlockReadParam *read_param) +{ + USB_HOST_MSC_STATUS status = USB_HOST_MSC_OK; + + if (host_driver_ifdevconnected(&usb_app_instance) != 0UL) { + + do { + status = usb_host_msc_Read10(&usb_app_instance, (uint8 *)read_param->buffer, read_param->pos, USB_SINGLE_BLOCK_SIZE * (uint32_t)read_param->size); + usb_host_msc_botxferprocess(&usb_app_instance, &usb_app_host); + + if (host_driver_ifdevconnected(&usb_app_instance) == 0UL) { + return 0; + } + } while (USB_HOST_MSC_BUSY == status); + } + + if (USB_HOST_MSC_OK == status) { + return read_param->size; + } + + return 0; +} + +static uint32 UsbHostWrite(void *dev, struct BusBlockWriteParam *write_param) +{ + USB_HOST_MSC_STATUS status = USB_HOST_MSC_OK; + + if (host_driver_ifdevconnected(&usb_app_instance) != 0UL) { + do { + status = usb_host_msc_Write10(&usb_app_instance, (uint8 *)write_param->buffer, write_param->pos, USB_SINGLE_BLOCK_SIZE * (uint32_t)write_param->size); + usb_host_msc_botxferprocess(&usb_app_instance, &usb_app_host); + + if (host_driver_ifdevconnected(&usb_app_instance) == 0UL) { + return 0; + } + } while (USB_HOST_MSC_BUSY == status); + } + + if (USB_HOST_MSC_OK == status) { + return write_param->size; + } + + return 0; +} + +static int UsbControl(struct HardwareDev *dev, struct HalDevBlockParam *block_param) +{ + NULL_PARAM_CHECK(dev); + + if (OPER_BLK_GETGEOME == block_param->cmd) { + block_param->dev_block.size_perbank = USB_SINGLE_BLOCK_SIZE; + block_param->dev_block.block_size = USB_SINGLE_BLOCK_SIZE; + block_param->dev_block.bank_num = USB_HOST_MSC_Param.MSC_Capacity; + } + + return EOK; +} + +/*manage the usb device operations*/ +static const struct UsbDevDone dev_done = +{ + .open = UsbHostOpen, + .close = UsbHostClose, + .write = UsbHostWrite, + .read = UsbHostRead, +}; + +static void UsbHostTask(void *parameter) +{ + usb_host_init(&usb_app_instance, &usb_app_host, &USBH_MSC_cb, &USR_cb); + while (1) { + usb_host_mainprocess(&usb_app_instance, &usb_app_host); + } +} + +/*Init usb host bus、driver*/ +static int BoardUsbBusInit(struct UsbBus *usb_bus, struct UsbDriver *usb_driver) +{ + x_err_t ret = EOK; + + /*Init the usb bus */ + ret = UsbBusInit(usb_bus, USB_BUS_NAME); + if (EOK != ret) { + KPrintf("board_usb_init UsbBusInit error %d\n", ret); + return ERROR; + } + + /*Init the usb driver*/ + ret = UsbDriverInit(usb_driver, USB_DRIVER_NAME); + if (EOK != ret){ + KPrintf("board_usb_init UsbDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the usb driver to the usb bus*/ + ret = UsbDriverAttachToBus(USB_DRIVER_NAME, USB_BUS_NAME); + if (EOK != ret) { + KPrintf("board_usb_init USEDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the usb device to the usb bus*/ +static int BoardUsbDevBend(void) +{ + x_err_t ret = EOK; + static struct UsbHardwareDevice usb_device; + memset(&usb_device, 0, sizeof(struct UsbHardwareDevice)); + + usb_device.dev_done = &dev_done; + usb_device.haldev.dev_block_control = UsbControl; + + ret = USBDeviceRegister(&usb_device, NONE, USB_DEVICE_NAME); + if (EOK != ret) { + KPrintf("USBDeviceRegister device %s error %d\n", USB_DEVICE_NAME, ret); + return ERROR; + } + + ret = USBDeviceAttachToBus(USB_DEVICE_NAME, USB_BUS_NAME); + if (EOK != ret) { + KPrintf("USBDeviceAttachToBus device %s error %d\n", USB_DEVICE_NAME, ret); + return ERROR; + } + + return ret; +} + +int HwUsbHostInit(void) +{ + x_err_t ret = EOK; + + static struct UsbBus usb_bus; + memset(&usb_bus, 0, sizeof(struct UsbBus)); + + static struct UsbDriver usb_driver; + memset(&usb_driver, 0, sizeof(struct UsbDriver)); + + ret = BoardUsbBusInit(&usb_bus, &usb_driver); + if (EOK != ret) { + KPrintf("BoardUsbBusInit error ret %u\n", ret); + return ERROR; + } + + ret = BoardUsbDevBend(); + if (EOK != ret) { + KPrintf("BoardUsbDevBend error ret %u\n", ret); + return ERROR; + } + + return ret; +} + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/Makefile new file mode 100644 index 000000000..be76fe492 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/Makefile @@ -0,0 +1,5 @@ +SRC_FILES := usb_host_user.c usb_bsp.c + +SRC_DIR := usb_host_lib + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_app_conf.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_app_conf.h new file mode 100644 index 000000000..6ae6f00c4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_app_conf.h @@ -0,0 +1,104 @@ +/** + ******************************************************************************* + * @file usb/usb_host_msc/source/usb_app_conf.h + * @brief low level driver configuration + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_APP_CONF_H__ +#define __USB_APP_CONF_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ + +/* USB MODE CONFIGURATION */ +/* +USB_FS_MODE, USB_HS_MODE, USB_HS_EXTERNAL_PHY defined comment +(1) If only defined USB_FS_MODE: + MCU USBFS core work in full speed using internal PHY. +(2) If only defined USB_HS_MODE: + MCU USBHS core work in full speed using internal PHY. +(3) If both defined USB_HS_MODE && USB_HS_EXTERNAL_PHY + MCU USBHS core work in high speed using external PHY. +(4) Other combination: + Not support, forbid!! +*/ + +//#define USB_HS_MODE +#define USB_FS_MODE + +#define USE_HOST_MODE + +#ifdef USB_HS_MODE +#define USB_HS_EXTERNAL_PHY +#endif + +#ifndef USB_HS_MODE +#ifndef USB_FS_MODE +#error "USB_HS_MODE or USB_FS_MODE should be defined" +#endif +#endif + +#ifndef USE_DEVICE_MODE +#ifndef USE_HOST_MODE +#error "USE_DEVICE_MODE or USE_HOST_MODE should be defined" +#endif +#endif + +/* USB FIFO CONFIGURATION */ +#ifdef USB_FS_MODE +#define RX_FIFO_FS_SIZE (128U) +#define TXH_NP_FS_FIFOSIZ (32U) +#define TXH_P_FS_FIFOSIZ (64U) + +#if ((RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ + TXH_P_FS_FIFOSIZ) > 640U) +#error "The USB max FIFO size is 640 x 4 Bytes!" +#endif +#endif + +#ifdef USB_HS_MODE +#define RX_FIFO_HS_SIZE (512U) +#define TXH_NP_HS_FIFOSIZ (128U) +#define TXH_P_HS_FIFOSIZ (256U) + +#if ((RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ + TXH_P_FS_FIFOSIZ) > 2048U) +#error "The USB max FIFO size is 2048 x 4 Bytes!" +#endif +#endif + +/* FUNCTION CONFIGURATION */ +#define USBH_MAX_NUM_INTERFACES (3U) +#define USBH_MAX_NUM_ENDPOINTS (2U) + +/* CONFIGURATION FOR MSC */ +#define USBH_MSC_MPS_SIZE (0x40U) +//#define USB_MSC_FAT_VALID + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_APP_CONF_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.c new file mode 100644 index 000000000..7e4f4c981 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.c @@ -0,0 +1,147 @@ +/** + ******************************************************************************* + * @file usb/usb_host_msc/source/usb_bsp.c + * @brief BSP function for USB example + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/** +* @file usb_bsp.c +* @brief support hc32f4a0-board usb bsp function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-08 +*/ + +/************************************************* +File name: usb_bsp.c +Description: support hc32f4a0-board usb bsp function +Others: +History: +1. Date: 2022-11-08 +Author: AIIT XUOS Lab +Modification: +1. support hc32f4a0-board usb IO configure +2. support hc32f4a0-board usb irq define +*************************************************/ +#include +#include "usb_bsp.h" +#include + +extern usb_core_instance usb_app_instance; + +/* USBFS Core*/ +#define USB_DP_PORT (GPIO_PORT_A) +#define USB_DP_PIN (GPIO_PIN_12) + +#define USB_DM_PORT (GPIO_PORT_A) +#define USB_DM_PIN (GPIO_PIN_11) + +#define USB_DRVVBUS_PORT (GPIO_PORT_C) +#define USB_DRVVBUS_PIN (GPIO_PIN_09) + +#define USB_VBUSDET_PORT (GPIO_PORT_A) +#define USB_VBUSDET_PIN (GPIO_PIN_09) + +#define USB_OC_PORT (GPIO_PORT_D) +#define USB_OC_PIN (GPIO_PIN_15) + +//USB HOST ISR +static void USB_IRQ_Handler(void) +{ + x_base lock = 0; + lock = DISABLE_INTERRUPT(); + + usb_host_isr(&usb_app_instance); + + ENABLE_INTERRUPT(lock); +} + +void usb_bsp_init(usb_core_instance *pdev) +{ + stc_gpio_init_t stcGpioCfg; + + /* USB clock source configurate */ + CLK_SetUSBClockSrc(CLK_USBCLK_SYSCLK_DIV5); + + (void)GPIO_StructInit(&stcGpioCfg); + +#ifdef USB_FS_MODE + stcGpioCfg.u16PinAttr = PIN_ATTR_ANALOG; + (void)GPIO_Init(USB_DM_PORT, USB_DM_PIN, &stcGpioCfg); + (void)GPIO_Init(USB_DP_PORT, USB_DP_PIN, &stcGpioCfg); + + GPIO_SetFunc(USB_DRVVBUS_PORT, USB_DRVVBUS_PIN, GPIO_FUNC_10); /* VBUS */ + + FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_USBFS, ENABLE); +#endif +} + +void usb_bsp_nvicconfig(void) +{ + stc_irq_signin_config_t stcIrqRegiConf; + /* Register INT_SRC_USBFS_GLB Int to Vect.No.030 */ + stcIrqRegiConf.enIRQn = INT030_IRQn; + /* Select interrupt function */ +#ifdef USB_FS_MODE + stcIrqRegiConf.enIntSrc = INT_SRC_USBFS_GLB; +#else + stcIrqRegiConf.enIntSrc = INT_SRC_USBHS_GLB; +#endif + /* Callback function */ + stcIrqRegiConf.pfnCallback = &USB_IRQ_Handler; + /* Registration IRQ */ + (void)INTC_IrqSignIn(&stcIrqRegiConf); + /* Clear Pending */ + NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn); + /* Set priority */ + NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIO_15); + /* Enable NVIC */ + NVIC_EnableIRQ(stcIrqRegiConf.enIRQn); +} + +void usb_udelay(const uint32_t usec) +{ + __IO uint32_t i; + uint32_t j; + j = (HCLK_VALUE + 1000000UL - 1UL) / 1000000UL * usec; + for (i = 0UL; i < j; i++) { + } +} + +void usb_mdelay(const uint32_t msec) +{ + usb_udelay(msec * 1000); +} + +/** + * @brief Configures the IO for the Vbus and OverCurrent + * @param [in] pdev device instance + * @retval None + */ +void usb_bsp_cfgvbus(LL_USB_TypeDef *USBx) +{ +} + +/** + * @brief Drive vbus + * @param [in] pdev device instance + * @param [in] state the vbus state it would be. + * @retval None + */ +void usb_bsp_drivevbus(LL_USB_TypeDef *USBx, uint8_t state) +{ +} diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.h new file mode 100644 index 000000000..d09cd20a3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.h @@ -0,0 +1,104 @@ +/** + ******************************************************************************* + * @file usb/usb_host_msc/source/usb_bsp.h + * @brief Head file for usb_bsp.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/** +* @file usb_bsp.h +* @brief support hc32f4a0-board usb bsp function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-08 +*/ + +/************************************************* +File name: usb_bsp.h +Description: support hc32f4a0-board usb bsp function +Others: +History: +1. Date: 2022-11-08 +Author: AIIT XUOS Lab +Modification: +*************************************************/ + +#ifndef USB_BSP_H +#define USB_BSP_H + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include + +/** + * @addtogroup HC32F4A0_DDL_Applications + * @{ + */ + +/** + * @addtogroup USB_Host_Msc + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void usb_bsp_init(usb_core_instance *pdev); +extern void usb_udelay(const uint32_t usec); +extern void usb_mdelay(const uint32_t msec); +extern void usb_bsp_nvicconfig(void); +#ifdef USE_HOST_MODE +extern void usb_bsp_cfgvbus(LL_USB_TypeDef *USBx); +extern void usb_bsp_drivevbus(LL_USB_TypeDef *USBx, uint8_t state); +#endif + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_BSP_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/Makefile new file mode 100644 index 000000000..e55e5e056 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/Makefile @@ -0,0 +1,3 @@ +SRC_DIR := host_class host_core + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/Makefile new file mode 100644 index 000000000..947ef2d88 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/Makefile @@ -0,0 +1,3 @@ +SRC_DIR := msc + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/Makefile new file mode 100644 index 000000000..901d58c18 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := usb_host_msc_bot.c usb_host_msc_class.c usb_host_msc_scsi.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.c new file mode 100644 index 000000000..d8509ac8a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.c @@ -0,0 +1,449 @@ +/** + ******************************************************************************* + * @file usb_host_msc_bot.c + * @brief mass storage related functions + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_msc_class.h" +#include "usb_host_msc_scsi.h" +#include "usb_host_msc_bot.h" +#include "usb_host_ctrltrans.h" +#include "usb_host_def.h" +#include "usb_host_int.h" +#include "usb_host_driver.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC USB Host MSC + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ +#ifdef USB_INTERNAL_DMA_ENABLED +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ +#pragma data_alignment=4 +#endif +#endif /* USB_INTERNAL_DMA_ENABLED */ +__USB_ALIGN_BEGIN HOST_CSW_PACKET_TypeDef USBH_MSC_CSWData; + +USB_HOST_BOTXFER_TypeDef USBH_MSC_BOTXferParam; + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +#ifdef USB_INTERNAL_DMA_ENABLED +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ +#pragma data_alignment=4 +#endif +#endif /* USB_INTERNAL_DMA_ENABLED */ +__USB_ALIGN_BEGIN HostCBWPkt_TypeDef USBH_MSC_CBWData; + +static uint32_t BOTStallErrorCount; /* Keeps count of STALL Error Cases*/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief initializes original state of the mass storage parameters + * @param [in] pdev device instance + * @retval None + */ +void usb_host_msc_init(usb_core_instance *pdev) +{ + if (host_driver_ifdevconnected(pdev) != 0UL) { + USBH_MSC_CBWData.field.CBWSignature = HOST_MSC_BOT_CBW_SIGNATURE; + USBH_MSC_CBWData.field.CBWTag = HOST_MSC_BOT_CBW_TAG; + USBH_MSC_CBWData.field.CBWLUN = 0U; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + } + BOTStallErrorCount = 0UL; + MSCErrorCount = 0U; +} + +/** + * @brief manages the different states of BOT transfer and updates the + * status for the upper layer. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval None + */ +void usb_host_msc_botxferprocess(usb_core_instance *pdev, USBH_HOST *phost) +{ + uint8_t xferDirection, index; + static uint32_t remainingDataLength; + static uint8_t *datapointer, *datapointer_prev; + static uint8_t error_direction; + HOST_STATUS status; + + HOST_CH_XFER_STATE URB_Status; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + + switch (USBH_MSC_BOTXferParam.BOTState) { + case HOST_MSC_SEND_CBW: + /* send a CBW */ + usb_host_sendbulkdata(pdev, + &USBH_MSC_CBWData.CBWArray[0], + HOST_MSC_BOT_CBW_PACKET_LENGTH, + MSC_Machine.hc_num_out); + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_SEND_CBW; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SENT_CBW; + break; + case HOST_MSC_SENT_CBW: + URB_Status = host_driver_getxferstate(pdev, MSC_Machine.hc_num_out); + switch (URB_Status) { + case HOST_CH_XFER_DONE: + BOTStallErrorCount = 0U; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_SENT_CBW; + /* If the CBW packet is sent successful, then update the state */ + xferDirection = (USBH_MSC_CBWData.field.CBWFlags & USB_REQ_DIR_MASK); + if (USBH_MSC_CBWData.field.CBWTransferLength != 0UL) { + remainingDataLength = USBH_MSC_CBWData.field.CBWTransferLength ; + datapointer = USBH_MSC_BOTXferParam.pRxTxBuff; + datapointer_prev = datapointer; + /* If there has data transfer stage, update the direction whether it is D2H or H2D */ + if (xferDirection == USB_D2H) { + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_DATAIN_STATE; + } else { + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_DATAOUT_STATE; + } + } else { + /* If there has not data transfer stage also update the state */ + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_RECEIVE_CSW_STATE; + } + break; + case HOST_CH_XFER_UNREADY: + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; + break; + case HOST_CH_XFER_STALL: + error_direction = HOST_MSC_DIR_OUT; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_OUT; + break; + default: + break; + } + break; + + case HOST_MSC_BOT_DATAIN_STATE: + URB_Status = host_driver_getxferstate(pdev, MSC_Machine.hc_num_in); + if ((URB_Status == HOST_CH_XFER_DONE) \ + || (USBH_MSC_BOTXferParam.BOTStateBkp != HOST_MSC_BOT_DATAIN_STATE)) { + BOTStallErrorCount = 0U; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_BOT_DATAIN_STATE; + + if (remainingDataLength > MSC_Machine.MSC_BulkInEpSize) { + usb_host_recvbulkdata(pdev, + datapointer, + MSC_Machine.MSC_BulkInEpSize, + MSC_Machine.hc_num_in); + remainingDataLength -= MSC_Machine.MSC_BulkInEpSize; + datapointer = datapointer + MSC_Machine.MSC_BulkInEpSize; + } else if (remainingDataLength == 0UL) { + /* If value was 0, and successful transfer, then change the state */ + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_RECEIVE_CSW_STATE; + } else { + usb_host_recvbulkdata(pdev, + datapointer, + (uint16_t)remainingDataLength, + MSC_Machine.hc_num_in); + remainingDataLength = 0UL; + } + } else if (URB_Status == HOST_CH_XFER_STALL) { + error_direction = HOST_MSC_DIR_IN; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_IN; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE; + } else { + ; + } + break; + case HOST_MSC_BOT_DATAOUT_STATE: + URB_Status = host_driver_getxferstate(pdev, MSC_Machine.hc_num_out); + if (URB_Status == HOST_CH_XFER_DONE) { + BOTStallErrorCount = 0UL; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_BOT_DATAOUT_STATE; + if (remainingDataLength > MSC_Machine.MSC_BulkOutEpSize) { + usb_host_sendbulkdata(pdev, + datapointer, + MSC_Machine.MSC_BulkOutEpSize, + MSC_Machine.hc_num_out); + datapointer_prev = datapointer; + datapointer = datapointer + MSC_Machine.MSC_BulkOutEpSize; + + remainingDataLength = remainingDataLength - MSC_Machine.MSC_BulkOutEpSize; + } else if (remainingDataLength == 0UL) { + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_RECEIVE_CSW_STATE; + } else { + usb_host_sendbulkdata(pdev, + datapointer, + (uint16_t)remainingDataLength, + MSC_Machine.hc_num_out); + remainingDataLength = 0UL; + } + } else if (URB_Status == HOST_CH_XFER_UNREADY) { + if (datapointer != datapointer_prev) { + usb_host_sendbulkdata(pdev, + (datapointer - MSC_Machine.MSC_BulkOutEpSize), + MSC_Machine.MSC_BulkOutEpSize, + MSC_Machine.hc_num_out); + } else { + usb_host_sendbulkdata(pdev, + datapointer, + MSC_Machine.MSC_BulkOutEpSize, + MSC_Machine.hc_num_out); + } + } else if (URB_Status == HOST_CH_XFER_STALL) { + error_direction = HOST_MSC_DIR_OUT; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_OUT; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE; + } else { + ; + } + break; + + case HOST_MSC_RECEIVE_CSW_STATE: + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE; + USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray; + USBH_MSC_BOTXferParam.DataLength = HOST_MSC_CSW_MAX_LENGTH; + for (index = 0U; index < HOST_MSC_CSW_LENGTH; index++) { + USBH_MSC_CSWData.CSWArray[index] = 0U; + } + + USBH_MSC_CSWData.CSWArray[0] = 0U; + usb_host_recvbulkdata(pdev, + USBH_MSC_BOTXferParam.pRxTxBuff, + HOST_MSC_CSW_MAX_LENGTH, + MSC_Machine.hc_num_in); + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_DECODE_CSW; + + break; + + case HOST_MSC_DECODE_CSW: + URB_Status = host_driver_getxferstate(pdev, MSC_Machine.hc_num_in); + if (URB_Status == HOST_CH_XFER_DONE) { + BOTStallErrorCount = 0UL; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE; + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateCurrent ; + USBH_MSC_BOTXferParam.BOTXferStatus = usb_host_msc_cswdecode(pdev, phost); + } else if (URB_Status == HOST_CH_XFER_STALL) { + error_direction = HOST_MSC_DIR_IN; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_IN; + } else { + ; + } + break; + + case HOST_MSC_BOT_ERROR_IN: + status = usb_host_msc_botabort(pdev, phost, HOST_MSC_DIR_IN); + if (status == HSTATUS_OK) { + if (error_direction == HOST_MSC_BOTH_DIR) { + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_OUT; + } else { + /* switch back to the original state */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; + } + } else if (status == HSTATUS_UNRECOVERED_ERROR) { + /* This means that there is a STALL Error limit, Do Reset Recovery */ + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_PHASE_ERROR; + } else { + ; + } + break; + case HOST_MSC_BOT_ERROR_OUT: + status = usb_host_msc_botabort(pdev, phost, HOST_MSC_DIR_OUT); + if (status == HSTATUS_OK) { + /* switch back to the original state */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; + } else if (status == HSTATUS_UNRECOVERED_ERROR) { + /* This means that there is a STALL Error limit, Do Reset Recovery */ + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_PHASE_ERROR; + } else { + ; + } + break; + + default: + break; + } + } +} + +/** + * @brief manages the different Error handling for STALL + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] direction IN / OUT + * @retval None + */ +HOST_STATUS usb_host_msc_botabort(usb_core_instance *pdev, USBH_HOST *phost, uint8_t direction) +{ + HOST_STATUS status; + + status = HSTATUS_BUSY; + + switch (direction) { + case HOST_MSC_DIR_IN: + /* send ClrFeture on Bulk IN endpoint */ + status = usb_host_clrfeature(pdev, + phost, + MSC_Machine.MSC_BulkInEp, + MSC_Machine.hc_num_in); + break; + case HOST_MSC_DIR_OUT: + /* send ClrFeature on Bulk OUT endpoint */ + status = usb_host_clrfeature(pdev, + phost, + MSC_Machine.MSC_BulkOutEp, + MSC_Machine.hc_num_out); + break; + default: + break; + } + BOTStallErrorCount++; + if (BOTStallErrorCount > 4UL) { + status = HSTATUS_UNRECOVERED_ERROR; + } + return status; +} + +/** + * @brief Decodes the CSW received by the device and updates the same to upper layer + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval On success USB_HOST_MSC_OK, on failure USB_HOST_MSC_FAIL + */ +uint8_t usb_host_msc_cswdecode(usb_core_instance *pdev, USBH_HOST *phost) +{ + USB_HOST_MSC_STATUS status; + uint32_t dataXferCount; + status = USB_HOST_MSC_FAIL; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + dataXferCount = host_driver_getxfercnt(pdev, MSC_Machine.hc_num_in); + if (dataXferCount != HOST_MSC_CSW_LENGTH) { + /*(4) Hi > Dn (Host expects to receive data from the device, + Device intends to transfer no data) + (5) Hi > Di (Host expects to receive data from the device, + Device intends to send data to the host) + (9) Ho > Dn (Host expects to send data to the device, + Device intends to transfer no data) + (11) Ho > Do (Host expects to send data to the device, + Device intends to receive data from the host)*/ + status = USB_HOST_MSC_PHASE_ERROR; + } else { + /* CSW length is Correct */ + + /* Check validity of the CSW Signature and CSWStatus */ + if (USBH_MSC_CSWData.field.dCSWSignature == HOST_MSC_BOT_CSW_SIGNATURE) { + /* Check Condition 1. dCSWSignature is equal to 53425355h */ + if (USBH_MSC_CSWData.field.dCSWTag == USBH_MSC_CBWData.field.CBWTag) { + /* Check Condition 3. dCSWTag matches the dCBWTag from the + corresponding CBW */ + if (USBH_MSC_CSWData.field.dCSWStatus == (uint8_t)USB_HOST_MSC_OK) { + /* Refer to USB Mass-Storage Class : BOT (www.usb.org) + + Hn Host expects no data transfers + Hi Host expects to receive data from the device + Ho Host expects to send data to the device + + Dn Device intends to transfer no data + Di Device intends to send data to the host + Do Device intends to receive data from the host + + Section 6.7 + (1) Hn = Dn (Host expects no data transfers, + Device intends to transfer no data) + (6) Hi = Di (Host expects to receive data from the device, + Device intends to send data to the host) + (12) Ho = Do (Host expects to send data to the device, + Device intends to receive data from the host) + */ + status = USB_HOST_MSC_OK; + } else if (USBH_MSC_CSWData.field.dCSWStatus == (uint8_t)USB_HOST_MSC_FAIL) { + status = USB_HOST_MSC_FAIL; + } else if (USBH_MSC_CSWData.field.dCSWStatus == (uint8_t)USB_HOST_MSC_PHASE_ERROR) { + /* Refer to USB Mass-Storage Class : BOT (www.usb.org) + Section 6.7 + (2) Hn < Di ( Host expects no data transfers, + Device intends to send data to the host) + (3) Hn < Do ( Host expects no data transfers, + Device intends to receive data from the host) + (7) Hi < Di ( Host expects to receive data from the device, + Device intends to send data to the host) + (8) Hi <> Do ( Host expects to receive data from the device, + Device intends to receive data from the host) + (10) Ho <> Di (Host expects to send data to the device, + Di Device intends to send data to the host) + (13) Ho < Do (Host expects to send data to the device, + Device intends to receive data from the host) + */ + status = USB_HOST_MSC_PHASE_ERROR; + } else { + ; + } + } + } else { + status = USB_HOST_MSC_PHASE_ERROR; + } + } + } + + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)status; + return (uint8_t)status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.h new file mode 100644 index 000000000..7950e7b6b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.h @@ -0,0 +1,162 @@ +/** + ******************************************************************************* + * @file usb_host_msc_bot.h + * @brief Head file for usb_host_msc_bot.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_HOST_MSC_BOT_H__ +#define __USB_HOST_MSC_BOT_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_stdreq.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ +typedef union _USBH_CBW_Block { + struct __CBW { + uint32_t CBWSignature; + uint32_t CBWTag; + uint32_t CBWTransferLength; + uint8_t CBWFlags; + uint8_t CBWLUN; + uint8_t CBWLength; + uint8_t CBWCB[16]; + } field; + uint8_t CBWArray[31]; +} HostCBWPkt_TypeDef; + +typedef struct { + uint8_t MSCState; + uint8_t MSCStateBkp; + uint8_t MSCStateCurrent; + uint8_t CmdStateMachine; + uint8_t BOTState; + uint8_t BOTStateBkp; + uint8_t *pRxTxBuff; + uint16_t DataLength; + uint8_t BOTXferStatus; +} USB_HOST_BOTXFER_TypeDef; + +typedef union { + struct { + uint32_t dCSWSignature; + uint32_t dCSWTag; + uint32_t dCSWDataResidue; + uint8_t dCSWStatus; + } field; + uint8_t CSWArray[13]; +} HOST_CSW_PACKET_TypeDef; + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define HOST_MSC_BOT_INIT_STATE (0U) +#define HOST_MSC_BOT_RESET (1U) +#define HOST_MSC_GET_MAX_LUN (2U) +#define HOST_MSC_TEST_UNIT_READY (3U) +#define HOST_MSC_READ_CAPACITY10 (4U) +#define HOST_MSC_MODE_SENSE6 (5U) +#define HOST_MSC_REQUEST_SENSE (6U) +#define HOST_MSC_BOT_USB_TRANSFERS (7U) +#define HOST_MSC_DEFAULT_APPLI_STATE (8U) +#define HOST_MSC_CTRL_ERROR_STATE (9U) +#define HOST_MSC_UNRECOVERED_STATE (10U) + +#define HOST_MSC_SEND_CBW (1U) +#define HOST_MSC_SENT_CBW (2U) +#define HOST_MSC_BOT_DATAIN_STATE (3U) +#define HOST_MSC_BOT_DATAOUT_STATE (4U) +#define HOST_MSC_RECEIVE_CSW_STATE (5U) +#define HOST_MSC_DECODE_CSW (6U) +#define HOST_MSC_BOT_ERROR_IN (7U) +#define HOST_MSC_BOT_ERROR_OUT (8U) + +#define HOST_MSC_BOT_CBW_SIGNATURE (0x43425355UL) +#define HOST_MSC_BOT_CBW_TAG (0x20304050UL) +#define HOST_MSC_BOT_CSW_SIGNATURE (0x53425355UL) +#define HOST_MSC_CSW_DATA_LENGTH (13U) +#define HOST_MSC_BOT_CBW_PACKET_LENGTH (31U) +#define HOST_MSC_CSW_LENGTH (13U) +#define HOST_MSC_CSW_MAX_LENGTH (63U) +#define HOST_MSC_DIR_IN (0U) +#define HOST_MSC_DIR_OUT (1U) +#define HOST_MSC_BOTH_DIR (2U) +#define HOST_MSC_PAGE_LENGTH (512UL) + +#define CBW_CB_LENGTH (16U) +#define CBW_LENGTH (10U) +#define CBW_LENGTH_TEST_UNIT_READY (6U) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ +extern USB_HOST_BOTXFER_TypeDef USBH_MSC_BOTXferParam; +extern HostCBWPkt_TypeDef USBH_MSC_CBWData; +extern HOST_CSW_PACKET_TypeDef USBH_MSC_CSWData; + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void usb_host_msc_init(usb_core_instance *pdev); +extern void usb_host_msc_botxferprocess(usb_core_instance *pdev, USBH_HOST *phost); +extern uint8_t usb_host_msc_cswdecode(usb_core_instance *pdev, USBH_HOST *phost); +extern HOST_STATUS usb_host_msc_botabort(usb_core_instance *pdev, USBH_HOST *phost, uint8_t direction); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_MSC_BOT_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.c new file mode 100644 index 000000000..601b5834e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.c @@ -0,0 +1,395 @@ +/** + ******************************************************************************* + * @file usb_host_msc_class.c + * @brief The MSC class driver functions + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_msc_class.h" +#include "usb_host_msc_scsi.h" +#include "usb_host_msc_bot.h" +#include "usb_host_core.h" +#include "usb_host_driver.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define USBH_MSC_ERROR_RETRY_LIMIT (10U) + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +HOST_STATUS usb_host_msc_itfinit(usb_core_instance *pdev, void *phost); +void usb_host_msc_itfdeinit(usb_core_instance *pdev); +HOST_STATUS usb_host_msc_process(usb_core_instance *pdev, void *phost); +HOST_STATUS usb_host_msc_classreq(usb_core_instance *pdev, void *phost); + +HOST_STATUS usb_host_msc_bot_reset(usb_core_instance *pdev, USBH_HOST *phost); +HOST_STATUS usb_host_msc_maxlun_get(usb_core_instance *pdev, USBH_HOST *phost); +void usb_host_msc_error_process(USB_HOST_MSC_STATUS status); + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ +#ifdef USB_INTERNAL_DMA_ENABLED +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ +#pragma data_alignment=4 +#endif +#endif /* USB_INTERNAL_DMA_ENABLED */ +__USB_ALIGN_BEGIN MSC_Machine_TypeDef MSC_Machine; + +#ifdef USB_INTERNAL_DMA_ENABLED +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ +#pragma data_alignment=4 +#endif +#endif /* USB_INTERNAL_DMA_ENABLED */ +uint8_t MSCErrorCount = 0U; + +usb_host_class_callback_func USBH_MSC_cb = { + &usb_host_msc_itfinit, + &usb_host_msc_itfdeinit, + &usb_host_msc_classreq, + &usb_host_msc_process, +}; + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @brief This request is used to issue a request to reset the msc device and + * its related interface. This class-specific request shall prepare the + * device for the next CBW from the host. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status define by HOST_STATUS + */ +HOST_STATUS usb_host_msc_bot_reset(usb_core_instance *pdev, USBH_HOST *phost) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | \ + USB_REQ_RECIPIENT_INTERFACE; + phost->ctrlparam.setup.b.bRequest = USB_REQ_BOT_RESET; + phost->ctrlparam.setup.b.wValue.w = 0U; + phost->ctrlparam.setup.b.wIndex.w = 0U; + phost->ctrlparam.setup.b.wLength.w = 0U; + return usb_host_ctrlreq(pdev, phost, NULL, 0U); +} + +/** + * @brief this request is used to issue a request to get the max logic unit of + * the msc device. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status defined by HOST_STATUS + */ +HOST_STATUS usb_host_msc_maxlun_get(usb_core_instance *pdev, USBH_HOST *phost) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \ + USB_REQ_RECIPIENT_INTERFACE; + + phost->ctrlparam.setup.b.bRequest = USB_REQ_GET_MAX_LUN; + phost->ctrlparam.setup.b.wValue.w = 0U; + phost->ctrlparam.setup.b.wIndex.w = 0U; + phost->ctrlparam.setup.b.wLength.w = 1U; + return usb_host_ctrlreq(pdev, phost, MSC_Machine.buff, 1U); +} + +/** + * @brief The function is used for handling errors during processing the MSC + * state machine + * @param [in] status + * @retval None + */ +void usb_host_msc_error_process(USB_HOST_MSC_STATUS status) +{ + switch (status) { + case USB_HOST_MSC_FAIL: + MSCErrorCount++; + if (MSCErrorCount < USBH_MSC_ERROR_RETRY_LIMIT) { + /* Try MSC level error recovery, Issue the request Sense to get + driver error reason */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_REQUEST_SENSE; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + } else { + /* Error trials exceeded the limit, go to unrecovered state */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_UNRECOVERED_STATE; + } + break; + case USB_HOST_MSC_PHASE_ERROR: + /* Phase error, Go to Unrecoovered state */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_UNRECOVERED_STATE; + break; + default: + break; + } +} + +/** + * @brief Interface initialization for msc class application, the channels for + * the IN and OUT EP will be distributed. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status defined by HOST_STATUS + */ +HOST_STATUS usb_host_msc_itfinit(usb_core_instance *pdev, void *phost) +{ + USBH_HOST *pphost = phost; + + if ((pphost->device_prop.devitfdesc[0].bInterfaceClass == MSC_CLASS) && \ + (pphost->device_prop.devitfdesc[0].bInterfaceProtocol == MSC_PROTOCOL)) { + if ((pphost->device_prop.devepdesc[0][0].bEndpointAddress & 0x80U) == 0x80U) { + MSC_Machine.MSC_BulkInEp = (pphost->device_prop.devepdesc[0][0].bEndpointAddress); + MSC_Machine.MSC_BulkInEpSize = pphost->device_prop.devepdesc[0][0].wMaxPacketSize; + } else { + MSC_Machine.MSC_BulkOutEp = (pphost->device_prop.devepdesc[0][0].bEndpointAddress); + MSC_Machine.MSC_BulkOutEpSize = pphost->device_prop.devepdesc[0] [0].wMaxPacketSize; + } + if ((pphost->device_prop.devepdesc[0][1].bEndpointAddress & 0x80U) == 0x80U) { + MSC_Machine.MSC_BulkInEp = (pphost->device_prop.devepdesc[0][1].bEndpointAddress); + MSC_Machine.MSC_BulkInEpSize = pphost->device_prop.devepdesc[0][1].wMaxPacketSize; + } else { + MSC_Machine.MSC_BulkOutEp = (pphost->device_prop.devepdesc[0][1].bEndpointAddress); + MSC_Machine.MSC_BulkOutEpSize = pphost->device_prop.devepdesc[0][1].wMaxPacketSize; + } + /* distribute the channels for the EPs */ + MSC_Machine.hc_num_out = usb_host_distrch(pdev, MSC_Machine.MSC_BulkOutEp); + MSC_Machine.hc_num_in = usb_host_distrch(pdev, MSC_Machine.MSC_BulkInEp); + /* open the channels that have distributed */ + usb_host_chopen(pdev, + MSC_Machine.hc_num_out, + pphost->device_prop.devaddr, + pphost->device_prop.devspeed, + EP_TYPE_BULK, + MSC_Machine.MSC_BulkOutEpSize); + usb_host_chopen(pdev, + MSC_Machine.hc_num_in, + pphost->device_prop.devaddr, + pphost->device_prop.devspeed, + EP_TYPE_BULK, + MSC_Machine.MSC_BulkInEpSize); + } else { + pphost->user_callbk->huser_devunsupported(); + } + return HSTATUS_OK ; +} + +/** + * @brief deinitialize interface of msc class by freeing host channels + * @param [in] pdev device instance + * @retval None + */ +void usb_host_msc_itfdeinit(usb_core_instance *pdev) +{ + if (MSC_Machine.hc_num_out != 0U) { + usb_hchstop(&pdev->regs, MSC_Machine.hc_num_out); + (void)usb_host_freech(pdev, MSC_Machine.hc_num_out); + MSC_Machine.hc_num_out = 0U; + } + if (MSC_Machine.hc_num_in != 0U) { + usb_hchstop(&pdev->regs, MSC_Machine.hc_num_in); + (void)usb_host_freech(pdev, MSC_Machine.hc_num_in); + MSC_Machine.hc_num_in = 0U; + } +} + +/** + * @brief initialize the msc state machine + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status defined by HOST_STATUS + */ +HOST_STATUS usb_host_msc_classreq(usb_core_instance *pdev, void *phost) +{ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_INIT_STATE; + return HSTATUS_OK; +} + +/** + * @brief process the msc state machine + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status defined by HOST_STATUS + */ +HOST_STATUS usb_host_msc_process(usb_core_instance *pdev, void *phost) +{ + USBH_HOST *pphost = phost; + HOST_STATUS status = HSTATUS_BUSY; + USB_HOST_MSC_STATUS mscStatus; + uint8_t appliStatus; + static uint8_t maxLunExceed = FALSE; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.MSCState) { + case HOST_MSC_BOT_INIT_STATE: + usb_host_msc_init(pdev); + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_RESET; + break; + case HOST_MSC_BOT_RESET: + /* issue a request to reset the bot. */ + status = usb_host_msc_bot_reset(pdev, phost); + if (status == HSTATUS_OK) { + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_GET_MAX_LUN; + } + if (status == HSTATUS_UNSUPPORTED) { + /* if the request fails, it needs to move to next state and should save the next state as backup */ + USBH_MSC_BOTXferParam.MSCStateBkp = HOST_MSC_GET_MAX_LUN; + /* a clear feature should be issued if the request fails. */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_CTRL_ERROR_STATE; + } + break; + case HOST_MSC_GET_MAX_LUN: + /* issue a request to get the max logical unit(MAXLUN). */ + status = usb_host_msc_maxlun_get(pdev, phost); + if (status == HSTATUS_OK) { + MSC_Machine.maxLun = *(MSC_Machine.buff) ; + if ((MSC_Machine.maxLun > 0U) && (maxLunExceed == FALSE)) { + maxLunExceed = TRUE; + pphost->user_callbk->huser_devunsupported(); + break; + } + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_TEST_UNIT_READY; + } + + if (status == HSTATUS_UNSUPPORTED) { + /* if the request fails, it needs to move to next state and should save the next state as backup */ + USBH_MSC_BOTXferParam.MSCStateBkp = HOST_MSC_TEST_UNIT_READY; + /* a clear feature should be issued if the request fails. */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_CTRL_ERROR_STATE; + } + break; + case HOST_MSC_CTRL_ERROR_STATE: + /* issue a request to clear feature */ + status = usb_host_clrfeature(pdev, + phost, + 0x00U, + pphost->ctrlparam.hc_num_out); + if (status == HSTATUS_OK) { + /* If GetMaxLun Request not support, assume Single LUN configuration */ + MSC_Machine.maxLun = 0U; + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp; + } + break; + case HOST_MSC_TEST_UNIT_READY: + /* issue the request Test Unit Ready[0] of SCSI command */ + mscStatus = usb_host_msc_TestUnitReady(pdev); + + if (mscStatus == USB_HOST_MSC_OK) { + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_READ_CAPACITY10; + MSCErrorCount = 0U; + status = HSTATUS_OK; + } else { + usb_host_msc_error_process(mscStatus); + } + break; + + case HOST_MSC_READ_CAPACITY10: + /* issue the request Read Capacity[0] of SCSI command. */ + mscStatus = usb_host_msc_ReadCapacity10(pdev); + if (mscStatus == USB_HOST_MSC_OK) { + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_MODE_SENSE6; + MSCErrorCount = 0U; + status = HSTATUS_OK; + } else { + usb_host_msc_error_process(mscStatus); + } + break; + case HOST_MSC_MODE_SENSE6: + /* issue the request ModeSense6 of SCSI command for detecting whelth the deviec is write-protected. */ + mscStatus = usb_host_msc_ModeSense6(pdev); + if (mscStatus == USB_HOST_MSC_OK) { + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_DEFAULT_APPLI_STATE; + MSCErrorCount = 0U; + status = HSTATUS_OK; + } else { + usb_host_msc_error_process(mscStatus); + } + break; + case HOST_MSC_REQUEST_SENSE: + /* issue the request RequestSense of SCSI command for retreiving error code. */ + mscStatus = usb_host_msc_RequestSense(pdev); + if (mscStatus == USB_HOST_MSC_OK) { + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp; + status = HSTATUS_OK; + } else { + usb_host_msc_error_process(mscStatus); + } + break; + case HOST_MSC_BOT_USB_TRANSFERS: + /* handle the BOT state machine. */ + usb_host_msc_botxferprocess(pdev, phost); + break; + case HOST_MSC_DEFAULT_APPLI_STATE: + /* handle the user callback for the msc application. */ + appliStatus = pphost->user_callbk->huser_application(); + if (appliStatus == 0U) { + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_DEFAULT_APPLI_STATE; + } else if (appliStatus == 1U) { + /* deinit requested from the application layer. */ + status = HSTATUS_APP_DEINIT; + } else { + ; + } + break; + case HOST_MSC_UNRECOVERED_STATE: + status = HSTATUS_UNRECOVERED_ERROR; + break; + default: + break; + } + } + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.h new file mode 100644 index 000000000..fc3b7cfff --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.h @@ -0,0 +1,113 @@ +/** + ******************************************************************************* + * @file usb_host_msc_class.h + * @brief Head file for usb_host_msc_class.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_HOST_MSC_CLASS_H__ +#define __USB_HOST_MSC_CLASS_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_core.h" +#include "usb_host_stdreq.h" +#include "usb_bsp.h" +#include "usb_host_ctrltrans.h" +#include "usb_host_cfgch.h" +#include "usb_host_msc_class.h" +#include "usb_host_msc_scsi.h" +#include "usb_host_msc_bot.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/* Structure for MSC process */ +typedef struct { + uint8_t hc_num_in; + uint8_t hc_num_out; + uint8_t MSC_BulkOutEp; + uint8_t MSC_BulkInEp; + uint16_t MSC_BulkInEpSize; + uint16_t MSC_BulkOutEpSize; + uint8_t buff[USBH_MSC_MPS_SIZE]; + uint8_t maxLun; +} MSC_Machine_TypeDef; + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define USB_REQ_BOT_RESET (0xFFU) +#define USB_REQ_GET_MAX_LUN (0xFEU) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ +extern usb_host_class_callback_func USBH_MSC_cb; +extern MSC_Machine_TypeDef MSC_Machine; +extern uint8_t MSCErrorCount; + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_MSC_CLASS_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ + + + + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_fatfs.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_fatfs.c new file mode 100644 index 000000000..0a7e302f3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_fatfs.c @@ -0,0 +1,241 @@ +/** + ******************************************************************************* + * @file usb_host_msc_fatfs.c + * @brief The fatfs functions. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_app_conf.h" +#include "usb_host_driver.h" +#ifdef USB_MSC_FAT_VALID +#include "ff.h" +#include "diskio.h" +#include "usb_host_msc_class.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +extern usb_core_instance usb_app_instance; +extern USBH_HOST usb_app_host; + +/** + * @brief Initialize Disk Drive + * @param [in] drv Physical drive number (0) + * @retval DSTATUS + */ +DSTATUS disk_initialize(BYTE drv) +{ + if (host_driver_ifdevconnected(&usb_app_instance) != 0UL) { + Stat &= (DSTATUS)~STA_NOINIT; + } + return Stat; +} + +/** + * @brief Get Disk Status + * @param [in] drv Physical drive number (0) + * @retval DSTATUS + */ +DSTATUS disk_status(BYTE drv) +{ + DSTATUS status = Stat; + if (drv != 0U) { + status = STA_NOINIT; /* Supports only single drive */ + } + return status; +} + +/** + * @brief Read Sector(s) + * @param [in] drv Physical drive number (0) + * @param [in] buff Pointer to the data buffer to store read data + * @param [in] sector Start sector number (LBA) + * @param [in] count Sector count (1..255) + * @retval DSTATUS + */ +DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) +{ + USB_HOST_MSC_STATUS status = USB_HOST_MSC_OK; + + if ((pdrv != 0U) || (count == 0UL)) { + return RES_PARERR; + } + if ((Stat & STA_NOINIT) == STA_NOINIT) { + return RES_NOTRDY; + } + + if (host_driver_ifdevconnected(&usb_app_instance) != 0UL) { + + do { + status = usb_host_msc_Read10(&usb_app_instance, buff, sector, 512UL * (uint32_t)count); + usb_host_msc_botxferprocess(&usb_app_instance, &usb_app_host); + + if (host_driver_ifdevconnected(&usb_app_instance) == 0UL) { + return RES_ERROR; + } + } while (status == USB_HOST_MSC_BUSY); + } + + if (status == USB_HOST_MSC_OK) { + return RES_OK; + } + return RES_ERROR; + +} + + +#if _READONLY == 0 +/** + * @brief Write Sector(s) + * @param [in] drv Physical drive number (0) + * @param [in] buff Pointer to the data to be written + * @param [in] sector Start sector number (LBA) + * @param [in] count Sector count (1..255) + * @retval DSTATUS + */ +DRESULT disk_write(BYTE pdrv, const BYTE *buff, LBA_t sector, UINT count) +{ + USB_HOST_MSC_STATUS status = USB_HOST_MSC_OK; + + if ((pdrv != 0U) || (count == 0UL)) { + return RES_PARERR; + } + if ((Stat & STA_NOINIT) == STA_NOINIT) { + return RES_NOTRDY; + } + if ((Stat & STA_PROTECT) == STA_PROTECT) { + return RES_WRPRT; + } + if (host_driver_ifdevconnected(&usb_app_instance) != 0UL) { + do { + status = usb_host_msc_Write10(&usb_app_instance, (BYTE *)buff, sector, 512UL * (uint32_t)count); + usb_host_msc_botxferprocess(&usb_app_instance, &usb_app_host); + + if (host_driver_ifdevconnected(&usb_app_instance) == 0UL) { + return RES_ERROR; + } + } while (status == USB_HOST_MSC_BUSY); + } + + if (status == USB_HOST_MSC_OK) { + return RES_OK; + } + return RES_ERROR; +} +#endif /* _READONLY == 0 */ + +//#if _USE_IOCTL != 0 +/** + * @brief Miscellaneous Functions + * @param [in] drv Physical drive number (0) + * @param [in] ctrl Control code + * @param [in] buff Buffer to send/receive control data + ** + * @retval DSTATUS + */ +DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) +{ + DRESULT res; + + if (pdrv != 0U) { + return RES_PARERR; + } + + res = RES_ERROR; + + if ((Stat & STA_NOINIT) == STA_NOINIT) { + return RES_NOTRDY; + } + + switch (cmd) { + case CTRL_SYNC : /* Make sure that no pending write process */ + res = RES_OK; + break; + case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ + *(DWORD *)buff = (DWORD) USB_HOST_MSC_Param.MSC_Capacity; + res = RES_OK; + break; + case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */ + *(WORD *)buff = 512U; + res = RES_OK; + break; + case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ + *(DWORD *)buff = 512UL; + break; + default: + res = RES_PARERR; + break; + } + return res; +} +//#endif +#endif /* _USE_IOCTL != 0 */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.c new file mode 100644 index 000000000..f5964cc9c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.c @@ -0,0 +1,528 @@ +/** + ******************************************************************************* + * @file usb_host_msc_scsi.c + * @brief The SCSI commands。 + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_msc_class.h" +#include "usb_host_msc_scsi.h" +#include "usb_host_msc_bot.h" +#include "usb_host_ctrltrans.h" +#include "usb_host_def.h" +#include "usb_host_driver.h" +#include + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ +MSC_PARAMETER USB_HOST_MSC_Param; + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +#ifdef USB_INTERNAL_DMA_ENABLED +#if defined ( __ICCARM__ ) +#pragma data_alignment=4 +#endif +#endif +__USB_ALIGN_BEGIN static uint8_t USB_HOST_DataInBuf[512]; + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief Issues 'Test Unit Ready' command to the device. Once the response + * received, it updates the status to upper layer, the length of the + * command are 31bytes. + * @param [in] pdev device instance + * @retval status define by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_TestUnitReady(usb_core_instance *pdev) +{ + uint8_t index; + USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + USBH_MSC_CBWData.field.CBWTransferLength = 0UL; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH_TEST_UNIT_READY; + USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray; + USBH_MSC_BOTXferParam.DataLength = HOST_MSC_CSW_MAX_LENGTH; + USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_TEST_UNIT_READY; + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_TEST_UNIT_READY; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + /* Start the transfer, then let the state machine magage the other transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_FAIL; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + default: + break; + } + } + return status; +} + +/** + * @brief Issue the 'Read capacity10' command to the device. Once the response + * received, it updates the status to upper layer + * @param [in] pdev device instance + * @retval status define by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_ReadCapacity10(usb_core_instance *pdev) +{ + uint8_t index; + USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_READ_CAPACITY10; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + USBH_MSC_BOTXferParam.pRxTxBuff = USB_HOST_DataInBuf; + USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_READ_CAPACITY10; + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ_CAPACITY10; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + /* Start the transfer, then let the state machine manage the other + transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + /*assign the capacity*/ + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Capacity)[3]) = USB_HOST_DataInBuf[0]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Capacity)[2]) = USB_HOST_DataInBuf[1]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Capacity)[1]) = USB_HOST_DataInBuf[2]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Capacity)[0]) = USB_HOST_DataInBuf[3]; + /*assign the page length*/ + (((uint8_t *)&USB_HOST_MSC_Param.MSC_PageLength)[1]) = USB_HOST_DataInBuf[6]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_PageLength)[0]) = USB_HOST_DataInBuf[7]; + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_FAIL; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + + default: + break; + } + } + return status; +} + +/** + * @brief Issue the 'Mode Sense6' Command to the device. This function is used + * for reading the WriteProtect Status of the MSC device. + * @param [in] pdev device instance + * @retval status by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_ModeSense6(usb_core_instance *pdev) +{ + uint8_t index; + USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_MODE_SENSE6; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + + USBH_MSC_BOTXferParam.pRxTxBuff = USB_HOST_DataInBuf; + USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_MODE_SENSE6; + + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_MODE_SENSE6; + USBH_MSC_CBWData.field.CBWCB[2] = MODE_SENSE_PAGE_CONTROL_FIELD | \ + MODE_SENSE_PAGE_CODE; + + USBH_MSC_CBWData.field.CBWCB[4] = XFER_LEN_MODE_SENSE6; + + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + + /* Start the transfer, then let the state machine manage the other + transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + /* Assign the Write Protect status */ + /* If WriteProtect = 0, Writing is allowed + If WriteProtect != 0, Disk is Write Protected */ + if (0U != (USB_HOST_DataInBuf[2] & MASK_MODE_SENSE_WRITE_PROTECT)) { + USB_HOST_MSC_Param.MSC_WriteProtect = DISK_WRITE_PROTECTED; + } else { + USB_HOST_MSC_Param.MSC_WriteProtect = 0U; + } + + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_FAIL; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + + default: + break; + } + } + return status; +} + +/** + * @brief usb_host_msc_RequestSense + * Issues the Request Sense command to the device. Once the response + * received, it updates the status to upper layer + * @param [in] pdev device instance + * @retval status defined by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_RequestSense(usb_core_instance *pdev) +{ + USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + uint8_t index; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = \ + ALLOCATION_LENGTH_REQUEST_SENSE; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + + USBH_MSC_BOTXferParam.pRxTxBuff = USB_HOST_DataInBuf; + USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_BOTXferParam.MSCStateCurrent; + USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_REQUEST_SENSE; + + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_REQUEST_SENSE; + USBH_MSC_CBWData.field.CBWCB[1] = DESC_REQUEST_SENSE; + USBH_MSC_CBWData.field.CBWCB[4] = ALLOCATION_LENGTH_REQUEST_SENSE; + + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + /* Start the transfer, then let the state machine magage + the other transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + /* Get Sense data*/ + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Sense)[3]) = USB_HOST_DataInBuf[0]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Sense)[2]) = USB_HOST_DataInBuf[1]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Sense)[1]) = USB_HOST_DataInBuf[2]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Sense)[0]) = USB_HOST_DataInBuf[3]; + + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_FAIL; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + + default: + break; + } + } + return status; +} + +/** + * @brief issue the 'Write10 ' command to the device. Once the response received, + * it updates the status to upper layer + * @param [in] pdev device instance + * @param [in] dataBuffer data buffer contains the data to write + * @param [in] address address to which the data will be written + * @param [in] nbOfbytes NbOfbytes to be written + * @retval status define by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_Write10(usb_core_instance *pdev, + uint8_t *dataBuffer, + uint32_t address, + uint32_t nbOfbytes) +{ + uint8_t index; + USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + uint16_t nbOfPages; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer; + + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_WRITE10; + /*logical block address*/ + USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t *)&address)[3]) ; + USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t *)&address)[2]); + USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t *)&address)[1]); + USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t *)&address)[0]); + + /*HOST_MSC_PAGE_LENGTH = 512*/ + nbOfPages = (uint16_t)(nbOfbytes / HOST_MSC_PAGE_LENGTH); + + /*Tranfer length */ + USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ; + USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ; + + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + /* Start the transfer, then let the state machine + magage the other transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + + default: + break; + } + } + return status; +} + +/** + * @brief issue the read command to the device. Once the response received, + * it updates the status to upper layer + * @param [in] pdev device instance + * @param [in] dataBuffer data buffer will contain the data to be read + * @param [in] address Address from which the data will be read + * @param [in] nbOfbytes number of bytes to be read + * @retval status defined by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_Read10(usb_core_instance *pdev, + uint8_t *dataBuffer, + uint32_t address, + uint32_t nbOfbytes) +{ + uint8_t index; + static USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + uint16_t nbOfPages; + status = USB_HOST_MSC_BUSY; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + + USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer; + + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ10; + + /*logical block address*/ + USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t *)&address)[3]); + USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t *)&address)[2]); + USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t *)&address)[1]); + USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t *)&address)[0]); + /*HOST_MSC_PAGE_LENGTH = 512*/ + nbOfPages = (uint16_t)(nbOfbytes / HOST_MSC_PAGE_LENGTH); + /*Tranfer length */ + USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ; + USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + /* Start the transfer, then let the state machine + magage the other transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + + default: + break; + } + } + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.h new file mode 100644 index 000000000..e3336a8aa --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.h @@ -0,0 +1,136 @@ +/** + ******************************************************************************* + * @file usb_host_msc_scsi.h + * @brief Head file for usb_host_msc_scsi.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_HOST_MSC_SCSI_H__ +#define __USB_HOST_MSC_SCSI_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_stdreq.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/* USBH_MSC_SCSI_Exported_Types */ +typedef enum { + USB_HOST_MSC_OK = 0U, + USB_HOST_MSC_FAIL, + USB_HOST_MSC_PHASE_ERROR, + USB_HOST_MSC_BUSY +} USB_HOST_MSC_STATUS; + +typedef struct { + uint32_t MSC_Capacity; + uint32_t MSC_Sense; + uint16_t MSC_PageLength; + uint8_t MSC_BulkOutEP; + uint8_t MSC_BulkInEP; + uint8_t MSC_WriteProtect; +} MSC_PARAMETER; + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define USB_HOST_MSC_CMD_SEND (1) +#define USB_HOST_MSC_CMD_WAIT (2) + +#define OPCODE_TEST_UNIT_READY (0x00U) +#define OPCODE_READ_CAPACITY10 (0x25U) +#define OPCODE_MODE_SENSE6 (0x1AU) +#define OPCODE_READ10 (0x28U) +#define OPCODE_WRITE10 (0x2AU) +#define OPCODE_REQUEST_SENSE (0x03U) + +#define DESC_REQUEST_SENSE (0x00U) +#define ALLOCATION_LENGTH_REQUEST_SENSE (63U) +#define XFER_LEN_READ_CAPACITY10 (8U) +#define XFER_LEN_MODE_SENSE6 (63U) + +#define MASK_MODE_SENSE_WRITE_PROTECT (0x80U) +#define MODE_SENSE_PAGE_CONTROL_FIELD (0x00U) +#define MODE_SENSE_PAGE_CODE (0x3FU) +#define DISK_WRITE_PROTECTED (0x01U) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ +extern MSC_PARAMETER USB_HOST_MSC_Param; + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern USB_HOST_MSC_STATUS usb_host_msc_TestUnitReady(usb_core_instance *pdev); +extern USB_HOST_MSC_STATUS usb_host_msc_ReadCapacity10(usb_core_instance *pdev); +extern USB_HOST_MSC_STATUS usb_host_msc_ModeSense6(usb_core_instance *pdev); +extern USB_HOST_MSC_STATUS usb_host_msc_RequestSense(usb_core_instance *pdev); +extern USB_HOST_MSC_STATUS usb_host_msc_Write10(usb_core_instance *pdev, + uint8_t *dataBuffer, + uint32_t address, + uint32_t nbOfbytes); +extern USB_HOST_MSC_STATUS usb_host_msc_Read10(usb_core_instance *pdev, + uint8_t *dataBuffer, + uint32_t address, + uint32_t nbOfbytes); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_MSC_SCSI_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ + + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/Makefile new file mode 100644 index 000000000..f7cdc020a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := usb_host_cfgch.c usb_host_core.c usb_host_ctrltrans.c usb_host_driver.c usb_host_int.c usb_host_stdreq.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.c new file mode 100644 index 000000000..90a3884fb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.c @@ -0,0 +1,202 @@ +/** + ******************************************************************************* + * @file usb_host_cfgch.c + * @brief Functions for opening and closing host channels + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_cfgch.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE LL USB Host Core + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +uint16_t usb_host_getfreech(usb_core_instance *pdev); + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief configure and open a pipe + * @param [in] pdev device instance + * @param [in] hc_num host channel index + * @param [in] dev_address USB Device address allocated to attached device + * @param [in] speed core speed + * @param [in] ep_type communication type of the EP + * @param [in] mps max size of the packet + * @retval None + */ +void usb_host_chopen(usb_core_instance *pdev, + uint8_t hc_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + pdev->host.hc[hc_num].ep_idx = (uint8_t) pdev->host.channel[hc_num] & 0x7Fu; + pdev->host.hc[hc_num].is_epin = (uint8_t)((pdev->host.channel[hc_num] & 0x80U) == 0x80U); + pdev->host.hc[hc_num].dev_addr = dev_address; + pdev->host.hc[hc_num].ep_type = ep_type; + pdev->host.hc[hc_num].max_packet = mps; + pdev->host.hc[hc_num].ch_speed = speed; + pdev->host.hc[hc_num].in_toggle = 0U; + pdev->host.hc[hc_num].out_toggle = 0U; + + (void)usb_inithch(&pdev->regs, hc_num, &pdev->host.hc[hc_num], pdev->basic_cfgs.dmaen); +} + +/** + * @brief change a pipe on host + * @param [in] pdev device instance + * @param [in] hc_num host channel index + * @param [in] dev_address USB Device address allocated to attached device + * @param [in] speed core speed + * @param [in] ep_type communication type of EP + * @param [in] mps max size of packet + * @retval None + */ +void usb_host_mdfch(usb_core_instance *pdev, + uint8_t hc_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + (void)(ep_type); + if (dev_address != 0U) { + pdev->host.hc[hc_num].dev_addr = dev_address; + } + if ((pdev->host.hc[hc_num].max_packet != mps) && (mps != 0U)) { + pdev->host.hc[hc_num].max_packet = mps; + } + if ((pdev->host.hc[hc_num].ch_speed != speed) && (speed != 0U)) { + pdev->host.hc[hc_num].ch_speed = speed; + } + + (void)usb_inithch(&pdev->regs, hc_num, &pdev->host.hc[hc_num], pdev->basic_cfgs.dmaen); +} + +/** + * @brief distribute a new channel for the pipe + * @param [in] pdev device instance + * @param [in] ep_addr EP index the channel distributed for + * @retval hc_num host channel index + */ +uint8_t usb_host_distrch(usb_core_instance *pdev, uint8_t ep_addr) +{ + __IO uint16_t hc_num; + + hc_num = usb_host_getfreech(pdev); + if (hc_num != HC_ERROR) { + pdev->host.channel[hc_num & (USB_MAX_TX_FIFOS - 1U)] = HC_USED | ep_addr; + } + return (uint8_t)hc_num; +} + +/** + * @brief free the USB host channel assigned by idx + * @param [in] pdev device instance + * @param [in] idx Channel number to be freed + * @retval Status + */ +uint8_t usb_host_freech(usb_core_instance *pdev, uint8_t idx) +{ + if (idx < MAX_CHNUM) { + pdev->host.channel[idx & (USB_MAX_TX_FIFOS - 1U)] &= HC_USED_MASK; + } + return (uint8_t)HSTATUS_OK; +} + +/** + * @brief free all the USB host channels + * @param [in] pdev device instance + * @retval None + */ +void usb_host_dedistrallch(usb_core_instance *pdev) +{ + uint8_t idx; + + for (idx = 2U; idx < MAX_CHNUM ; idx ++) { + pdev->host.channel[idx & (USB_MAX_TX_FIFOS - 1U)] = 0U; + } +} + +/** + * @brief Get a free channel number so that can be distributed to a device endpoint + * @param [in] pdev device instance + * @retval idx the free channel index + */ +uint16_t usb_host_getfreech(usb_core_instance *pdev) +{ + uint8_t tmp_idx; + uint16_t u16Ret = HC_ERROR; + + for (tmp_idx = 0U ; tmp_idx < MAX_CHNUM ; tmp_idx++) { + if ((pdev->host.channel[tmp_idx & (USB_MAX_TX_FIFOS - 1U)] & HC_USED) == 0U) { + u16Ret = HC_OK; + break; + } + } + + if (u16Ret == HC_OK) { + u16Ret = tmp_idx; + } else { + u16Ret = HC_ERROR; + } + + return u16Ret; +} + +/** + * @} + */ + +/** + * @} + */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.h new file mode 100644 index 000000000..bea377cde --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.h @@ -0,0 +1,103 @@ +/** + ******************************************************************************* + * @file usb_host_cfgch.h + * @brief header file for the usb_host_cfgch.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_HOST_CFGCH_H__ +#define __USB_HOST_CFGCH_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/* USBH_HCS_Exported_Defines */ +#define MAX_CHNUM (12U) + +#define HC_OK (0x0000U) +#define HC_USED (0x8000U) +#define HC_ERROR (0xFFFFU) +#define HC_USED_MASK (0x7FFFU) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern uint8_t usb_host_distrch(usb_core_instance *pdev, uint8_t ep_addr); + +extern uint8_t usb_host_freech(usb_core_instance *pdev, uint8_t idx); + +extern void usb_host_dedistrallch(usb_core_instance *pdev); + +extern void usb_host_chopen(usb_core_instance *pdev, + uint8_t hc_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps); + +extern void usb_host_mdfch(usb_core_instance *pdev, + uint8_t hc_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_CFGCH_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.c new file mode 100644 index 000000000..3026c0bd6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.c @@ -0,0 +1,537 @@ +/** + ******************************************************************************* + * @file usb_host_core.c + * @brief The core state machine process the enumeration and the control transfer process + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include +#include "usb_host_core.h" +#include "usb_host_cfgch.h" +#include "usb_host_ctrltrans.h" +#include "usb_host_driver.h" +#include "usb_host_stdreq.h" +#include "usb_host_int.h" +#include "usb_bsp.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +HOST_STATUS usb_host_ctrlprocess(usb_core_instance *pdev, USBH_HOST *phost); +HOST_STATUS usb_host_enumprocess(usb_core_instance *pdev, USBH_HOST *phost); + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +static uint8_t Local_Buffer[ENUM_LOCAL_BUF]; + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief initialization for the host application + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] class_cbk the call back function for the class application + * @param [in] user_cbk the call back function for user + * @retval None + */ +void usb_host_init(usb_core_instance *pdev, + USBH_HOST *phost, + usb_host_class_callback_func *class_cbk, + usb_host_user_callback_func *user_cbk) +{ + usb_bsp_init(pdev); + usb_host_deinit(pdev, phost); + phost->class_callbk = class_cbk; + phost->user_callbk = user_cbk; + host_driver_init(pdev); + phost->user_callbk->huser_init(); + usb_bsp_nvicconfig(); +} + +/** + * @brief deinitialize the host application + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval None + */ +void usb_host_deinit(usb_core_instance *pdev, USBH_HOST *phost) +{ + phost->host_state = HOST_IDLE; + phost->host_state_backup = HOST_IDLE; + phost->enum_state = ENUM_IDLE; + phost->req_state = REQ_CMD_TX; + + phost->ctrlparam.ctrl_state = CTRL_SETUP; + phost->ctrlparam.ctrlmaxsize = USB_MAX_EP0_SIZE; + + phost->device_prop.devaddr = DEV_DEFAULT_ADDRESS; + phost->device_prop.devspeed = PRTSPD_FULL_SPEED; + + (void)usb_host_freech(pdev, phost->ctrlparam.hc_num_in); + (void)usb_host_freech(pdev, phost->ctrlparam.hc_num_out); +} + +/** + * @brief This is the main process function for the host core, it will process + * the main machine, such as connect,disconnect, emunation etc. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval None + */ +void usb_host_mainprocess(usb_core_instance *pdev, USBH_HOST *phost) +{ + __IO HOST_STATUS tmp_status; + tmp_status = HSTATUS_FAIL; + HOST_HANDLE_STATE tmp_host_state; + + if ((host_driver_ifdevconnected(pdev) == 0UL) && (phost->host_state != HOST_IDLE)) { + if (phost->host_state != HOST_DEV_DISCONNECTED) { + phost->host_state = HOST_DEV_DISCONNECTED; + } + } + + if ((host_driver_ifdevconnected(pdev) == 0UL) && (phost->host_state == HOST_IDLE) + && (host_driver_getvbusdrivestate(pdev) == 0UL)) { + phost->host_state = HOST_DEV_DISCONNECTED; + } + + tmp_host_state = phost->host_state; + if (tmp_host_state == HOST_IDLE) { + if (0U != host_driver_ifdevconnected(pdev)) { + phost->host_state = HOST_DEV_CONNECTED; + usb_mdelay(50UL); + } + } else if (tmp_host_state == HOST_DEV_CONNECTED) { +#ifdef MSC_HID_COMPOSITE + if (host_driver_getcurrentspd(pdev) == 2) { + host_driver_init(pdev); + } +#endif /* MSC_HID_COMPOSITE */ + phost->user_callbk->huser_devattached(); + phost->ctrlparam.hc_num_out = usb_host_distrch(pdev, 0x00U); + phost->ctrlparam.hc_num_in = usb_host_distrch(pdev, 0x80U); + host_driver_portrst(pdev); + phost->user_callbk->huser_devreset(); + phost->device_prop.devspeed = (uint8_t)host_driver_getcurrentspd(pdev); + phost->host_state = HOST_ENUM; + phost->user_callbk->huser_devspddetected(phost->device_prop.devspeed); + usb_host_chopen(pdev, + phost->ctrlparam.hc_num_in, + phost->device_prop.devaddr, + phost->device_prop.devspeed, + EP_TYPE_CTRL, + (uint16_t)phost->ctrlparam.ctrlmaxsize); + usb_host_chopen(pdev, + phost->ctrlparam.hc_num_out, + phost->device_prop.devaddr, + phost->device_prop.devspeed, + EP_TYPE_CTRL, + (uint16_t)phost->ctrlparam.ctrlmaxsize); + } else if (tmp_host_state == HOST_ENUM) { + if (usb_host_enumprocess(pdev, phost) == HSTATUS_OK) { + phost->user_callbk->huser_enumcompl(); + phost->host_state = HOST_USER_INPUT; + } + } else if (tmp_host_state == HOST_USER_INPUT) { + if ((phost->class_callbk->host_class_init(pdev, phost)) == HSTATUS_OK) { + phost->host_state = HOST_CLASS_REQ; + } + } else if (tmp_host_state == HOST_CLASS_REQ) { + tmp_status = phost->class_callbk->host_class_request(pdev, phost); + if (tmp_status == HSTATUS_OK) { + phost->host_state = HOST_CLASS_PROCESS; + } else { + usb_host_errorprocess(phost, tmp_status); + } + } else if (tmp_host_state == HOST_CLASS_PROCESS) { + tmp_status = phost->class_callbk->host_class_process(pdev, phost); + usb_host_errorprocess(phost, tmp_status); + } else if (tmp_host_state == HOST_CTRL_TRANSMIT) { + (void)usb_host_ctrlprocess(pdev, phost); + } else if (tmp_host_state == HOST_ERROR_STATE) { + usb_host_deinit(pdev, phost); + phost->user_callbk->huser_deinit(); + phost->class_callbk->host_class_deinit(pdev); + } else if (tmp_host_state == HOST_DEV_DISCONNECTED) { + phost->user_callbk->huser_devdisconn(); + usb_host_deinit(pdev, phost); + phost->user_callbk->huser_deinit(); + phost->class_callbk->host_class_deinit(pdev); + usb_host_dedistrallch(pdev); + phost->host_state = HOST_IDLE; + + host_driver_init(pdev); + } else { + ; + } +} + +/** + * @brief process the status when related error status happens. + * @param [in] phost host state set + * @param [in] errType host status + * @retval None + */ +void usb_host_errorprocess(USBH_HOST *phost, HOST_STATUS errType) +{ + switch (errType) { + case HSTATUS_APP_DEINIT: + phost->host_state = HOST_ERROR_STATE; + phost->user_callbk->huser_init(); + break; + case HSTATUS_SPEED_UNKNOWN: + case HSTATUS_UNRECOVERED_ERROR: + phost->user_callbk->huser_unrecoverederror(); + phost->host_state = HOST_ERROR_STATE; + break; + default: + break; + } +} + +/** + * @brief this function process all the emunation steps. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status + */ +HOST_STATUS usb_host_enumprocess(usb_core_instance *pdev, USBH_HOST *phost) +{ + HOST_STATUS tmp_status; + + ENUM_HANDLE_STATE tmp_enum_state; + tmp_status = HSTATUS_BUSY; + tmp_enum_state = phost->enum_state; + if (tmp_enum_state == ENUM_IDLE) { + if (usb_host_getdevdesc(pdev, phost, 8U) == HSTATUS_OK) { + phost->ctrlparam.ctrlmaxsize = phost->device_prop.devdesc.bMaxPacketSize0; + host_driver_portrst(pdev); + phost->enum_state = ENUM_GET_FULL_DEVDESC; + usb_host_mdfch(pdev, + phost->ctrlparam.hc_num_out, + 0U, + 0U, + 0U, + (uint16_t)phost->ctrlparam.ctrlmaxsize); + usb_host_mdfch(pdev, + phost->ctrlparam.hc_num_in, + 0U, + 0U, + 0U, + (uint16_t)phost->ctrlparam.ctrlmaxsize); + } + } + if (tmp_enum_state == ENUM_GET_FULL_DEVDESC) { + if (usb_host_getdevdesc(pdev, phost, USB_DEVICE_DESC_SIZE) == HSTATUS_OK) { + phost->user_callbk->huser_devdescavailable(&phost->device_prop.devdesc); + phost->enum_state = ENUM_SET_DEVADDR; + } + } + if (tmp_enum_state == ENUM_SET_DEVADDR) { + if (usb_host_setdevaddr(pdev, phost, DEV_ASSIGNED_ADDRESS) == HSTATUS_OK) { + usb_mdelay(2UL); + phost->device_prop.devaddr = DEV_ASSIGNED_ADDRESS; + phost->user_callbk->huser_devaddrdistributed(); + phost->enum_state = ENUM_GET_CFGDESC; + usb_host_mdfch(pdev, + phost->ctrlparam.hc_num_in, + phost->device_prop.devaddr, + 0U, + 0U, + 0U); + + usb_host_mdfch(pdev, + phost->ctrlparam.hc_num_out, + phost->device_prop.devaddr, + 0U, + 0U, + 0U); + } + } + if (tmp_enum_state == ENUM_GET_CFGDESC) { + if (usb_host_getcfgdesc(pdev, phost, USB_CONFIGURATION_DESC_SIZE) == HSTATUS_OK) { + phost->enum_state = ENUM_GET_FULL_CFGDESC; + } + } + if (tmp_enum_state == ENUM_GET_FULL_CFGDESC) { + if (usb_host_getcfgdesc(pdev, phost, phost->device_prop.devcfgdesc.wTotalLength) == HSTATUS_OK) { + phost->user_callbk->huser_cfgdescavailable(&phost->device_prop.devcfgdesc, + phost->device_prop.devitfdesc, + phost->device_prop.devepdesc[0]); + phost->enum_state = ENUM_GET_MFCSTRINGDESC; + } + } + if (tmp_enum_state == ENUM_GET_MFCSTRINGDESC) { + if (phost->device_prop.devdesc.iManufacturer != (uint8_t)0) { + if (usb_host_getstringdesc(pdev, + phost, + phost->device_prop.devdesc.iManufacturer, + Local_Buffer, + 0xffu) == HSTATUS_OK) { + phost->user_callbk->huser_mfcstring(Local_Buffer); + phost->enum_state = ENUM_GET_PRODUCT_STRINGDESC; + } + } else { + phost->user_callbk->huser_mfcstring("N/A"); + phost->enum_state = ENUM_GET_PRODUCT_STRINGDESC; + } + } + if (tmp_enum_state == ENUM_GET_PRODUCT_STRINGDESC) { + if (phost->device_prop.devdesc.iProduct != (uint8_t)0) { + if (usb_host_getstringdesc(pdev, + phost, + phost->device_prop.devdesc.iProduct, + Local_Buffer, + 0xffu) == HSTATUS_OK) { + phost->user_callbk->huser_productstring(Local_Buffer); + phost->enum_state = ENUM_GET_SERIALNUM_STRINGDESC; + } + } else { + phost->user_callbk->huser_productstring("N/A"); + phost->enum_state = ENUM_GET_SERIALNUM_STRINGDESC; + } + } + if (tmp_enum_state == ENUM_GET_SERIALNUM_STRINGDESC) { + if (phost->device_prop.devdesc.iSerialNumber != (uint8_t)0) { + if (usb_host_getstringdesc(pdev, + phost, + phost->device_prop.devdesc.iSerialNumber, + Local_Buffer, + 0xffu) == HSTATUS_OK) { + phost->user_callbk->huser_serialnum(Local_Buffer); + phost->enum_state = ENUM_SET_CFG; + } + } else { + phost->user_callbk->huser_serialnum("N/A"); + phost->enum_state = ENUM_SET_CFG; + } + } + if (tmp_enum_state == ENUM_SET_CFG) { + if (usb_host_setconfig(pdev, phost, + (uint16_t)phost->device_prop.devcfgdesc.bConfigurationValue) == HSTATUS_OK) { + phost->enum_state = ENUM_DEV_CFG_OVER; + } + } + if (tmp_enum_state == ENUM_DEV_CFG_OVER) { + tmp_status = HSTATUS_OK; + } else { + ; + } + return tmp_status; +} + + +/** + * @brief process the state machine of control transfer + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status + */ +HOST_STATUS usb_host_ctrlprocess(usb_core_instance *pdev, USBH_HOST *phost) +{ + uint8_t direction; + CTRL_HANDLE_STATE tmp_ctrl_state; + static uint16_t timeout = 0; + HOST_STATUS status = HSTATUS_OK; + HOST_CH_XFER_STATE URB_Status; + + phost->ctrlparam.ctrl_status = CTRL_START; + tmp_ctrl_state = phost->ctrlparam.ctrl_state; + + if (tmp_ctrl_state == CTRL_SETUP) { + /* transmit a setup packet to the device */ + usb_host_sendctrlsetup(pdev, phost->ctrlparam.setup.d8, phost->ctrlparam.hc_num_out); + phost->ctrlparam.ctrl_state = CTRL_SETUP_WAIT; + timeout = DATA_STAGE_TIMEOUT * 6U; + phost->ctrlparam.sof_num = (uint16_t)host_driver_getcurrentfrm(pdev); + } else if (tmp_ctrl_state == CTRL_SETUP_WAIT) { + URB_Status = host_driver_getxferstate(pdev, phost->ctrlparam.hc_num_out); + /* case SETUP packet sent successfully */ + if (URB_Status == HOST_CH_XFER_DONE) { + /* parse the direction of the request from the setup just sent */ + direction = (phost->ctrlparam.setup.b.bmRequestType & USB_REQ_DIR_MASK); + /* judge if there is a data stage, if wLength is not zero, there may be a in or out + data stage */ + if (phost->ctrlparam.setup.b.wLength.w != 0U) { + timeout = DATA_STAGE_TIMEOUT; + if (direction == USB_D2H) { + /* Data Direction is IN, device should send data in */ + phost->ctrlparam.ctrl_state = CTRL_DATA_IN; + } else { + /* Data Direction is OUT, host will send data out for device */ + phost->ctrlparam.ctrl_state = CTRL_DATA_OUT; + } + } + /* No DATA stage */ + else { + timeout = NODATA_STAGE_TIMEOUT; + /* If there is No Data Transfer Stage */ + if (direction == USB_D2H) { + /* Data Direction is IN */ + phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT; + } else { + /* Data Direction is OUT */ + phost->ctrlparam.ctrl_state = CTRL_STATUS_IN; + } + } + /* Set the delay timer to enable timeout for data stage completion */ + phost->ctrlparam.sof_num = (uint16_t)host_driver_getcurrentfrm(pdev); + } else if (URB_Status == HOST_CH_XFER_ERROR) { + phost->ctrlparam.ctrl_state = CTRL_ERROR; + phost->ctrlparam.ctrl_status = CTRL_XACTERR; + } else if ((host_driver_getcurrentfrm(pdev) - phost->ctrlparam.sof_num) > timeout) { +#if (LL_PRINT_ENABLE == DDL_ON) + DDL_Printf("Device not responding\r\n"); +#endif + } else { + ; + } + } else if (tmp_ctrl_state == CTRL_DATA_IN) { + /* Issue an IN token */ + usb_host_recvctrldata(pdev, phost->ctrlparam.buff, phost->ctrlparam.length, phost->ctrlparam.hc_num_in); + phost->ctrlparam.ctrl_state = CTRL_DATA_IN_WAIT; + } else if (tmp_ctrl_state == CTRL_DATA_IN_WAIT) { + URB_Status = host_driver_getxferstate(pdev, phost->ctrlparam.hc_num_in); + /* check is DATA packet transfered successfully */ + if (URB_Status == HOST_CH_XFER_DONE) { + phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT; + } + /* manage error cases*/ + if (URB_Status == HOST_CH_XFER_STALL) { + /* In stall case, return to previous machine state*/ + phost->host_state = phost->host_state_backup; + } else if (URB_Status == HOST_CH_XFER_ERROR) { + /* Device error */ + phost->ctrlparam.ctrl_state = CTRL_ERROR; + } else if ((host_driver_getcurrentfrm(pdev) - phost->ctrlparam.sof_num) > timeout) { + /* timeout for IN transfer */ + phost->ctrlparam.ctrl_state = CTRL_ERROR; + } else { + ; + } + } else if (tmp_ctrl_state == CTRL_DATA_OUT) { + /* Start DATA out transfer (only one DATA packet)*/ + pdev->host.hc[phost->ctrlparam.hc_num_out].out_toggle = 1; + + usb_host_sendctrldata(pdev, + phost->ctrlparam.buff, + phost->ctrlparam.length, + phost->ctrlparam.hc_num_out); + phost->ctrlparam.ctrl_state = CTRL_DATA_OUT_WAIT; + } else if (tmp_ctrl_state == CTRL_DATA_OUT_WAIT) { + URB_Status = host_driver_getxferstate(pdev, phost->ctrlparam.hc_num_out); + switch (URB_Status) { + case HOST_CH_XFER_DONE: + phost->ctrlparam.ctrl_state = CTRL_STATUS_IN; + break; + case HOST_CH_XFER_STALL: + phost->host_state = phost->host_state_backup; + phost->ctrlparam.ctrl_state = CTRL_STALLED; + break; + case HOST_CH_XFER_UNREADY: + phost->ctrlparam.ctrl_state = CTRL_DATA_OUT; + break; + case HOST_CH_XFER_ERROR: + phost->ctrlparam.ctrl_state = CTRL_ERROR; + break; + default: + break; + } + } else if (tmp_ctrl_state == CTRL_STATUS_IN) { + /* receive a packet with 0 byte */ + usb_host_recvctrldata(pdev, NULL, 0U, phost->ctrlparam.hc_num_in); + phost->ctrlparam.ctrl_state = CTRL_STATUS_IN_WAIT; + } else if (tmp_ctrl_state == CTRL_STATUS_IN_WAIT) { + URB_Status = host_driver_getxferstate(pdev, phost->ctrlparam.hc_num_in); + if (URB_Status == HOST_CH_XFER_DONE) { + /* Control transfers completed, Exit the State Machine */ + phost->host_state = phost->host_state_backup; + phost->ctrlparam.ctrl_state = CTRL_COMPLETE; + } else if (URB_Status == HOST_CH_XFER_ERROR) { + phost->ctrlparam.ctrl_state = CTRL_ERROR; + } else if ((host_driver_getcurrentfrm(pdev) - phost->ctrlparam.sof_num) > timeout) { + phost->ctrlparam.ctrl_state = CTRL_ERROR; + } else if (URB_Status == HOST_CH_XFER_STALL) { + /* Control transfers completed, Exit the State Machine */ + phost->host_state = phost->host_state_backup; + phost->ctrlparam.ctrl_status = CTRL_STALL; + status = HSTATUS_UNSUPPORTED; + } else { + ; + } + } else if (tmp_ctrl_state == CTRL_STATUS_OUT) { + pdev->host.hc[phost->ctrlparam.hc_num_out].out_toggle ^= 1U; + usb_host_sendctrldata(pdev, NULL, 0U, phost->ctrlparam.hc_num_out); + phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT_WAIT; + } else if (tmp_ctrl_state == CTRL_STATUS_OUT_WAIT) { + URB_Status = host_driver_getxferstate(pdev, phost->ctrlparam.hc_num_out); + switch (URB_Status) { + case HOST_CH_XFER_DONE: + phost->host_state = phost->host_state_backup; + phost->ctrlparam.ctrl_state = CTRL_COMPLETE; + break; + case HOST_CH_XFER_UNREADY: + phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT; + break; + case HOST_CH_XFER_ERROR: + phost->ctrlparam.ctrl_state = CTRL_ERROR; + break; + default: + break; + } + } else if (tmp_ctrl_state == CTRL_ERROR) { + if (++ phost->ctrlparam.err_cnt <= HOST_MAX_ERROR_CNT) { + /* re-start the transmission, starting from SETUP packet */ + phost->ctrlparam.ctrl_state = CTRL_SETUP; + } else { + phost->ctrlparam.ctrl_status = CTRL_FAIL; + phost->host_state = phost->host_state_backup; + + status = HSTATUS_FAIL; + } + } else { + ; + } + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.h new file mode 100644 index 000000000..66c045fbe --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.h @@ -0,0 +1,95 @@ +/** + ******************************************************************************* + * @file usb_host_core.h + * @brief header file for the usb_host_core.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_HOST_CORE_H__ +#define __USB_HOST_CORE_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +/* USBH_CORE_Exported_Defines */ +#define MSC_CLASS (0x08U) +#define HID_CLASS (0x03U) +#define MSC_PROTOCOL (0x50U) +#define CBI_PROTOCOL (0x01U) + +#define DEV_DEFAULT_ADDRESS (0U) +#define DEV_ASSIGNED_ADDRESS (1U) + +#define HOST_MAX_ERROR_CNT (2U) + +#define ENUM_LOCAL_BUF (256U) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void usb_host_init(usb_core_instance *pdev, + USBH_HOST *phost, + usb_host_class_callback_func *class_cbk, + usb_host_user_callback_func *user_cbk); +extern void usb_host_deinit(usb_core_instance *pdev, USBH_HOST *phost); +extern void usb_host_mainprocess(usb_core_instance *pdev, USBH_HOST *phost); +extern void usb_host_errorprocess(USBH_HOST *phost, HOST_STATUS errType); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_CORE_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.c new file mode 100644 index 000000000..db3379775 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.c @@ -0,0 +1,320 @@ +/** + ******************************************************************************* + * @file usb_host_ctrltrans.c + * @brief This file handles the issuing of the USB transactions + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_ctrltrans.h" +#include "usb_host_driver.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +void usb_host_submitsetupreq(USBH_HOST *phost, uint8_t *buff, uint16_t length); + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @brief Start a setup transfer by changing the state-machine and + * initializing the required variables needed for the Control Transfer + * @param [in] phost host state set + * @param [in] buff data buffer used for setup request + * @param [in] length data length in byte + * @retval status + */ +void usb_host_submitsetupreq(USBH_HOST *phost, uint8_t *buff, uint16_t length) +{ + /* Save Global State */ + phost->host_state_backup = phost->host_state; + /* Prepare the Transactions */ + phost->host_state = HOST_CTRL_TRANSMIT; + phost->ctrlparam.buff = buff; + phost->ctrlparam.length = length; + phost->ctrlparam.ctrl_state = CTRL_SETUP; +} + +/** + * @brief send a control request and update the status after the request sent. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] buff data buffer whose data will be sent in the control pipe. + * @param [in] length length of the data sent. + * @retval status + */ +HOST_STATUS usb_host_ctrlreq(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t *buff, + uint16_t length) +{ + HOST_STATUS status; + REQ_HANDLE_STATE tmp_req_state; + (void)(pdev); + status = HSTATUS_BUSY; + tmp_req_state = phost->req_state; + if (tmp_req_state == REQ_CMD_TX) { + /* prepare a setup packet for transferring */ + usb_host_submitsetupreq(phost, buff, length); + /* update the request state */ + phost->req_state = REQ_CMD_WAIT; + /* The status would be returned in this function */ + status = HSTATUS_BUSY; + } else if (tmp_req_state == REQ_CMD_WAIT) { + switch (phost->ctrlparam.ctrl_state) { + case CTRL_COMPLETE: + /* Commands have been successfully sent and Responses have been Received */ + phost->req_state = REQ_CMD_TX; + /* update the control state */ + phost->ctrlparam.ctrl_state = CTRL_IDLE; + status = HSTATUS_OK; + break; + case CTRL_ERROR: + /* fail transfer */ + phost->req_state = REQ_CMD_TX; + status = HSTATUS_FAIL; + break; + case CTRL_STALLED: + /* Commands have been successfully sent and Responses have been Received */ + phost->req_state = REQ_CMD_TX; + status = HSTATUS_UNSUPPORTED; + break; + default: + break; + } + } else { + ; + } + return status; +} + +/** + * @brief sends a setup packet to the control EP of the USB device + * @param [in] pdev device instance + * @param [in] buff data buffer whose data will be sent in the control pipe to the control EP of the device. + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_sendctrlsetup(usb_core_instance *pdev, uint8_t *buff, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = 0U; + pdev->host.hc[hc_num].pid_type = PID_SETUP; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = 8; + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief sends a data packet to the USB device + * @param [in] pdev device instance + * @param [in] buff data buffer whose data will be sent to the USB device + * @param [in] length the data length in byte that would be sent + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_sendctrldata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = 0; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + if (length == 0U) { + /* For Status OUT stage, Length==0, Status Out PID = 1 always */ + pdev->host.hc[hc_num].out_toggle = 1; + } + /* Set the Data Toggle bit */ + if (pdev->host.hc[hc_num].out_toggle == 0U) { + pdev->host.hc[hc_num].pid_type = PID_DATA0; + } else { + pdev->host.hc[hc_num].pid_type = PID_DATA1 ; + } + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief Receives the response data to the setup packet + * @param [in] pdev device instance + * @param [in] buff data buffer when received data. + * @param [in] length the length data in byte have received. + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_recvctrldata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)1; + pdev->host.hc[hc_num].pid_type = PID_DATA1; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief sent the bulk packet to the device + * @param [in] pdev device instance + * @param [in] buff data buffer whose data will be sent + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_sendbulkdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = 0; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + /* Set the Data Toggle bit */ + if (pdev->host.hc[hc_num].out_toggle == 0U) { + pdev->host.hc[hc_num].pid_type = PID_DATA0; + } else { + pdev->host.hc[hc_num].pid_type = PID_DATA1 ; + } + + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief receives bulk packet from device + * @param [in] pdev device instance + * @param [in] buff buffer to save the data received from the device + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval status + */ +void usb_host_recvbulkdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)1; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + + if (pdev->host.hc[hc_num].in_toggle == (uint8_t)0) { + pdev->host.hc[hc_num].pid_type = PID_DATA0; + } else { + pdev->host.hc[hc_num].pid_type = PID_DATA1; + } + + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief receives the device response to the Interrupt IN token + * @param [in] pdev device instance + * @param [in] buff buffer to save the data received from the device + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_recvintdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)1; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + if (pdev->host.hc[hc_num].in_toggle == (uint8_t)0) { + pdev->host.hc[hc_num].pid_type = PID_DATA0; + } else { + pdev->host.hc[hc_num].pid_type = PID_DATA1; + } + /* toggle the DATA PID */ + pdev->host.hc[hc_num].in_toggle ^= (uint8_t)1; + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief send the data on Interrupt OUT Endpoint + * @param [in] pdev device instance + * @param [in] buff data buffer whose data will be sent + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_sentintdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)0; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + if (pdev->host.hc[hc_num].in_toggle == (uint8_t)0) { + pdev->host.hc[hc_num].pid_type = PID_DATA0; + } else { + pdev->host.hc[hc_num].pid_type = PID_DATA1; + } + + pdev->host.hc[hc_num].in_toggle ^= (uint8_t)1; + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief receives the Device Response to the Isochronous IN token + * @param [in] pdev device instance + * @param [in] buff buffer to save the data received from the device + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_recvisocdata(usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)1; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + pdev->host.hc[hc_num].pid_type = PID_DATA0; + + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief Sends the data through Isochronous OUT Endpoint + * @param [in] pdev device instance + * @param [in] buff data buffer whose data will be sent + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_sendisocdata(usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)0; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + pdev->host.hc[hc_num].pid_type = PID_DATA0; + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @} + */ + +/** + * @} + */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.h new file mode 100644 index 000000000..98e461caf --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.h @@ -0,0 +1,86 @@ +/** + ******************************************************************************* + * @file usb_host_ctrltrans.h + * @brief header file for the usb_host_ctrltrans.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_HOST_CTRLTRANS_H__ +#define __USB_HOST_CTRLTRANS_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void usb_host_sendctrlsetup(usb_core_instance *pdev, uint8_t *buff, uint8_t hc_num); +extern void usb_host_sendctrldata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern void usb_host_recvctrldata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern void usb_host_recvbulkdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern void usb_host_sendbulkdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern void usb_host_recvintdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern void usb_host_sentintdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern HOST_STATUS usb_host_ctrlreq(usb_core_instance *pdev, USBH_HOST *phost, uint8_t *buff, uint16_t length); +extern void usb_host_recvisocdata(usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num); +extern void usb_host_sendisocdata(usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_CTRLTRANS_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_def.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_def.h new file mode 100644 index 000000000..df7549071 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_def.h @@ -0,0 +1,430 @@ +/** + ******************************************************************************* + * @file usb_host_def.h + * @brief Definitions used in the USB host library + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_HOST_DEF_H__ +#define __USB_HOST_DEF_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include +#include "usb_app_conf.h" +#include "usb_lib.h" +#include "hc32_ll.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ +/* This Union is copied from usb_core.h */ +typedef union { + uint16_t w; + struct BW { + uint8_t msb; + uint8_t lsb; + } + bw; +} uint16_t_uint8_t; +/* standard setup packet defination */ +typedef union { + uint8_t d8[8]; + struct _SetupPkt_Struc { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t_uint8_t wValue; + uint16_t_uint8_t wIndex; + uint16_t_uint8_t wLength; + } b; +} usb_setup_typedef; + +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} USB_HOST_DescHeader_TypeDef; + +/* Standard Device Descriptor */ +typedef struct { + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* Device descriptor type */ + uint16_t bcdUSB; /* USB Specification Release Numbrer in Binary-Coded Decimal(i.e.,2.10 is 210H) */ + uint8_t bDeviceClass; /* Class code(assigned by the USB-IF) */ + uint8_t bDeviceSubClass; /* Subclass code(assigned by the USB-IF) this code is qualified by the value of the \ + bDeviceClass field. */ + uint8_t bDeviceProtocol; /* Protocol code(assigned by the USB-IF), this code is qualified by the value of the \ + bDeviceClass and the bDeviceSubClass fields. */ + uint8_t bMaxPacketSize0; /* Maximum packet size for EP0 */ + uint16_t idVendor; /* Vendor ID (assigned by the USB-IF) */ + uint16_t idProduct; /* Product ID (assigned by manufacturer) */ + uint16_t bcdDevice; /* Device Release Number in binary-coded decimal */ + uint8_t iManufacturer; /* Index of string descriptor describing manufacturer */ + uint8_t iProduct; /* Index of string descriptor describing product */ + uint8_t iSerialNumber; /* Index of string descriptor describing the device's serial number */ + uint8_t bNumConfigurations; /* Number of possible configurations */ +} usb_host_devdesc_typedef; + +/* Standard Configuration Descriptor */ +typedef struct { + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* CONFIGURATION descriptor type */ + uint16_t wTotalLength; /* Total length of data returned for this configuration */ + uint8_t bNumInterfaces; /* Number of interfaces supported by this configuration */ + uint8_t bConfigurationValue; /* Value to use as an argument to the SetConfiguration() request to select this configuration */ + uint8_t iConfiguration; /* Index of string descriptor describing this configuration */ + uint8_t bmAttributes; /* Configuration characteristics: D7:Reserved(set to one) D6:Self-powered D5:Remote Wakeup D4..0 Reserved(set to zero) */ + uint8_t bMaxPower; /* Maximum power consumption of the device from the bus in this specific configuration when the device is fully operational */ +} usb_host_cfgdesc_typedef; + +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdHID; /* indicates what endpoint this descriptor is describing */ + uint8_t bCountryCode; /* specifies the transfer type. */ + uint8_t bNumDescriptors; /* specifies the transfer type. */ + uint8_t bReportDescriptorType; /* Maximum Packet Size this endpoint is capable of sending or receiving */ + uint16_t wItemLength; /* is used to specify the polling interval of certain transfers. */ +} USB_HOST_HIDDesc_TypeDef; + +/* Standard Interface Descriptor */ +typedef struct { + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* INTERFACE Descriptor Type */ + uint8_t bInterfaceNumber; /* Number of this interface */ + uint8_t bAlternateSetting; /* Value used to select this alternate setting for the interface identifiled in the \ + prior field */ + uint8_t bNumEndpoints; /* Number of Endpoints used by this interface */ + uint8_t bInterfaceClass; /* Class code (assigned by the USB-IF) */ + uint8_t bInterfaceSubClass; /* Subclass code (assigned by the USB-IF) */ + uint8_t bInterfaceProtocol; /* Protocol code (assigned by the USB) */ + uint8_t iInterface; /* Index of string descriptor describing this interface */ +} usb_host_itfdesc_typedef; + +/* Standard Endpoint Descriptor */ +typedef struct { + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* ENDPOINT descriptor type */ + uint8_t bEndpointAddress; /* The address of the endpoint on the device described by this descriptor */ + uint8_t bmAttributes; /* refer to the related standard of USB 2.0 */ + uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving when this \ + configuration is selected */ + uint8_t bInterval; /* Interval for servicing the endpoint for data transfers */ +} USB_HOST_EPDesc_TypeDef; + +/* USBH_CORE_Exported_Types */ +/* Host status */ +typedef enum { + HSTATUS_OK = 0, + HSTATUS_BUSY, + HSTATUS_FAIL, + HSTATUS_UNSUPPORTED, + HSTATUS_UNRECOVERED_ERROR, + HSTATUS_SPEED_UNKNOWN, + HSTATUS_APP_DEINIT +} HOST_STATUS; + +/* states about the handle stages on the host side */ +typedef enum { + HOST_IDLE = 0, + HOST_DEV_CONNECTED, + HOST_DEV_DISCONNECTED, + HOST_GET_DEVSPEED, + HOST_ENUM, + HOST_CLASS_REQ, + HOST_CLASS_PROCESS, + HOST_CTRL_TRANSMIT, + HOST_USER_INPUT, + HOST_SUSPENDED, + HOST_ERROR_STATE +} HOST_HANDLE_STATE; + + +/* states of the enumeration stage on the host side */ +typedef enum { + ENUM_IDLE = 0, + ENUM_GET_FULL_DEVDESC, + ENUM_SET_DEVADDR, + ENUM_GET_CFGDESC, + ENUM_GET_FULL_CFGDESC, + ENUM_GET_MFCSTRINGDESC, + ENUM_GET_PRODUCT_STRINGDESC, + ENUM_GET_SERIALNUM_STRINGDESC, + ENUM_SET_CFG, + ENUM_DEV_CFG_OVER +} ENUM_HANDLE_STATE; + +/* states of the control stages on the host side */ +typedef enum { + CTRL_IDLE = 0, + CTRL_SETUP, + CTRL_SETUP_WAIT, + CTRL_DATA_IN, + CTRL_DATA_IN_WAIT, + CTRL_DATA_OUT, + CTRL_DATA_OUT_WAIT, + CTRL_STATUS_IN, + CTRL_STATUS_IN_WAIT, + CTRL_STATUS_OUT, + CTRL_STATUS_OUT_WAIT, + CTRL_ERROR, + CTRL_STALLED, + CTRL_COMPLETE +} CTRL_HANDLE_STATE; + +/* Following states are state machine for the request transferring */ +typedef enum { + REQ_CMD_IDLE = 0, + REQ_CMD_TX, + REQ_CMD_WAIT +} REQ_HANDLE_STATE; + +typedef enum { + USER_HAVE_RESP = 0, + USER_NONE_RESP +} HOST_USER_STATUS; + +typedef struct { + uint8_t hc_num_in; /* channel number for the IN EP */ + uint8_t hc_num_out; /* channel number for the OUT EP */ + uint8_t ctrlmaxsize; /* the max size of EP0 parsed from the device descriptor */ + uint8_t err_cnt; /* the error counter */ + uint16_t sof_num; /* the frame number for sof packet */ + uint16_t length; /* length of data in byte */ + uint8_t *buff; /* data buffer */ + CTRL_HANDLE_STATUS ctrl_status; /* status of control pipe */ + CTRL_HANDLE_STATE ctrl_state; /* running state of the control transfer */ + usb_setup_typedef setup; /* setup packet */ +} usb_host_ctrl_param; + +/* Device information parsed from the related descriptors requested from the connected device + the following data are all parsed from the data sent by the connnected device */ +typedef struct { + uint8_t devaddr; /* the address of the connected device */ + uint8_t devspeed; /* the core speed of the connected device */ + usb_host_devdesc_typedef devdesc; /* the device descriptor parsed from the data sent by device */ + usb_host_cfgdesc_typedef devcfgdesc; /* the device configuration descriptor parsed from the data sent by device */ + usb_host_itfdesc_typedef devitfdesc[USBH_MAX_NUM_INTERFACES]; /* the interface descritpor */ + USB_HOST_EPDesc_TypeDef devepdesc[USBH_MAX_NUM_INTERFACES][USBH_MAX_NUM_ENDPOINTS]; /* the endpoint descriptor */ + USB_HOST_HIDDesc_TypeDef hiddesc; /* the hid descriptor */ +} usb_host_devinformation; + +typedef struct { + HOST_STATUS(*host_class_init)(usb_core_instance *pdev, void *phost); + void (*host_class_deinit)(usb_core_instance *pdev); + HOST_STATUS(*host_class_request)(usb_core_instance *pdev, void *phost); + HOST_STATUS(*host_class_process)(usb_core_instance *pdev, void *phost); +} usb_host_class_callback_func; + +typedef struct { + void (*huser_init)(void); + void (*huser_deinit)(void); + void (*huser_devattached)(void); + void (*huser_devreset)(void); + void (*huser_devdisconn)(void); + void (*huser_overcurrent)(void); + void (*huser_devspddetected)(uint8_t DeviceSpeed); + void (*huser_devdescavailable)(void *); + void (*huser_devaddrdistributed)(void); + void (*huser_cfgdescavailable)(usb_host_cfgdesc_typedef *, + usb_host_itfdesc_typedef *, + USB_HOST_EPDesc_TypeDef *); + /* Configuration Descriptor available */ + void (*huser_mfcstring)(void *); + void (*huser_productstring)(void *); + void (*huser_serialnum)(void *); + void (*huser_enumcompl)(void); + HOST_USER_STATUS(*huser_userinput)(void); + int (*huser_application)(void); + void (*huser_devunsupported)(void); + void (*huser_unrecoverederror)(void); +} usb_host_user_callback_func; + +typedef struct { + /* states for the host, enumeration, request */ + REQ_HANDLE_STATE req_state; /* value of state machine about the request */ + ENUM_HANDLE_STATE enum_state; /* state machine while enumerating */ + HOST_HANDLE_STATE host_state_backup; /* backup value of state machine about the host */ + HOST_HANDLE_STATE host_state; /* value of state machine about the host */ + /* control informations */ + usb_host_ctrl_param ctrlparam; /* values about the control parameters */ + /* device information parsed from the descriptors from the device */ + usb_host_devinformation device_prop; + /* functions: call back functions for the class and user */ + usb_host_class_callback_func *class_callbk; + usb_host_user_callback_func *user_callbk; +} USBH_HOST; + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + +#ifndef FALSE +#define FALSE 0U +#endif + +#ifndef TRUE +#define TRUE 1U +#endif + +/* Get a 16bits data from buffer in little end mode. */ +#define SMALL_END(addr) (((uint16_t)(*((uint8_t *)(addr)))) + (((uint16_t)(*(((uint8_t *)(addr)) + 1U))) << 8U)) + +#define USB_LEN_CFG_DESC (0x09U) + +/* bmRequestType +D7: Data transfer direction + 0 = Host-to-device + 1 = Device-to-host +*/ +#define USB_REQ_DIR_MASK (0x80U) +#define USB_H2D (0x00U) +#define USB_D2H (0x80U) + +/* bmRequestType +D6...5: Type + 0 = Standard + 1 = Class + 2 = Vendor + 3 = Reserved +*/ +#define USB_REQ_TYPE_STANDARD (0x00U) +#define USB_REQ_TYPE_CLASS (0x20U) +#define USB_REQ_TYPE_VENDOR (0x40U) +#define USB_REQ_TYPE_RESERVED (0x60U) + +/* bmRequestType +D4...0: Recipient + 0 = Device + 1 = Interface + 2 = Endpoint + 3 = Other + 4...31 = Reserved +*/ +#define USB_REQ_RECIPIENT_DEVICE (0x00U) +#define USB_REQ_RECIPIENT_INTERFACE (0x01U) +#define USB_REQ_RECIPIENT_ENDPOINT (0x02U) +#define USB_REQ_RECIPIENT_OTHER (0x03U) + +/* Table 9-4. Standard Request Codes [USB Specification] */ +/* bRequest Value */ +#define USB_REQ_GET_STATUS (0x00U) +#define USB_REQ_CLEAR_FEATURE (0x01U) +#define USB_REQ_SET_FEATURE (0x03U) +#define USB_REQ_SET_ADDRESS (0x05U) +#define USB_REQ_GET_DESCRIPTOR (0x06U) +#define USB_REQ_SET_DESCRIPTOR (0x07U) +#define USB_REQ_GET_CONFIGURATION (0x08U) +#define USB_REQ_SET_CONFIGURATION (0x09U) +#define USB_REQ_GET_INTERFACE (0x0AU) +#define USB_REQ_SET_INTERFACE (0x0BU) +#define USB_REQ_SYNCH_FRAME (0x0Cu) + +/* Table 9-5. Descriptor Types [USB Specification] */ +/* Descriptor Types Value */ +#define USB_DESC_TYPE_DEVICE (1U) +#define USB_DESC_TYPE_CONFIGURATION (2U) +#define USB_DESC_TYPE_STRING (3U) +#define USB_DESC_TYPE_INTERFACE (4U) +#define USB_DESC_TYPE_ENDPOINT (5U) +#define USB_DESC_TYPE_DEVICE_QUALIFIER (6U) +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION (7U) +#define USB_DESC_TYPE_INTERFACE_POWER (8U) +#define USB_DESC_TYPE_HID (0x21U) +#define USB_DESC_TYPE_HID_REPORT (0x22U) + +#define USB_DEVICE_DESC_SIZE (18U) +#define USB_CONFIGURATION_DESC_SIZE (9U) +#define USB_HID_DESC_SIZE (9U) +#define USB_INTERFACE_DESC_SIZE (9U) +#define USB_ENDPOINT_DESC_SIZE (7U) + +/* Descriptor Type and Descriptor Index */ +/* Use the following values when calling the function usb_host_getdesc */ +#define USB_DESC_DEVICE (((uint16_t)USB_DESC_TYPE_DEVICE << 8U) & 0xFF00U) +#define USB_DESC_CONFIGURATION (((uint16_t)USB_DESC_TYPE_CONFIGURATION << 8U) & 0xFF00U) +#define USB_DESC_STRING (((uint16_t)USB_DESC_TYPE_STRING << 8U) & 0xFF00U) +#define USB_DESC_INTERFACE (((uint16_t)USB_DESC_TYPE_INTERFACE << 8U) & 0xFF00U) +#define USB_DESC_ENDPOINT (((uint16_t)USB_DESC_TYPE_INTERFACE << 8U) & 0xFF00U) +#define USB_DESC_DEVICE_QUALIFIER (((uint16_t)USB_DESC_TYPE_DEVICE_QUALIFIER << 8U) & 0xFF00U) +#define USB_DESC_OTHER_SPEED_CONFIGURATION (((uint16_t)USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8U) & 0xFF00U) +#define USB_DESC_INTERFACE_POWER (((uint16_t)USB_DESC_TYPE_INTERFACE_POWER << 8U) & 0xFF00U) +#define USB_DESC_HID_REPORT (((uint16_t)USB_DESC_TYPE_HID_REPORT << 8U) & 0xFF00U) +#define USB_DESC_HID (((uint16_t)USB_DESC_TYPE_HID << 8U) & 0xFF00U) + +#define USB_EP_DIR_OUT (0x00U) +#define USB_EP_DIR_IN (0x80U) +#define USB_EP_DIR_MSK (0x80U) + +/* supported classes */ +#define USB_MSC_CLASS (0x08U) +#define USB_HID_CLASS (0x03U) + +/* Interface Descriptor field values for HID Boot Protocol */ +#define HID_BOOT_CODE (0x01U) +#define HID_KEYBRD_BOOT_CODE (0x01U) +#define HID_MOUSE_BOOT_CODE (0x02U) + +/* As per USB specs 9.2.6.4 :Standard request with data request timeout: 5sec + Standard request with no data stage timeout : 50ms */ +#define DATA_STAGE_TIMEOUT (5000U) +#define NODATA_STAGE_TIMEOUT (50U) + +/* Macro definations for host mode */ +#define PID_DATA0 (0U) +#define PID_DATA2 (1U) +#define PID_DATA1 (2U) +#define PID_SETUP (3U) +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_DEF_H__ */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.c new file mode 100644 index 000000000..606709899 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.c @@ -0,0 +1,231 @@ +/** + ******************************************************************************* + * @file usb_host_driver.c + * @brief Host Interface Layer. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_driver.h" +#include "usb_bsp.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @brief Initialize the driver for the host mode + * @param [in] pdev device instance + * @retval None + */ +void host_driver_init(usb_core_instance *pdev) +{ + uint8_t i; + + pdev->host.is_dev_connect = 0U; + for (i = 0U; i < USB_MAX_TX_FIFOS; i++) { + pdev->host.ErrCnt[i] = 0U; + pdev->host.XferCnt[i] = 0U; + pdev->host.HC_Status[i] = HOST_CH_IDLE; + } + pdev->host.hc[0].max_packet = 8U; + + usb_setregaddr(&pdev->regs, &pdev->basic_cfgs);; + + usb_gintdis(&pdev->regs); + usb_initusbcore(&pdev->regs, &pdev->basic_cfgs); + /* force to work in host mode*/ + usb_modeset(&pdev->regs, HOST_MODE); + /* configure charge pump IO */ + usb_bsp_cfgvbus(&pdev->regs); + usb_vbusctrl(&pdev->regs, 1U); + usb_mdelay(50UL); + + usb_hostmodeinit(&pdev->regs, &pdev->basic_cfgs); + usb_ginten(&pdev->regs); +} + +/** + * @brief get current speed when in host mode + * @param [in] pdev device instance + * @retval current speed + */ +uint32_t host_driver_getcurrentspd(usb_core_instance *pdev) +{ + uint32_t u32hppt; + u32hppt = READ_REG32(*pdev->regs.HPRT); + return ((u32hppt & USBFS_HPRT_PSPD) >> USBFS_HPRT_PSPD_POS); +} + +/** + * @brief get current DM DP state + * @param [in] pdev device instance + * @retval DM DP state + * 0x00 DM L, DP L + * 0x01 DM L, DP H + * 0x02 DM H, DP L + * 0x03 DM H, DP H + */ +uint32_t host_driver_getdmdpstate(usb_core_instance *pdev) +{ + uint32_t u32hppt; + u32hppt = READ_REG32(*pdev->regs.HPRT); + return ((u32hppt & USBFS_HPRT_PLSTS) >> USBFS_HPRT_PLSTS_POS); +} + +/** + * @brief get vbus drive state + * @param [in] pdev device instance + * @retval vbus driver state + * 0x00 vbus driver disable + * 0x01 vbus driver enable + */ +uint32_t host_driver_getvbusdrivestate(usb_core_instance *pdev) +{ + uint32_t u32hppt; + u32hppt = READ_REG32(*pdev->regs.HPRT); + return ((u32hppt & USBFS_HPRT_PWPR) >> USBFS_HPRT_PWPR_POS); +} + +/** + * @brief reset the port + * @param [in] pdev device instance + * @retval None + */ +void host_driver_portrst(usb_core_instance *pdev) +{ + usb_hprtrst(&pdev->regs); +} + +/** + * @brief get the connected status of the device + * @param [in] pdev device instance + * @retval 1 connected or 0 disconnected + */ +uint32_t host_driver_ifdevconnected(usb_core_instance *pdev) +{ + return (pdev->host.is_dev_connect); +} + +/** + * @brief gets the frame number for of sof packet + * @param [in] pdev device instance + * @retval number of frame + */ +uint32_t host_driver_getcurrentfrm(usb_core_instance *pdev) +{ + return (READ_REG32(pdev->regs.HREGS->HFNUM) & 0xFFFFUL) ; +} + +/** + * @brief gets the last xfer state + * @param [in] pdev device instance + * @param [in] ch_num channel number + * @retval HOST_CH_XFER_STATE + */ +HOST_CH_XFER_STATE host_driver_getxferstate(usb_core_instance *pdev, uint8_t ch_num) +{ + return pdev->host.URB_State[ch_num] ; +} + +/** + * @brief gets the xfer count + * @param [in] pdev device instance + * @param [in] ch_num channel number + * @retval number of data trandmitted in bytes + */ +uint32_t host_driver_getxfercnt(usb_core_instance *pdev, uint8_t ch_num) +{ + return pdev->host.XferCnt[ch_num] ; +} + +/** + * @brief gets the host channel status + * @param [in] pdev device instance + * @param [in] ch_num channel number + * @retval HOST_CH_STATUS + */ +HOST_CH_STATUS host_driver_gethostchstate(usb_core_instance *pdev, uint8_t ch_num) +{ + return pdev->host.HC_Status[ch_num] ; +} + +/** + * @brief prepare a host channel and start a transfer + * @param [in] pdev device instance + * @param [in] hc_num channel number + * @retval status + */ +uint32_t host_driver_hostch_init(usb_core_instance *pdev, uint8_t hc_num) +{ + return usb_inithch(&pdev->regs, hc_num, &pdev->host.hc[hc_num], pdev->basic_cfgs.dmaen); +} + +/** + * @brief prepare a host channel and start a transfer + * @param [in] pdev device instance + * @param [in] hc_num channel number + * @retval status + */ +uint32_t host_driver_submitrequest(usb_core_instance *pdev, uint8_t hc_num) +{ + pdev->host.URB_State[hc_num] = HOST_CH_XFER_IDLE; + pdev->host.hc[hc_num].xfer_count = 0U ; + return usb_hchtransbegin(&pdev->regs, hc_num, &pdev->host.hc[hc_num], pdev->basic_cfgs.dmaen); +} + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.h new file mode 100644 index 000000000..b7a902d21 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.h @@ -0,0 +1,90 @@ +/** + ******************************************************************************* + * @file usb_host_driver.h + * @brief Head file for usb_host_driver.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_HOST_DRIVER_H__ +#define __USB_HOST_DRIVER_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void host_driver_init(usb_core_instance *pdev); +extern uint32_t host_driver_hostch_init(usb_core_instance *pdev, uint8_t hc_num); +extern uint32_t host_driver_submitrequest(usb_core_instance *pdev, uint8_t hc_num); +extern uint32_t host_driver_getcurrentspd(usb_core_instance *pdev); +extern uint32_t host_driver_getdmdpstate(usb_core_instance *pdev); +extern uint32_t host_driver_getvbusdrivestate(usb_core_instance *pdev); +extern void host_driver_portrst(usb_core_instance *pdev); +extern uint32_t host_driver_ifdevconnected(usb_core_instance *pdev); +extern uint32_t host_driver_getcurrentfrm(usb_core_instance *pdev); +extern HOST_CH_XFER_STATE host_driver_getxferstate(usb_core_instance *pdev, uint8_t ch_num); +extern uint32_t host_driver_getxfercnt(usb_core_instance *pdev, uint8_t ch_num); +extern HOST_CH_STATUS host_driver_gethostchstate(usb_core_instance *pdev, uint8_t ch_num); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_DRIVER_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ + + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.c new file mode 100644 index 000000000..cb8fe2899 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.c @@ -0,0 +1,575 @@ +/** + ******************************************************************************* + * @file usb_host_int.c + * @brief Host driver interrupt subroutines. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_int.h" +#include "usb_host_driver.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +void usb_host_hc_isr(usb_core_instance *pdev); + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief processes interrupt for a specific host channel which is used for OUT EP + * @param [in] pdev device instance + * @param [in] chnum channel index + * @retval None + */ +static void usb_host_chx_out_isr(usb_core_instance *pdev, uint8_t chnum) +{ + uint32_t u32hcchar; + uint32_t u32hcint; + uint32_t u32hcintmsk; + + u32hcchar = READ_REG32(pdev->regs.HC_REGS[chnum]->HCCHAR); + u32hcint = READ_REG32(pdev->regs.HC_REGS[chnum]->HCINT); + u32hcintmsk = READ_REG32(pdev->regs.HC_REGS[chnum]->HCINTMSK); + u32hcint = u32hcint & u32hcintmsk; + + if (0UL != (u32hcint & USBFS_HCINT_ACK)) { + usb_host_clrint(pdev, chnum, USBFS_HCINT_ACK); + } +#if defined (HC32F4A0) + else if (0UL != (u32hcint & USBFS_HCINT_AHBERR)) { + usb_host_clrint(pdev, chnum, USBFS_HCINT_AHBERR); + usb_host_int_unmskchhltd(pdev, chnum); + } +#endif + else if (0UL != (u32hcint & USBFS_HCINT_FRMOR)) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_FRMOR); + } else if (0UL != (u32hcint & USBFS_HCINT_XFRC)) { + pdev->host.ErrCnt[chnum] = 0U; + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_XFRC); + pdev->host.HC_Status[chnum] = HOST_CH_XFERCOMPL; + } else if (0UL != (u32hcint & USBFS_HCINT_STALL)) { + usb_host_clrint(pdev, chnum, USBFS_HCINT_STALL); + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + pdev->host.HC_Status[chnum] = HOST_CH_STALL; + } else if (0UL != (u32hcint & USBFS_HCINT_NAK)) { + pdev->host.ErrCnt[chnum] = 0U; + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + pdev->host.HC_Status[chnum] = HOST_CH_NAK; + } else if (0UL != (u32hcint & USBFS_HCINT_TXERR)) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + pdev->host.ErrCnt[chnum] ++; + pdev->host.HC_Status[chnum] = HOST_CH_XACTERR; + usb_host_clrint(pdev, chnum, USBFS_HCINT_TXERR); + } else if (0UL != (u32hcint & HCINT_NYET)) { + pdev->host.ErrCnt[chnum] = 0U; + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, HCINT_NYET); + pdev->host.HC_Status[chnum] = HOST_CH_NYET; + } else if (0UL != (u32hcint & USBFS_HCINT_DTERR)) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + pdev->host.HC_Status[chnum] = HOST_CH_DATATGLERR; + usb_host_clrint(pdev, chnum, USBFS_HCINT_DTERR); + } else if (0UL != (u32hcint & USBFS_HCINT_CHH)) { + usb_host_int_mskchhltd(pdev, chnum); + if (pdev->host.HC_Status[chnum] == HOST_CH_XFERCOMPL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE; + + if (((u32hcchar & USBFS_HCCHAR_EPTYP) >> USBFS_HCCHAR_EPTYP_POS) == EP_TYPE_BULK) { + pdev->host.hc[chnum].out_toggle ^= 1U; + } + } else if (pdev->host.HC_Status[chnum] == HOST_CH_NAK) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_UNREADY; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_NYET) { + if (pdev->host.hc[chnum].do_ping == 1U) { + usb_pingtokenissue(&pdev->regs, chnum); + } + pdev->host.URB_State[chnum] = HOST_CH_XFER_UNREADY; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_STALL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_STALL; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_XACTERR) { + if (pdev->host.ErrCnt[chnum] == 3UL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_ERROR; + pdev->host.ErrCnt[chnum] = 0UL; + } + } else { + ; + } + usb_host_clrint(pdev, chnum, USBFS_HCINT_CHH); + } else { + ; + } +} + +/** + * @brief processes interrupt for a specific host Channel which is used for IN EP + * @param [in] pdev device instance + * @param [in] chnum channel index + * @retval None + */ +static void usb_host_chx_in_isr(usb_core_instance *pdev, uint8_t chnum) +{ + uint32_t u32hcchar; + uint32_t u32hctsiz; + uint32_t u32eptypetmp; + uint32_t u32hcint; + uint32_t u32hcintmsk; + + u32hcchar = READ_REG32(pdev->regs.HC_REGS[chnum]->HCCHAR); + u32hcint = READ_REG32(pdev->regs.HC_REGS[chnum]->HCINT); + u32hcintmsk = READ_REG32(pdev->regs.HC_REGS[chnum]->HCINTMSK); + u32hcint = u32hcint & u32hcintmsk; + + u32eptypetmp = (u32hcchar & USBFS_HCCHAR_EPTYP) >> USBFS_HCCHAR_EPTYP_POS; + if (0UL != (u32hcint & USBFS_HCINT_ACK)) { + usb_host_clrint(pdev, chnum, USBFS_HCINT_ACK); + } +#if defined (HC32F4A0) + else if (0UL != (u32hcint & USBFS_HCINT_AHBERR)) { + usb_host_clrint(pdev, chnum, USBFS_HCINT_AHBERR); + usb_host_int_unmskchhltd(pdev, chnum); + } +#endif + else if (0UL != (u32hcint & USBFS_HCINT_STALL)) { + usb_host_int_unmskchhltd(pdev, chnum); + pdev->host.HC_Status[chnum] = HOST_CH_STALL; + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + usb_host_clrint(pdev, chnum, USBFS_HCINT_STALL); + usb_hchstop(&pdev->regs, chnum); + } else if (0UL != (u32hcint & USBFS_HCINT_DTERR)) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + pdev->host.HC_Status[chnum] = HOST_CH_DATATGLERR; + usb_host_clrint(pdev, chnum, USBFS_HCINT_DTERR); + } else if (0UL != (u32hcint & USBFS_HCINT_FRMOR)) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_FRMOR); + } else if (0UL != (u32hcint & USBFS_HCINT_XFRC)) { + if (pdev->basic_cfgs.dmaen == 1U) { + u32hctsiz = READ_REG32(pdev->regs.HC_REGS[chnum]->HCTSIZ); + pdev->host.XferCnt[chnum] = pdev->host.hc[chnum].xfer_len - (u32hctsiz & USBFS_HCTSIZ_XFRSIZ); + } + pdev->host.HC_Status[chnum] = HOST_CH_XFERCOMPL; + pdev->host.ErrCnt [chnum] = 0U; + usb_host_clrint(pdev, chnum, USBFS_HCINT_XFRC); + switch (u32eptypetmp) { + case EP_TYPE_CTRL: + case EP_TYPE_BULK: + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + pdev->host.hc[chnum].in_toggle ^= (uint8_t)1; + break; + case EP_TYPE_INTR: + u32hcchar |= USBFS_HCCHAR_ODDFRM; + WRITE_REG32(pdev->regs.HC_REGS[chnum]->HCCHAR, u32hcchar); + pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE; + break; + case EP_TYPE_ISOC: + if (pdev->host.HC_Status[chnum] == HOST_CH_XFERCOMPL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE; + } + break; + default: + break; + } + } else if (0UL != (u32hcint & USBFS_HCINT_CHH)) { + usb_host_int_mskchhltd(pdev, chnum); + if (pdev->host.HC_Status[chnum] == HOST_CH_XFERCOMPL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_STALL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_STALL; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_XACTERR) { + pdev->host.ErrCnt[chnum] = 0U; + pdev->host.URB_State[chnum] = HOST_CH_XFER_ERROR; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_DATATGLERR) { + pdev->host.ErrCnt[chnum] = 0U; + pdev->host.URB_State[chnum] = HOST_CH_XFER_ERROR; + } else if (u32eptypetmp == EP_TYPE_INTR) { + pdev->host.hc[chnum].in_toggle ^= (uint8_t)1; + } else { + ; + } + usb_host_clrint(pdev, chnum, USBFS_HCINT_CHH); + } else if (0UL != (u32hcint & USBFS_HCINT_TXERR)) { + usb_host_int_unmskchhltd(pdev, chnum); + pdev->host.ErrCnt[chnum] ++; + pdev->host.HC_Status[chnum] = HOST_CH_XACTERR; + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_TXERR); + } else if (0UL != (u32hcint & USBFS_HCINT_NAK)) { + if (u32eptypetmp == EP_TYPE_INTR) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + } else if ((u32eptypetmp == EP_TYPE_CTRL) || (u32eptypetmp == EP_TYPE_BULK)) { + u32hcchar |= USBFS_HCCHAR_CHENA; + u32hcchar &= ~USBFS_HCCHAR_CHDIS; + WRITE_REG32(pdev->regs.HC_REGS[chnum]->HCCHAR, u32hcchar); + } else { + ; + } + pdev->host.HC_Status[chnum] = HOST_CH_NAK; + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + } else { + ; + } +} + +/** + * @brief this function processes the channel interrupt + * @param [in] pdev device instance + * @retval None + */ +void usb_host_hc_isr(usb_core_instance *pdev) +{ + uint32_t u32hcchar; + uint8_t u8Cnt; + uint32_t u32haint; + + u32haint = READ_REG32(pdev->regs.HREGS->HAINT); + for (u8Cnt = 0U; u8Cnt < pdev->basic_cfgs.host_chnum; u8Cnt++) { + if (0UL != (u32haint & (1UL << u8Cnt))) { + u32hcchar = READ_REG32(pdev->regs.HC_REGS[u8Cnt]->HCCHAR); + if (0UL != ((u32hcchar & USBFS_HCCHAR_EPDIR) >> USBFS_HCCHAR_EPDIR_POS)) { + usb_host_chx_in_isr(pdev, u8Cnt); + } else { + usb_host_chx_out_isr(pdev, u8Cnt); + } + } + } +} + +/** + * @brief process the start-of-frame interrupt in host mode. + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_sof_isr(usb_core_instance *pdev) +{ + WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_SOF); +} + +/** + * @brief processes disconnect interrupt + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_disconn_isr(usb_core_instance *pdev) +{ + usb_gintdis(&pdev->regs); + usb_vbusctrl(&pdev->regs, 0U); + WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_DISCINT); + + pdev->host.is_dev_connect = 0U; +} + +#define USBFS_HNPTXSTS_NPTXQTOP_CHEPNUM_POS (27U) +#define USBFS_HNPTXSTS_NPTXQTOP_CHEPNUM (0x78000000UL) +/** + * @brief processes non-periodic txFIFO empty interrupt. + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_nptxfifoempty_isr(usb_core_instance *pdev) +{ + uint32_t u32hnptxsts; + uint16_t u16LenWord; + uint16_t u16Len; + uint8_t u8ChNum; + + u32hnptxsts = READ_REG32(pdev->regs.GREGS->HNPTXSTS); + u8ChNum = (uint8_t)((u32hnptxsts & USBFS_HNPTXSTS_NPTXQTOP_CHEPNUM) >> USBFS_HNPTXSTS_NPTXQTOP_CHEPNUM_POS); + + u16LenWord = (uint16_t)((pdev->host.hc[u8ChNum].xfer_len + 3UL) / 4UL); + while (((u32hnptxsts & USBFS_HNPTXSTS_NPTXFSAV) > u16LenWord) && (pdev->host.hc[u8ChNum].xfer_len != 0U)) { + u16Len = (uint16_t)((u32hnptxsts & USBFS_HNPTXSTS_NPTXFSAV) * 4UL); + if (u16Len > pdev->host.hc[u8ChNum].xfer_len) { + u16Len = (uint16_t)pdev->host.hc[u8ChNum].xfer_len; + CLR_REG32_BIT(pdev->regs.GREGS->GINTMSK, USBFS_GINTSTS_NPTXFE); + } + u16LenWord = (uint16_t)((pdev->host.hc[u8ChNum].xfer_len + 3UL) / 4UL); + usb_wrpkt(&pdev->regs, pdev->host.hc[u8ChNum].xfer_buff, u8ChNum, u16Len, pdev->basic_cfgs.dmaen); + pdev->host.hc[u8ChNum].xfer_buff += u16Len; + pdev->host.hc[u8ChNum].xfer_len -= u16Len; + pdev->host.hc[u8ChNum].xfer_count += u16Len; + u32hnptxsts = READ_REG32(pdev->regs.GREGS->HNPTXSTS); + } +} +#define USBFS_HPTXSTS_PTXQTOP_CHNUM_POS (27U) +#define USBFS_HPTXSTS_PTXQTOP_CHNUM (0x78000000UL) +/** + * @brief processes periodic txFIFO empty interrupt + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_ptxfifoempty_isr(usb_core_instance *pdev) +{ + uint32_t u32hptxsts; + uint16_t u16LenWord; + uint16_t u16Len; + uint8_t u8ChNum; + + u32hptxsts = READ_REG32(pdev->regs.HREGS->HPTXSTS); + u8ChNum = (uint8_t)((u32hptxsts & USBFS_HPTXSTS_PTXQTOP_CHNUM) >> USBFS_HPTXSTS_PTXQTOP_CHNUM_POS); + u16LenWord = (uint16_t)((pdev->host.hc[u8ChNum].xfer_len + 3UL) / 4UL); + while ((((u32hptxsts & USBFS_HPTXSTS_PTXFSAVL)) > u16LenWord) && (pdev->host.hc[u8ChNum].xfer_len != 0U)) { + u16Len = (uint16_t)((u32hptxsts & USBFS_HPTXSTS_PTXFSAVL) * 4UL); + if (u16Len > pdev->host.hc[u8ChNum].xfer_len) { + u16Len = (uint16_t)pdev->host.hc[u8ChNum].xfer_len; + CLR_REG32_BIT(pdev->regs.GREGS->GINTMSK, USBFS_GINTMSK_PTXFEM); + } + u16LenWord = (uint16_t)((pdev->host.hc[u8ChNum].xfer_len + 3UL) / 4UL); + usb_wrpkt(&pdev->regs, pdev->host.hc[u8ChNum].xfer_buff, u8ChNum, u16Len, pdev->basic_cfgs.dmaen); + pdev->host.hc[u8ChNum].xfer_buff += u16Len; + pdev->host.hc[u8ChNum].xfer_len -= u16Len; + pdev->host.hc[u8ChNum].xfer_count += u16Len; + u32hptxsts = READ_REG32(pdev->regs.HREGS->HPTXSTS); + } +} + +/** + * @brief This function determines which interrupt conditions have occurred + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_port_isr(usb_core_instance *pdev) +{ + uint32_t u32hprt; + uint32_t u32hprt_bk; + uint8_t u8fslspclksel; + uint32_t do_reset = 0UL; + uint8_t u8PortSpeed; + + u32hprt = READ_REG32(*pdev->regs.HPRT); + u32hprt_bk = u32hprt; + /* Clear the interrupt bits in GINTSTS */ + //tmp_hprt_bk.b.prtovrcurrchng = 0U; //todo don't have this bit + u32hprt_bk &= ~(USBFS_HPRT_PENA | USBFS_HPRT_PCDET | USBFS_HPRT_PENCHNG); + + /* check if a port connect have been detected */ + if ((u32hprt & USBFS_HPRT_PCDET) != 0UL) { + u32hprt_bk |= USBFS_HPRT_PCDET; + if (host_driver_getvbusdrivestate(pdev) != 0UL) { + pdev->host.is_dev_connect = 1U; + } + } + /* check if port enable or disable change */ + if ((u32hprt & USBFS_HPRT_PENCHNG) != 0UL) { + u32hprt_bk |= USBFS_HPRT_PENCHNG; + + if ((u32hprt & USBFS_HPRT_PENA) != 0UL) { + u8PortSpeed = (uint8_t)((u32hprt & USBFS_HPRT_PSPD) >> USBFS_HPRT_PSPD_POS); + if ((u8PortSpeed == PRTSPD_LOW_SPEED) || (u8PortSpeed == PRTSPD_FULL_SPEED)) { + u8fslspclksel = (uint8_t)(READ_REG32(pdev->regs.HREGS->HCFG) & USBFS_HCFG_FSLSPCS); + if (u8PortSpeed == PRTSPD_LOW_SPEED) { + if (u8fslspclksel != HCFG_6_MHZ) { + do_reset = 1U; + } + } else { + /* 1ms*(PHY clock frequency for FS/LS)-1 */ + WRITE_REG32(pdev->regs.HREGS->HFIR, 48000UL); + if (u8fslspclksel != HCFG_48_MHZ) { + usb_fslspclkselset(&pdev->regs, HCFG_48_MHZ); + do_reset = 1U; + } + } + } else { + do_reset = 1U; + } + } + } + + //todo don't have this bit + //if ((u32hprt & USBFS_HPRT_PRTOVRCURRCHNG) != 0UL) { + // u32hprt_bk |= USBFS_HPRT_PRTOVRCURRCHNG; + //} + + if (0UL != do_reset) { + usb_hprtrst(&pdev->regs); + } + WRITE_REG32(*pdev->regs.HPRT, u32hprt_bk); +} + +/** + * @brief processes the rxFIFO non-empty interrupt + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_rxflvl_isr(usb_core_instance *pdev) +{ + uint32_t u32grxsts; + uint32_t u32hctsiz; + uint32_t u32hcchar; + uint8_t u8chnum; + uint8_t *pu8Tmp; + uint16_t u16bcnt; + + CLR_REG32_BIT(pdev->regs.GREGS->GINTMSK, USBFS_GINTSTS_RXFNE); + + u32grxsts = READ_REG32(pdev->regs.GREGS->GRXSTSP); + u8chnum = (uint8_t)(u32grxsts & USBFS_GRXSTSP_CHNUM_EPNUM); + u16bcnt = (uint16_t)((u32grxsts & USBFS_GRXSTSP_BCNT) >> USBFS_GRXSTSP_BCNT_POS); + u32hcchar = READ_REG32(pdev->regs.HC_REGS[u8chnum]->HCCHAR); + + switch ((u32grxsts & USBFS_GRXSTSP_PKTSTS) >> USBFS_GRXSTSP_PKTSTS_POS) { + case 2: /* IN dat packet received */ + pu8Tmp = pdev->host.hc[u8chnum].xfer_buff; + if ((u16bcnt > 0U) && (pu8Tmp != (void *)0U)) { + usb_rdpkt(&pdev->regs, pdev->host.hc[u8chnum].xfer_buff, u16bcnt); + pdev->host.hc[u8chnum].xfer_buff += u16bcnt; + pdev->host.hc[u8chnum].xfer_count += u16bcnt; + pdev->host.XferCnt[u8chnum] = pdev->host.hc[u8chnum].xfer_count; + + u32hctsiz = READ_REG32(pdev->regs.HC_REGS[u8chnum]->HCTSIZ); + if (((u32hctsiz & USBFS_HCTSIZ_PKTCNT) >> USBFS_HCTSIZ_PKTCNT_POS) > 0U) { + u32hcchar |= USBFS_HCCHAR_CHENA; + u32hcchar &= ~USBFS_HCCHAR_CHDIS; + WRITE_REG32(pdev->regs.HC_REGS[u8chnum]->HCCHAR, u32hcchar); + } + } + break; + + case 3: /* IN transfer completed(trigger an interrupt) */ + break; + case 5: /* Daat toggle error(trigger an interrupt) */ + break; + case 7: /* Channel halted(trigger an interrupt) */ + break; + default: + break; + } + + SET_REG32_BIT(pdev->regs.GREGS->GINTMSK, USBFS_GINTSTS_RXFNE); +} + +/** + * @brief process the incomplete periodic transfer interrupt(incompIP) + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_incomplisoout_isr(usb_core_instance *pdev) +{ + SET_REG32_BIT(pdev->regs.HC_REGS[0]->HCCHAR, USBFS_HCCHAR_CHENA | USBFS_HCCHAR_CHDIS); + WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_IPXFR_INCOMPISOOUT); +} + +/** + * @brief process the resume/remote wakeup detected interrupt(WkUpInt) + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_wkupint_isr(usb_core_instance *pdev) +{ + uint32_t u32hprt; + u32hprt = usb_rdhprt(&pdev->regs); + u32hprt &= ~USBFS_HPRT_PRES; + WRITE_REG32(*pdev->regs.HPRT, u32hprt); +} + +/** + * @brief This function process all interrupt of USB in host mode + * @param [in] pdev device instance + * @retval None + */ +void usb_host_isr(usb_core_instance *pdev) +{ + uint32_t gintstsval; + if (0U != usb_getcurmod(&pdev->regs)) { + gintstsval = usb_getcoreintr(&pdev->regs); + if (0UL != (gintstsval & USBFS_GINTSTS_SOF)) { + usb_host_sof_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_RXFNE)) { + usb_host_rxflvl_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_NPTXFE)) { + usb_host_nptxfifoempty_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_PTXFE)) { + usb_host_ptxfifoempty_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_HCINT)) { + usb_host_hc_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_HPRTINT)) { + usb_host_port_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_DISCINT)) { + usb_host_disconn_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_IPXFR_INCOMPISOOUT)) { + usb_host_incomplisoout_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_WKUINT)) { + usb_host_wkupint_isr(pdev); + } + } +} + +/** + * @} + */ + +/** + * @} + */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.h new file mode 100644 index 000000000..6942068b9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.h @@ -0,0 +1,128 @@ +/** + ******************************************************************************* + * @file usb_host_int.h + * @brief Head file for usb_host_int.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_HOST_INT_H__ +#define __USB_HOST_INT_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define HCINT_NYET (1UL << 6) + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +/** + * @brief clear the interrupt flag bit + * @param [in] pdev device instance + * @param [in] ch_num the channel index + * @param [in] intbit the interrupt bit of the register HCINTn + * @retval None + */ +__STATIC_INLINE void usb_host_clrint(usb_core_instance *pdev, uint32_t ch_num, uint32_t intbit) +{ + WRITE_REG32(pdev->regs.HC_REGS[ch_num]->HCINT, intbit); +} + +/** + * @brief mask the interrupt of ChHltd + * @param [in] pdev device instance + * @param [in] ch_num channel index of the host application + * @retval None + */ +__STATIC_INLINE void usb_host_int_mskchhltd(usb_core_instance *pdev, uint32_t ch_num) +{ + CLR_REG32_BIT(pdev->regs.HC_REGS[ch_num]->HCINTMSK, USBFS_HCINTMSK_CHHM); +} + +/** + * @brief unmask the interrupt of ChHltd + * @param [in] pdev device instance + * @param [in] ch_num channel index of the host application + * @retval None + */ +__STATIC_INLINE void usb_host_int_unmskchhltd(usb_core_instance *pdev, uint32_t ch_num) +{ + SET_REG32_BIT(pdev->regs.HC_REGS[ch_num]->HCINTMSK, USBFS_HCINTMSK_CHHM); +} + +/** + * @brief mask the interrupt of ACK + * @param [in] pdev device instance + * @param [in] ch_num channel index of the host application + * @retval None + */ +__STATIC_INLINE void usb_host_int_mskack(usb_core_instance *pdev, uint32_t ch_num) +{ + CLR_REG32_BIT(pdev->regs.HC_REGS[ch_num]->HCINTMSK, USBFS_HCINTMSK_ACKM); +} + +/** + * @brief unmask the interrupt of ACK + * @param [in] pdev device instance + * @param [in] ch_num channel index of the host application + * @retval None + */ +__STATIC_INLINE void usb_host_int_unmskack(usb_core_instance *pdev, uint32_t ch_num) +{ + SET_REG32_BIT(pdev->regs.HC_REGS[ch_num]->HCINTMSK, USBFS_HCINTMSK_ACKM); +} + +void usb_host_isr(usb_core_instance *pdev); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_INT_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ + + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.c new file mode 100644 index 000000000..02f316bca --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.c @@ -0,0 +1,482 @@ +/** + ******************************************************************************* + * @file usb_host_stdreq.c + * @brief Standard requests for device enumeration + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_stdreq.h" +#include "usb_host_ctrltrans.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes declared in the last part. + ******************************************************************************/ +void usb_host_parsedevdesc(usb_host_devdesc_typedef *, uint8_t *buf, uint16_t length); + +void usb_host_parsecfgdesc(usb_host_cfgdesc_typedef *cfg_desc, + usb_host_itfdesc_typedef *itf_desc, + USB_HOST_EPDesc_TypeDef ep_desc[][USBH_MAX_NUM_ENDPOINTS], + uint8_t *buf, + uint16_t length); +void usb_host_parseitfdesc(usb_host_itfdesc_typedef *if_descriptor, uint8_t *buf); +void usb_host_parseepdesc(USB_HOST_EPDesc_TypeDef *ep_descriptor, uint8_t *buf); +void usb_host_parsestringdesc(uint8_t *psrc, uint8_t *pdest, uint16_t length); + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +/** + * @brief issue a command descriptor from the connected device. parses the + * descriptor and updates the status once the response has been received. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] req_type type of the descriptor + * @param [in] value_idx wValue of setup for the request to get Descriptr + * @param [in] buff: buffer to save the the descriptor + * @param [in] length the length of the description. + * @retval status + */ +HOST_STATUS usb_host_getdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t req_type, + uint16_t value_idx, + uint8_t *buff, + uint16_t length) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_D2H | req_type; + phost->ctrlparam.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR; + phost->ctrlparam.setup.b.wValue.w = value_idx; + + if ((value_idx & 0xff00U) == USB_DESC_STRING) { + phost->ctrlparam.setup.b.wIndex.w = 0x0409U; + } else { + phost->ctrlparam.setup.b.wIndex.w = 0U; + } + phost->ctrlparam.setup.b.wLength.w = length; + return usb_host_ctrlreq(pdev, phost, buff, length); +} + +/** + * @brief Issue command to the device to get the device discription. it parses + * the device descriptor and updates the status once getting the device + * description. + * @param [in] pdev device instance + * @param [in] phost host state set. + * @param [in] length the length of the description. + * @retval status + */ +HOST_STATUS usb_host_getdevdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t length) +{ + HOST_STATUS status; + status = usb_host_getdesc(pdev, + phost, + (uint8_t)(USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD), + USB_DESC_DEVICE, + pdev->host.Rx_Buffer, + (uint16_t)length); + if (status == HSTATUS_OK) { + /* Commands successfully sent and Response Received */ + usb_host_parsedevdesc(&phost->device_prop.devdesc, pdev->host.Rx_Buffer, (uint16_t)length); + } + return status; +} + +/** + * @brief Issue a command to get the configuration description from the device + * connected, parse the configuration descriptor and update the + * status once the response has been received. + * @param [in] pdev device instance + * @param [in] phost host state set. + * @param [in] length the length of the description. + * @retval status + */ +HOST_STATUS usb_host_getcfgdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint16_t length) +{ + HOST_STATUS status; + + status = usb_host_getdesc(pdev, + phost, + USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, + USB_DESC_CONFIGURATION, + pdev->host.Rx_Buffer, + length); + if (status == HSTATUS_OK) { + usb_host_parsecfgdesc(&phost->device_prop.devcfgdesc, + phost->device_prop.devitfdesc, + phost->device_prop.devepdesc, + pdev->host.Rx_Buffer, + length); + } + return status; +} + +/** + * @brief Issues string Descriptor command to the device. Once the response + * received, it parses the string descriptor and updates the status. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] string_index the index for the string + * @param [in] buff buffer to save the the string descriptor + * @param [in] length the length of the description. + * @retval status + */ +HOST_STATUS usb_host_getstringdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t string_index, + uint8_t *buff, + uint16_t length) +{ + HOST_STATUS status; + status = usb_host_getdesc(pdev, + phost, + USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, + USB_DESC_STRING | string_index, + pdev->host.Rx_Buffer, + length); + if (status == HSTATUS_OK) { + usb_host_parsestringdesc(pdev->host.Rx_Buffer, buff, length); + } + return status; +} + +/** + * @brief issue a command to set the address for the device that have connected. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] DeviceAddress Device address which would be set to the conected device + * @retval status + */ +HOST_STATUS usb_host_setdevaddr(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t DeviceAddress) +{ + /* + Refer to table9-3 of 9.4 + */ + phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD; + phost->ctrlparam.setup.b.bRequest = USB_REQ_SET_ADDRESS; + phost->ctrlparam.setup.b.wValue.w = (uint16_t)DeviceAddress; + phost->ctrlparam.setup.b.wIndex.w = 0U; + phost->ctrlparam.setup.b.wLength.w = 0U; + + return usb_host_ctrlreq(pdev, phost, NULL, 0U); +} + +/** + * @brief issue a command to set the configuration to the connected device. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] cfg_idx value for the configuration setup + * @retval status + */ +HOST_STATUS usb_host_setconfig(usb_core_instance *pdev, + USBH_HOST *phost, + uint16_t cfg_idx) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD; + phost->ctrlparam.setup.b.bRequest = USB_REQ_SET_CONFIGURATION; + phost->ctrlparam.setup.b.wValue.w = cfg_idx; + phost->ctrlparam.setup.b.wIndex.w = 0U; + phost->ctrlparam.setup.b.wLength.w = 0U; + + return usb_host_ctrlreq(pdev, phost, NULL, 0U); +} + +/** + * @brief issue a command to set the Interface value to the connected device + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] ep_num the index of the endpoint + * @param [in] altSetting the value for the setup of set interface + * @retval status + */ +HOST_STATUS usb_host_setintf(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t ep_num, + uint8_t altSetting) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_STANDARD; + + phost->ctrlparam.setup.b.bRequest = USB_REQ_SET_INTERFACE; + phost->ctrlparam.setup.b.wValue.w = altSetting; + phost->ctrlparam.setup.b.wIndex.w = ep_num; + phost->ctrlparam.setup.b.wLength.w = 0U; + + return usb_host_ctrlreq(pdev, phost, NULL, 0U); +} + +/** + * @brief issue a comman to clear or disable a specific feature in the device. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] ep_num index of the endpoint + * @param [in] hc_num host channel index + * @retval status + */ +HOST_STATUS usb_host_clrfeature(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t ep_num, + uint8_t hc_num) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_H2D | + USB_REQ_RECIPIENT_ENDPOINT | + USB_REQ_TYPE_STANDARD; + + phost->ctrlparam.setup.b.bRequest = USB_REQ_CLEAR_FEATURE; + phost->ctrlparam.setup.b.wValue.w = FEATURE_SELECTOR_ENDPOINT; + phost->ctrlparam.setup.b.wIndex.w = ep_num; + phost->ctrlparam.setup.b.wLength.w = 0U; + + if ((ep_num & USB_REQ_DIR_MASK) == USB_D2H) { + pdev->host.hc[hc_num].in_toggle = 0U; + } else { + pdev->host.hc[hc_num].out_toggle = 0U; + } + + return usb_host_ctrlreq(pdev, phost, NULL, 0U); +} + +/** + * @brief parse the data frame of device descriptor + * @param [in] dev_desc the structure of the device descriptor + * @param [in] buf buffer where the source descriptor is save + * @param [in] length Length of the descriptor in byte + * @retval None + */ +void usb_host_parsedevdesc(usb_host_devdesc_typedef *dev_desc, + uint8_t *buf, + uint16_t length) +{ + dev_desc->bLength = *(uint8_t *)(buf + 0U); + dev_desc->bDescriptorType = *(uint8_t *)(buf + 1U); + dev_desc->bcdUSB = SMALL_END(buf + 2U); + dev_desc->bDeviceClass = *(uint8_t *)(buf + 4U); + dev_desc->bDeviceSubClass = *(uint8_t *)(buf + 5U); + dev_desc->bDeviceProtocol = *(uint8_t *)(buf + 6U); + dev_desc->bMaxPacketSize0 = *(uint8_t *)(buf + 7U); + + if (length > (uint16_t)8) { + dev_desc->idVendor = SMALL_END(buf + 8U); + dev_desc->idProduct = SMALL_END(buf + 10U); + dev_desc->bcdDevice = SMALL_END(buf + 12U); + dev_desc->iManufacturer = *(uint8_t *)(buf + 14U); + dev_desc->iProduct = *(uint8_t *)(buf + 15U); + dev_desc->iSerialNumber = *(uint8_t *)(buf + 16U); + dev_desc->bNumConfigurations = *(uint8_t *)(buf + 17U); + } +} + +/** + * @brief This function Parses the configuration descriptor from the received buffer + * @param [in] cfg_desc the structure of configuration descriptor + * @param [in] itf_desc the structure of interface descriptor + * @param [in] ep_desc the structure of endpoint descriptor + * @param [in] buf buffer where the source descriptor is save + * @param [in] length Length of the descriptor in byte + * @retval None + */ +void usb_host_parsecfgdesc(usb_host_cfgdesc_typedef *cfg_desc, + usb_host_itfdesc_typedef *itf_desc, + USB_HOST_EPDesc_TypeDef ep_desc[][USBH_MAX_NUM_ENDPOINTS], + uint8_t *buf, + uint16_t length) +{ + usb_host_itfdesc_typedef *pif ; + usb_host_itfdesc_typedef temp_pif ; + USB_HOST_EPDesc_TypeDef *pep; + USB_HOST_DescHeader_TypeDef *pdesc = (USB_HOST_DescHeader_TypeDef *)buf; + uint16_t ptr; + int8_t if_ix; + int8_t ep_ix; + static uint16_t prev_ep_size = 0U; + static uint8_t prev_itf = 0U; + + /* Parse the configuration descriptor */ + cfg_desc->bLength = *(uint8_t *)(buf + 0U); + cfg_desc->bDescriptorType = *(uint8_t *)(buf + 1U); + cfg_desc->wTotalLength = SMALL_END(buf + 2U); + cfg_desc->bNumInterfaces = *(uint8_t *)(buf + 4U); + cfg_desc->bConfigurationValue = *(uint8_t *)(buf + 5U); + cfg_desc->iConfiguration = *(uint8_t *)(buf + 6U); + cfg_desc->bmAttributes = *(uint8_t *)(buf + 7U); + cfg_desc->bMaxPower = *(uint8_t *)(buf + 8U); + + if (length > USB_CONFIGURATION_DESC_SIZE) { + ptr = USB_LEN_CFG_DESC; + + if (cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES) { + + while (ptr < cfg_desc->wTotalLength) { + pdesc = usb_host_getnextdesc((uint8_t *)pdesc, &ptr); + if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE) { + if_ix = (int8_t) * (((uint8_t *)pdesc) + 2U); + pif = &itf_desc[if_ix]; + + if ((*((uint8_t *)pdesc + 3U)) < 3U) { + usb_host_parseitfdesc(&temp_pif, (uint8_t *)pdesc); + ep_ix = (int8_t)0; + + /* Parse Ep descriptors relative to the current interface */ + if (temp_pif.bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) { + while (ep_ix < (int8_t)temp_pif.bNumEndpoints) { + pdesc = usb_host_getnextdesc((void *)pdesc, &ptr); + if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) { + pep = &ep_desc[if_ix][ep_ix]; + + if (prev_itf != (uint8_t)if_ix) { + prev_itf = (uint8_t)if_ix; + usb_host_parseitfdesc(pif, (uint8_t *)&temp_pif); + } else { + if (prev_ep_size > SMALL_END((uint8_t *)pdesc + 4U)) { + break; + } else { + usb_host_parseitfdesc(pif, (uint8_t *)&temp_pif); + } + } + usb_host_parseepdesc(pep, (uint8_t *)pdesc); + prev_ep_size = SMALL_END((uint8_t *)pdesc + 4U); + ep_ix++; + } + } + } + } + } + } + } + prev_ep_size = 0U; + prev_itf = 0U; + } +} + +/** + * @brief This function parses the interface descriptor from the received buffer. + * @param [in] if_descriptor structure of interface descriptor + * @param [in] buf buffer where the source descriptor is save + * @retval None + */ +void usb_host_parseitfdesc(usb_host_itfdesc_typedef *if_descriptor, uint8_t *buf) +{ + if_descriptor->bLength = *(uint8_t *)(buf + 0U); + if_descriptor->bDescriptorType = *(uint8_t *)(buf + 1U); + if_descriptor->bInterfaceNumber = *(uint8_t *)(buf + 2U); + if_descriptor->bAlternateSetting = *(uint8_t *)(buf + 3U); + if_descriptor->bNumEndpoints = *(uint8_t *)(buf + 4U); + if_descriptor->bInterfaceClass = *(uint8_t *)(buf + 5U); + if_descriptor->bInterfaceSubClass = *(uint8_t *)(buf + 6U); + if_descriptor->bInterfaceProtocol = *(uint8_t *)(buf + 7U); + if_descriptor->iInterface = *(uint8_t *)(buf + 8U); +} + +/** + * @brief This function parses the endpoint descriptor from the received buffer. + * @param [in] ep_descriptor the structure of endpoint descriptor. + * @param [in] buf buffer where the source descriptor is save + * @retval None + */ +void usb_host_parseepdesc(USB_HOST_EPDesc_TypeDef *ep_descriptor, uint8_t *buf) +{ + ep_descriptor->bLength = *(uint8_t *)(buf + 0U); + ep_descriptor->bDescriptorType = *(uint8_t *)(buf + 1U); + ep_descriptor->bEndpointAddress = *(uint8_t *)(buf + 2U); + ep_descriptor->bmAttributes = *(uint8_t *)(buf + 3U); + ep_descriptor->wMaxPacketSize = SMALL_END(buf + 4U); + ep_descriptor->bInterval = *(uint8_t *)(buf + 6U); +} + +/** + * @brief This function parses the string descriptor from the received buffer. + * @param [in] psrc source data + * @param [in] pdest destination data + * @param [in] length Length of the descriptor in byte + * @retval None + */ +void usb_host_parsestringdesc(uint8_t *psrc, uint8_t *pdest, uint16_t length) +{ + uint16_t strlength; + uint16_t tmp_idx; + /* + The describ of String Desctipor refers to 9.6.8 + psrc[0] = bLength bLength = N+2 + psrc[1] = bDescriptorType STRING Descriptor Type + ... + */ + if (psrc[1] == USB_DESC_TYPE_STRING) { + strlength = ((((uint16_t)psrc[0]) - 2U) <= length) ? (((uint16_t)psrc[0]) - 2U) : length; + psrc += 2U; + for (tmp_idx = 0U; tmp_idx < strlength; tmp_idx += 2U) { + *pdest = psrc[tmp_idx]; + pdest++; + } + *pdest = 0U; + } +} + +/** + * @brief This function gets the header of next descriptor. + * @param [in] pbuf buffer where the configuration descriptor is contained. + * @param [in] ptr data popinter inside the cfg descriptor + * @retval header of next descriptor + */ +USB_HOST_DescHeader_TypeDef *usb_host_getnextdesc(uint8_t *pbuf, uint16_t *ptr) +{ + USB_HOST_DescHeader_TypeDef *pnext; + + *ptr += ((USB_HOST_DescHeader_TypeDef *)pbuf)->bLength; + pnext = (USB_HOST_DescHeader_TypeDef *)((uint8_t *)pbuf + ((USB_HOST_DescHeader_TypeDef *)pbuf)->bLength); + + return (pnext); +} + +/** + * @} + */ + +/** + * @} + */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.h new file mode 100644 index 000000000..762a89597 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.h @@ -0,0 +1,107 @@ +/** + ******************************************************************************* + * @file usb_host_stdreq.h + * @brief Header file for usb_host_stdreq.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_HOST_STDREQ_H__ +#define __USB_HOST_STDREQ_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/* USBH_STDREQ_Exported_Defines */ +/* Standard Feature Selector for clear feature command */ +#define FEATURE_SELECTOR_ENDPOINT (0x00U) +#define FEATURE_SELECTOR_DEVICE (0x01U) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern HOST_STATUS usb_host_getdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t req_type, + uint16_t value_idx, + uint8_t *buff, + uint16_t length); + +extern HOST_STATUS usb_host_getdevdesc(usb_core_instance *pdev, USBH_HOST *phost, uint8_t length); + +HOST_STATUS usb_host_getstringdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t string_index, + uint8_t *buff, + uint16_t length); + +extern HOST_STATUS usb_host_setconfig(usb_core_instance *pdev, USBH_HOST *phost, uint16_t cfg_idx); + +extern HOST_STATUS usb_host_getcfgdesc(usb_core_instance *pdev, USBH_HOST *phost, uint16_t length); + +extern HOST_STATUS usb_host_setdevaddr(usb_core_instance *pdev, USBH_HOST *phost, uint8_t DeviceAddress); + +extern HOST_STATUS usb_host_clrfeature(usb_core_instance *pdev, USBH_HOST *phost, uint8_t ep_num, uint8_t hc_num); + +extern HOST_STATUS usb_host_setintf(usb_core_instance *pdev, USBH_HOST *phost, uint8_t ep_num, uint8_t altSetting); + +extern USB_HOST_DescHeader_TypeDef *usb_host_getnextdesc(uint8_t *pbuf, uint16_t *ptr); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_STDREQ_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/usb_lib.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/usb_lib.h new file mode 100644 index 000000000..9b1132c27 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/usb_lib.h @@ -0,0 +1,199 @@ +/** + ******************************************************************************* + * @file usb_lib.h + * @brief Header of the Core Layer Driver + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_LIB_H__ +#define __USB_LIB_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include +#include + +/** + * @addtogroup LL_USB_LIB LL USB Lib + * @{ + */ + +/** + * @addtogroup LL_USB_LIB_DEF LL USB Lib Define + * @{ + */ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define MAX_DATA_LENGTH (0x200U) + + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/* status of the host channel */ +typedef enum { + HOST_CH_IDLE = 0U, + HOST_CH_XFERCOMPL, + HOST_CH_CHHLTD, + HOST_CH_NAK, + HOST_CH_NYET, + HOST_CH_STALL, + HOST_CH_XACTERR, + HOST_CH_BBLERR, + HOST_CH_DATATGLERR, + HOST_CH_AHBERR, + HOST_CH_FRMOVRUN, + HOST_CH_BNAINTR, + HOST_CH_XCS_XACT_ERR, + HOST_CH_DESC_LST_ROLLINTR +} HOST_CH_STATUS; + +typedef enum { + HOST_CH_XFER_IDLE = 0U, + HOST_CH_XFER_DONE, + HOST_CH_XFER_UNREADY, + HOST_CH_XFER_ERROR, + HOST_CH_XFER_STALL +} HOST_CH_XFER_STATE; + +typedef enum { + CTRL_START = 0U, + CTRL_XFRC, + CTRL_HALTED, + CTRL_NAK, + CTRL_STALL, + CTRL_XACTERR, + CTRL_BBLERR, + CTRL_DATATGLERR, + CTRL_FAIL +} CTRL_HANDLE_STATUS; + +typedef struct { + uint8_t bmRequest; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} USB_SETUP_REQ; + +typedef struct { + uint8_t *(*get_dev_desc)(uint16_t *length); + uint8_t *(*get_dev_langiddesc)(uint16_t *length); + uint8_t *(*get_dev_manufacturerstr)(uint16_t *length); + uint8_t *(*get_dev_productstr)(uint16_t *length); + uint8_t *(*get_dev_serialstr)(uint16_t *length); + uint8_t *(*get_dev_configstr)(uint16_t *length); + uint8_t *(*get_dev_interfacestr)(uint16_t *length); +} usb_dev_desc_func; + +typedef struct { + void (*class_init)(void *pdev); + void (*class_deinit)(void *pdev); + uint8_t (*ep0_setup)(void *pdev, USB_SETUP_REQ *req); + void (*ep0_datain)(void *pdev); + void (*ep0_dataout)(void *pdev); + uint8_t *(*class_getconfigdesc)(uint16_t *length); + uint8_t (*class_sof)(void *pdev); + void (*class_datain)(void *pdev, uint8_t epnum); + void (*class_dataout)(void *pdev, uint8_t epnum); + void (*class_syn_in_incomplt)(void *pdev); + void (*class_syn_out_incomplt)(void *pdev); +} usb_dev_class_func; + +typedef struct { + void (*user_init)(void); + void (*user_devrst)(void); + void (*user_devconfig)(void); + void (*user_devsusp)(void); + void (*user_devresume)(void); + void (*user_devconn)(void); + void (*user_devdisconn)(void); +} usb_dev_user_func; + +typedef struct { + __IO uint8_t device_config; + __IO uint8_t device_address; + __IO uint8_t device_state; + __IO uint8_t device_old_status; + __IO uint8_t device_cur_status; + __IO uint8_t connection_status; + __IO uint8_t device_remote_wakeup; + __IO uint8_t test_mode; + USB_DEV_EP in_ep[USB_MAX_TX_FIFOS]; + USB_DEV_EP out_ep[USB_MAX_TX_FIFOS]; + uint8_t setup_pkt_buf[24]; + usb_dev_class_func *class_callback; + usb_dev_user_func *user_callback; + usb_dev_desc_func *desc_callback; +} USB_DEV_PARAM; + +typedef struct { + uint16_t channel[USB_MAX_TX_FIFOS]; + USB_HOST_CH hc[USB_MAX_TX_FIFOS]; + __IO uint32_t is_dev_connect; + uint8_t Rx_Buffer[MAX_DATA_LENGTH]; + __IO uint32_t ErrCnt[USB_MAX_TX_FIFOS]; + __IO uint32_t XferCnt[USB_MAX_TX_FIFOS]; + __IO HOST_CH_STATUS HC_Status[USB_MAX_TX_FIFOS]; + __IO HOST_CH_XFER_STATE URB_State[USB_MAX_TX_FIFOS]; +} USB_HOST_PARAM; + +typedef struct { + USB_CORE_BASIC_CFGS basic_cfgs; + LL_USB_TypeDef regs; +#ifdef USE_DEVICE_MODE + USB_DEV_PARAM dev; +#endif +#ifdef USE_HOST_MODE + USB_HOST_PARAM host; +#endif +} usb_core_instance; + + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_LIB_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.c new file mode 100644 index 000000000..d3ceadb1f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.c @@ -0,0 +1,340 @@ +/** + ******************************************************************************* + * @file usb/usb_host_msc/source/usb_host_user.c + * @brief user application layer. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ + +/** +* @file usb_host_user.c +* @brief support hc32f4a0-board usb function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-07 +*/ + +/************************************************* +File name: usb_host_user.c +Description: support hc32f4a0-board usb function +Others: +History: +1. Date: 2022-11-07 +Author: AIIT XUOS Lab +Modification: +1. delete useless usb host configure and define +2. add KPrintf function +3. add UsbMountFileSystem() and UsbUnmountFileSystem() +*************************************************/ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include +#include +#include +#include "usb_host_user.h" +#include "usb_host_msc_class.h" +#include "usb_host_msc_scsi.h" +#include "usb_host_msc_bot.h" +#include "usb_host_driver.h" + +/** + * @addtogroup HC32F4A0_DDL_Applications + * @{ + */ + +/** + * @addtogroup USB_Host_Msc + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ +extern void UsbMountFileSystem(); +extern void UsbUnmountFileSystem(); + +/* USBH_USR_Private_Macros */ +extern usb_core_instance usb_app_instance; + +/* Points to the DEVICE_PROP structure of current device */ +/* The purpose of this register is to speed up the execution */ +usb_host_user_callback_func USR_cb = { + &host_user_init, + &host_user_denint, + &host_user_devattached, + &host_user_devreset, + &host_user_devdisconn, + &host_user_overcurrent, + &host_user_devspddetected, + &host_user_devdescavailable, + &host_user_devaddrdistributed, + &host_user_cfgdescavailable, + &host_user_mfcstring, + &host_user_productstring, + &host_user_serialnum, + &host_user_enumcompl, + &host_user_userinput, + &host_user_msc_app, + &host_user_devunsupported, + &host_user_unrecoverederror + +}; + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +static int usb_connect_status = 0; + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +uint8_t USB_HOST_USER_AppState = USH_USR_FS_INIT; + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @brief Displays the message on terminal for host lib initialization + * @param None + * @retval None + */ +void host_user_init(void) +{ + static uint8_t startup = 0U; + + if (startup == 0U) { + startup = 1U; + //KPrintf("USB Host library v2.1.0 started\r\n"); + } +} + +/** + * @brief Displays the message on terminal via DDL_Printf + * @param None + * @retval None + */ +void host_user_devattached(void) +{ + KPrintf("USB device attached\r\n"); +} + +/** + * @brief host_user_unrecoverederror + * @param None + * @retval None + */ +void host_user_unrecoverederror(void) +{ + KPrintf("USB device unrecovered error\r\n"); +} + +/** + * @brief Device disconnect event + * @param None + * @retval None + */ +void host_user_devdisconn(void) +{ + KPrintf("USB device disconnect\r\n"); + usb_connect_status = 0; + UsbUnmountFileSystem(); +} + +/** + * @brief USBH_USR_ResetUSBDevice + * @param None + * @retval None + */ +void host_user_devreset(void) +{ + /* callback for USB-Reset */ + KPrintf("USB device reset\r\n"); +} + +/** + * @brief host_user_devspddetected + * @param [in] DeviceSpeed USB speed + * @retval None + */ +void host_user_devspddetected(uint8_t DeviceSpeed) +{ + if (DeviceSpeed == PRTSPD_FULL_SPEED) { + KPrintf("USB device speed PRTSPD_FULL_SPEED\r\n"); + } else if (DeviceSpeed == PRTSPD_LOW_SPEED) { + KPrintf("USB device speed PRTSPD_LOW_SPEED\r\n"); + } else { + KPrintf("USB device speed error\r\n"); + } +} + +/** + * @brief host_user_devdescavailable + * @param [in] DeviceDesc device descriptor + * @retval None + */ +void host_user_devdescavailable(void *DeviceDesc) +{ + usb_host_devdesc_typedef *hs; + hs = DeviceDesc; + KPrintf("USB device VID : %04lXh PID : %04lXh\r\n", (uint32_t)(*hs).idVendor, (uint32_t)(*hs).idProduct); +} + +/** + * @brief host_user_devaddrdistributed + * @param None + * @retval None + */ +void host_user_devaddrdistributed(void) +{ +} + +/** + * @brief host_user_cfgdescavailable + * @param [in] cfgDesc Configuration desctriptor + * @param [in] itfDesc Interface desctriptor + * @param [in] epDesc Endpoint desctriptor + * @retval None + */ +void host_user_cfgdescavailable(usb_host_cfgdesc_typedef *cfgDesc, + usb_host_itfdesc_typedef *itfDesc, + USB_HOST_EPDesc_TypeDef *epDesc) +{ + usb_host_itfdesc_typedef *id; + + id = itfDesc; + if ((*id).bInterfaceClass == 0x08U) { + KPrintf("USB Mass storage device connected\r\n"); + } else if ((*id).bInterfaceClass == 0x03U) { + KPrintf("USB HID device connected\r\n"); + } else { + ; + } +} + +/** + * @brief Displays the message on terminal for Manufacturer String + * @param [in] ManufacturerString + * @retval None + */ +void host_user_mfcstring(void *ManufacturerString) +{ + KPrintf("Manufacturer : %s\r\n", (char *)ManufacturerString); +} + +/** + * @brief Displays the message on terminal for product String + * @param [in] ProductString + * @retval None + */ +void host_user_productstring(void *ProductString) +{ + KPrintf("Product : %s\r\n", (char *)ProductString); +} + +/** + * @brief Displays the message on terminal for SerialNum_String + * @param [in] SerialNumString + * @retval None + */ +void host_user_serialnum(void *SerialNumString) +{ + KPrintf("Serial Number : %s\r\n", (char *)SerialNumString); +} + +/** + * @brief User response request is displayed to ask application jump to class + * @param None + * @retval None + */ +void host_user_enumcompl(void) +{ +} + +/** + * @brief Device is not supported + * @param None + * @retval None + */ +void host_user_devunsupported(void) +{ + KPrintf("USB Device not supported.\r\n"); +} + +/** + * @brief User Action for application state entry + * @param None + * @retval HOST_USER_STATUS User response for key button + */ +HOST_USER_STATUS host_user_userinput(void) +{ +} + +/** + * @brief Over Current Detected on VBUS + * @param None + * @retval None + */ +void host_user_overcurrent(void) +{ + KPrintf("USB HOST Overcurrent detected.\r\n"); +} + +/** + * @brief Demo application for mass storage + * @param None + * @retval None + */ +int host_user_msc_app(void) +{ + if (0 == usb_connect_status) { + KPrintf("ready to mount file system\n"); + UsbMountFileSystem(); + usb_connect_status = 1; + } + + return ((int)0); +} + +/** + * @brief Deint User state and associated variables + * @param None + * @retval None + */ +void host_user_denint(void) +{ + USB_HOST_USER_AppState = USH_USR_FS_INIT; +} + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.h new file mode 100644 index 000000000..b12cb152a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.h @@ -0,0 +1,109 @@ +/** + ******************************************************************************* + * @file usb/usb_host_msc/source/usb_host_user.h + * @brief Header file for usb_host_user.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC 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 + * + ******************************************************************************* + */ +#ifndef __USB_HOST_USER_H__ +#define __USB_HOST_USER_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +//#include "ff.h" +#include "usb_host_core.h" +#include "usb_app_conf.h" +#include +#include "usb_host_msc_class.h" + +/** + * @addtogroup HC32F4A0_DDL_Applications + * @{ + */ + +/** + * @addtogroup USB_Host_Msc + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +/* State Machine for the USBH_USR_ApplicationState */ +#define USH_USR_FS_INIT (0U) +#define USH_USR_FS_READLIST (1U) +#define USH_USR_FS_WRITEFILE (2U) +#define USH_USR_FS_IDLE (3U) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ +extern usb_host_user_callback_func USR_cb; +extern uint8_t USB_HOST_USER_AppState; + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void host_user_init(void); +extern void host_user_denint(void); +extern void host_user_devattached(void); +extern void host_user_devreset(void); +extern void host_user_devdisconn(void); +extern void host_user_overcurrent(void); +extern void host_user_devspddetected(uint8_t DeviceSpeed); +extern void host_user_devdescavailable(void *DeviceDesc); +extern void host_user_devaddrdistributed(void); +extern void host_user_cfgdescavailable(usb_host_cfgdesc_typedef *cfgDesc, + usb_host_itfdesc_typedef *itfDesc, + USB_HOST_EPDesc_TypeDef *epDesc); +extern void host_user_mfcstring(void *ManufacturerString); +extern void host_user_productstring(void *ProductString); +extern void host_user_serialnum(void *SerialNumString); +extern void host_user_enumcompl(void); +extern HOST_USER_STATUS host_user_userinput(void); +extern void host_user_devunsupported(void); +extern void host_user_unrecoverederror(void); +extern int host_user_msc_app(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__USB_HOST_USER_H__*/ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ + + diff --git a/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/Kconfig b/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/Kconfig index a9a9da0f1..573bdc009 100644 --- a/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/Kconfig @@ -42,7 +42,7 @@ menu "imxrt1176-sbc feature" menu "config board peripheral" config MOUNT_SDCARD - bool "mount cd card" + bool "mount sd card" default n endmenu diff --git a/Ubiquitous/XiZi_IIoT/board/k210-emulator/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/k210-emulator/third_party_driver/spi/connect_spi.c index 1ddbda670..cb8f4afc6 100644 --- a/Ubiquitous/XiZi_IIoT/board/k210-emulator/third_party_driver/spi/connect_spi.c +++ b/Ubiquitous/XiZi_IIoT/board/k210-emulator/third_party_driver/spi/connect_spi.c @@ -391,9 +391,15 @@ static int BoardSpiDevBend(struct SpiDmaParam *spi_initparam) static struct SpiHardwareDevice spi_device2; memset(&spi_device2, 0, sizeof(struct SpiHardwareDevice)); - spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_2] = SPI_DEVICE_SLAVE_ID_2; - spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_2] = SPI1_CS2_PIN; - spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_2] = SPI_CHIP_SELECT_2; + static struct SpiSlaveParam spi_slaveparam2; + memset(&spi_slaveparam2, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam2.spi_slave_id = SPI_DEVICE_SLAVE_ID_2; + spi_slaveparam2.spi_cs_gpio_pin = SPI1_CS2_PIN; + spi_slaveparam2.spi_cs_select_id = SPI_CHIP_SELECT_2; + + spi_device2.spi_param.spi_dma_param = spi_initparam; + spi_device2.spi_param.spi_slave_param = &spi_slaveparam2; spi_device2.spi_dev_done = &(spi_dev_done); @@ -414,9 +420,15 @@ static int BoardSpiDevBend(struct SpiDmaParam *spi_initparam) static struct SpiHardwareDevice spi_device3; memset(&spi_device3, 0, sizeof(struct SpiHardwareDevice)); - spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_3] = SPI_DEVICE_SLAVE_ID_3; - spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_3] = SPI1_CS3_PIN; - spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_3] = SPI_CHIP_SELECT_3; + static struct SpiSlaveParam spi_slaveparam3; + memset(&spi_slaveparam3, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam3.spi_slave_id = SPI_DEVICE_SLAVE_ID_3; + spi_slaveparam3.spi_cs_gpio_pin = SPI1_CS3_PIN; + spi_slaveparam3.spi_cs_select_id = SPI_CHIP_SELECT_3; + + spi_device3.spi_param.spi_dma_param = spi_initparam; + spi_device3.spi_param.spi_slave_param = &spi_slaveparam3; spi_device3.spi_dev_done = &(spi_dev_done); diff --git a/Ubiquitous/XiZi_IIoT/board/kd233/Kconfig b/Ubiquitous/XiZi_IIoT/board/kd233/Kconfig index 6eb98a869..ea5ee1580 100644 --- a/Ubiquitous/XiZi_IIoT/board/kd233/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/kd233/Kconfig @@ -46,7 +46,7 @@ menu "kd233 feature" menu "config board peripheral" config MOUNT_SDCARD - bool "mount cd card" + bool "mount sd card" default n select BSP_USING_SPI select BSP_USING_SPI1 diff --git a/Ubiquitous/XiZi_IIoT/board/kd233/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/kd233/third_party_driver/spi/connect_spi.c index 2e74711eb..6a8148b7d 100644 --- a/Ubiquitous/XiZi_IIoT/board/kd233/third_party_driver/spi/connect_spi.c +++ b/Ubiquitous/XiZi_IIoT/board/kd233/third_party_driver/spi/connect_spi.c @@ -393,9 +393,15 @@ static int BoardSpiDevBend(struct SpiDmaParam *spi_initparam) static struct SpiHardwareDevice spi_device2; memset(&spi_device2, 0, sizeof(struct SpiHardwareDevice)); - spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_2] = SPI_DEVICE_SLAVE_ID_2; - spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_2] = SPI1_CS2_PIN; - spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_2] = SPI_CHIP_SELECT_2; + static struct SpiSlaveParam spi_slaveparam2; + memset(&spi_slaveparam2, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam2.spi_slave_id = SPI_DEVICE_SLAVE_ID_2; + spi_slaveparam2.spi_cs_gpio_pin = SPI1_CS2_PIN; + spi_slaveparam2.spi_cs_select_id = SPI_CHIP_SELECT_2; + + spi_device2.spi_param.spi_dma_param = spi_initparam; + spi_device2.spi_param.spi_slave_param = &spi_slaveparam2; spi_device2.spi_dev_done = &(spi_dev_done); @@ -416,9 +422,15 @@ static int BoardSpiDevBend(struct SpiDmaParam *spi_initparam) static struct SpiHardwareDevice spi_device3; memset(&spi_device3, 0, sizeof(struct SpiHardwareDevice)); - spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_3] = SPI_DEVICE_SLAVE_ID_3; - spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_3] = SPI1_CS3_PIN; - spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_3] = SPI_CHIP_SELECT_3; + static struct SpiSlaveParam spi_slaveparam3; + memset(&spi_slaveparam3, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam3.spi_slave_id = SPI_DEVICE_SLAVE_ID_3; + spi_slaveparam3.spi_cs_gpio_pin = SPI1_CS3_PIN; + spi_slaveparam3.spi_cs_select_id = SPI_CHIP_SELECT_3; + + spi_device3.spi_param.spi_dma_param = spi_initparam; + spi_device3.spi_param.spi_slave_param = &spi_slaveparam3; spi_device3.spi_dev_done = &(spi_dev_done); diff --git a/Ubiquitous/XiZi_IIoT/board/ok1052-c/Kconfig b/Ubiquitous/XiZi_IIoT/board/ok1052-c/Kconfig index 55da0eb1b..d70794d68 100644 --- a/Ubiquitous/XiZi_IIoT/board/ok1052-c/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/ok1052-c/Kconfig @@ -42,7 +42,10 @@ menu "ok1052-c feature" menu "config board peripheral" config MOUNT_SDCARD - bool "mount cd card" + bool + default n + config MOUNT_USB + bool default n endmenu diff --git a/Ubiquitous/XiZi_IIoT/board/ok1052-c/board.c b/Ubiquitous/XiZi_IIoT/board/ok1052-c/board.c index 5b1174a39..d891bfd50 100644 --- a/Ubiquitous/XiZi_IIoT/board/ok1052-c/board.c +++ b/Ubiquitous/XiZi_IIoT/board/ok1052-c/board.c @@ -59,6 +59,10 @@ extern int ExtSramInit(void); #include #endif +#ifdef BSP_USING_USB +#include +#endif + #ifdef BSP_USING_ADC #include #endif @@ -693,5 +697,11 @@ void InitBoardHardware() Imxrt1052HwSdioInit(); #endif +#ifdef BSP_USING_USB +#ifdef BSP_USING_NXP_USBH + Imxrt1052HwUsbHostInit(); +#endif +#endif + } diff --git a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/sdio/Kconfig b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/sdio/Kconfig index c2ceb303d..5c0855bad 100644 --- a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/sdio/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/sdio/Kconfig @@ -12,7 +12,7 @@ if BSP_USING_SDIO default "sdio_dev" config MOUNT_SDCARD_FS - bool "mount cd card file system" + bool "mount sd card file system" default n select MOUNT_SDCARD diff --git a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/usb/Kconfig b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/usb/Kconfig index a1f439ca9..eee8330b9 100644 --- a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/usb/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/usb/Kconfig @@ -11,5 +11,15 @@ config BSP_USING_NXP_USBH config USB_DEVICE_NAME string "usb bus device name" default "usb_dev" + config MOUNT_USB_FS + bool "mount usb file system" + default y + select MOUNT_USB + + if MOUNT_USB_FS + config MOUNT_USB_FS_TYPE + int "choose file system type : FATFS(0) LWEXT4(3)" + default 0 + endif endif diff --git a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/usb/connect_usb.c b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/usb/connect_usb.c index 28d4320f2..cdff41df4 100644 --- a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/usb/connect_usb.c +++ b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/usb/connect_usb.c @@ -28,13 +28,14 @@ Modification: #include #include -#define BSP_USING_NXP_USBH #ifdef BSP_USING_NXP_USBH /*! @brief USB host msd command instance global variable */ extern usb_host_msd_command_instance_t g_MsdCommandInstance; usb_host_handle g_HostHandle; +static void UsbHostTask(void* parameter); + extern usb_status_t USB_HostMsdReadApi(usb_host_msd_command_instance_t *msdCommandInstance, uint8_t *buffer, uint32_t pos, uint32_t block_size, uint32_t block_num); extern usb_status_t USB_HostMsdWriteApi(usb_host_msd_command_instance_t *msdCommandInstance, const uint8_t *buffer, uint32_t pos, uint32_t block_size, uint32_t block_num); @@ -149,6 +150,22 @@ void UsbUnmountFileSystem() { UnmountFileSystem(UDISK_MOUNTPOINT); } + +#ifdef MOUNT_USB +int MountUsb(void) +{ + int32 usb_host_task = 0; + usb_host_task = KTaskCreate("usbh", UsbHostTask, NONE, + USB_HOST_STACK_SIZE, 8); + if(usb_host_task < 0) { + KPrintf("usb_host_task create failed ...%s %d.\n", __FUNCTION__,__LINE__); + return ERROR; + } + + StartupKTask(usb_host_task); + return 0; +} +#endif #endif static uint32 UsbHostOpen(void *dev) @@ -259,7 +276,6 @@ static int BoardUsbDevBend(void) int Imxrt1052HwUsbHostInit(void) { x_err_t ret = EOK; - int32 usb_host_task = 0; static struct UsbBus usb_bus; memset(&usb_bus, 0, sizeof(struct UsbBus)); @@ -281,15 +297,6 @@ int Imxrt1052HwUsbHostInit(void) return ERROR; } - usb_host_task = KTaskCreate("usbh", UsbHostTask, NONE, - USB_HOST_STACK_SIZE, 8); - if(usb_host_task < 0) { - KPrintf("usb_host_task create failed ...%s %d.\n", __FUNCTION__,__LINE__); - return ERROR; - } - - StartupKTask(usb_host_task); - return ret; } diff --git a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/Kconfig b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/Kconfig index b7f97a747..179ebeadd 100644 --- a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/Kconfig @@ -33,6 +33,14 @@ menu "stm32f407-st-discovery feature" default 0x20000000 endmenu + menu "config board peripheral" + config MOUNT_SDCARD + bool + default n + config MOUNT_USB + bool + default n + endmenu endmenu endmenu diff --git a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/board.c b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/board.c index f01d158d1..12d5289d8 100644 --- a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/board.c +++ b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/board.c @@ -50,6 +50,7 @@ extern int Stm32HwRtcInit(); extern int HwSdioInit(); extern int Stm32HwAdcInit(void); extern int Stm32HwDacInit(void); +extern int Stm32HwUsbInit(void); #ifdef BSP_USING_LWIP extern int ETH_BSP_Config(); #endif @@ -139,6 +140,11 @@ struct InitSequenceDesc _board_init[] = #ifdef BSP_USING_SDIO {"hw sdcard init", HwSdioInit}, #endif +#ifdef BSP_USING_USB +#ifdef BSP_USING_STM32_USBH + { "hw usb", Stm32HwUsbInit }, +#endif +#endif #ifdef BSP_USING_ADC {"hw adc init", Stm32HwAdcInit}, #endif diff --git a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/spi/connect_spi.c index be515a41a..348807df9 100644 --- a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/spi/connect_spi.c +++ b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/spi/connect_spi.c @@ -110,7 +110,7 @@ static x_err_t Stm32SpiInit(struct Stm32Spi *spi_drv, struct SpiMasterParam *cfg SPI_InitTypeDef *spi_init = &spi_drv->init; - if (cfg->spi_work_mode & DEV_SPI_SLAVE){ + if (cfg->spi_work_mode & SPI_DEV_SLAVE){ spi_init->SPI_Mode = SPI_Mode_Slave; } else{ diff --git a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/usb/Kconfig b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/usb/Kconfig index 69d2536d9..746ee30e7 100644 --- a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/usb/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/usb/Kconfig @@ -1,6 +1,7 @@ config BSP_USING_STM32_USBH bool "Using usb host" - default y + default n + if BSP_USING_STM32_USBH config USB_BUS_NAME string "usb bus name" default "usb" @@ -9,4 +10,15 @@ config BSP_USING_STM32_USBH default "usb_drv" config USB_DEVICE_NAME string "usb bus device name" - default "usb_dev" \ No newline at end of file + default "usb_dev" + config MOUNT_USB_FS + bool "mount usb file system" + default y + select MOUNT_USB + + if MOUNT_USB_FS + config MOUNT_USB_FS_TYPE + int "choose file system type : FATFS(0) LWEXT4(3)" + default 0 + endif + endif diff --git a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/usb/connect_usb.c b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/usb/connect_usb.c index eb10628cf..c7fdd28a0 100644 --- a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/usb/connect_usb.c +++ b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/usb/connect_usb.c @@ -27,6 +27,14 @@ uint32 UdiskRead_new_api(void *dev, struct BusBlockReadParam *read_param); uint32 UdiskWirte_new_api(void *dev, struct BusBlockWriteParam *write_param); +#ifdef MOUNT_USB +int MountUsb(void) +{ + STM32USBHostRegister(); + return 0; +} +#endif + static uint32 UdiskOpenNewApi(void *dev) { return EOK; diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/Kconfig index 9c7c7989e..faa887906 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/Kconfig @@ -42,7 +42,10 @@ menu "xidatong-arm32 feature" menu "config board peripheral" config MOUNT_SDCARD - bool "mount sd card" + bool + default n + config MOUNT_USB + bool default n endmenu diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c index 7c4e83381..1a64fc4f2 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c @@ -56,6 +56,10 @@ Modification: #include #endif +#ifdef BSP_USING_USB +#include +#endif + #ifdef BSP_USING_WDT #include #endif @@ -303,6 +307,12 @@ struct InitSequenceDesc _board_init[] = { "sdio", Imxrt1052HwSdioInit }, #endif +#ifdef BSP_USING_USB +#ifdef BSP_USING_NXP_USBH + { "nxp hw usb", Imxrt1052HwUsbHostInit }, +#endif +#endif + #ifdef BSP_USING_I2C { "hw_i2c", Imxrt1052HwI2cInit }, #endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/sdio/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/sdio/Kconfig index c2ceb303d..5c0855bad 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/sdio/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/sdio/Kconfig @@ -12,7 +12,7 @@ if BSP_USING_SDIO default "sdio_dev" config MOUNT_SDCARD_FS - bool "mount cd card file system" + bool "mount sd card file system" default n select MOUNT_SDCARD diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/usb/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/usb/Kconfig index a1f439ca9..eee8330b9 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/usb/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/usb/Kconfig @@ -11,5 +11,15 @@ config BSP_USING_NXP_USBH config USB_DEVICE_NAME string "usb bus device name" default "usb_dev" + config MOUNT_USB_FS + bool "mount usb file system" + default y + select MOUNT_USB + + if MOUNT_USB_FS + config MOUNT_USB_FS_TYPE + int "choose file system type : FATFS(0) LWEXT4(3)" + default 0 + endif endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/usb/connect_usb.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/usb/connect_usb.c index 717659f9a..945440aef 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/usb/connect_usb.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/usb/connect_usb.c @@ -28,13 +28,14 @@ Modification: #include #include -#define BSP_USING_NXP_USBH #ifdef BSP_USING_NXP_USBH /*! @brief USB host msd command instance global variable */ extern usb_host_msd_command_instance_t g_MsdCommandInstance; usb_host_handle g_HostHandle; +static void UsbHostTask(void* parameter); + extern usb_status_t USB_HostMsdReadApi(usb_host_msd_command_instance_t *msdCommandInstance, uint8_t *buffer, uint32_t pos, uint32_t block_size, uint32_t block_num); extern usb_status_t USB_HostMsdWriteApi(usb_host_msd_command_instance_t *msdCommandInstance, const uint8_t *buffer, uint32_t pos, uint32_t block_size, uint32_t block_num); @@ -149,6 +150,22 @@ void UsbUnmountFileSystem() { UnmountFileSystem(UDISK_MOUNTPOINT); } + +#ifdef MOUNT_USB +int MountUsb(void) +{ + int32 usb_host_task = 0; + usb_host_task = KTaskCreate("usbh", UsbHostTask, NONE, + USB_HOST_STACK_SIZE, 8); + if(usb_host_task < 0) { + KPrintf("usb_host_task create failed ...%s %d.\n", __FUNCTION__,__LINE__); + return ERROR; + } + + StartupKTask(usb_host_task); + return 0; +} +#endif #endif static uint32 UsbHostOpen(void *dev) @@ -259,7 +276,6 @@ static int BoardUsbDevBend(void) int Imxrt1052HwUsbHostInit(void) { x_err_t ret = EOK; - int32 usb_host_task = 0; static struct UsbBus usb_bus; memset(&usb_bus, 0, sizeof(struct UsbBus)); @@ -281,15 +297,6 @@ int Imxrt1052HwUsbHostInit(void) return ERROR; } - usb_host_task = KTaskCreate("usbh", UsbHostTask, NONE, - USB_HOST_STACK_SIZE, 8); - if(usb_host_task < 0) { - KPrintf("usb_host_task create failed ...%s %d.\n", __FUNCTION__,__LINE__); - return ERROR; - } - - StartupKTask(usb_host_task); - return ret; } diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/Kconfig index a52319e9c..0131b2fe7 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/Kconfig @@ -37,7 +37,7 @@ menu "xidatong-riscv64 feature" menu "config board peripheral" config MOUNT_SDCARD - bool "mount cd card" + bool "mount sd card" default n config MOUNT_USB bool "mount usb" diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c index b6b365a6c..42ee200ce 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c @@ -70,7 +70,7 @@ extern int HwWdtInit(void); * @description: Mount USB * @return 0 */ -int MountUSB(void) +int MountUsb(void) { if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, FSTYPE_CH376, "/") == 0) KPrintf("usb mount to '/'\n"); diff --git a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/Kconfig b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/Kconfig index 98ba98b3b..410ff0272 100644 --- a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/Kconfig @@ -42,7 +42,10 @@ menu "xiwangtong-arm32 feature" menu "config board peripheral" config MOUNT_SDCARD - bool "mount sd card" + bool + default n + config MOUNT_USB + bool default n endmenu diff --git a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/board.c b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/board.c index 014925cd8..165a7025c 100644 --- a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/board.c +++ b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/board.c @@ -56,6 +56,10 @@ Modification: #include #endif +#ifdef BSP_USING_USB +#include +#endif + #ifdef BSP_USING_WDT #include #endif @@ -303,6 +307,12 @@ struct InitSequenceDesc _board_init[] = { "sdio", Imxrt1052HwSdioInit }, #endif +#ifdef BSP_USING_USB +#ifdef BSP_USING_NXP_USBH + { "nxp hw usb", Imxrt1052HwUsbHostInit }, +#endif +#endif + #ifdef BSP_USING_I2C { "hw_i2c", Imxrt1052HwI2cInit }, #endif diff --git a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/sdio/Kconfig b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/sdio/Kconfig index c2ceb303d..5c0855bad 100644 --- a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/sdio/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/sdio/Kconfig @@ -12,7 +12,7 @@ if BSP_USING_SDIO default "sdio_dev" config MOUNT_SDCARD_FS - bool "mount cd card file system" + bool "mount sd card file system" default n select MOUNT_SDCARD diff --git a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/usb/Kconfig b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/usb/Kconfig index a1f439ca9..eee8330b9 100644 --- a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/usb/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/usb/Kconfig @@ -11,5 +11,15 @@ config BSP_USING_NXP_USBH config USB_DEVICE_NAME string "usb bus device name" default "usb_dev" + config MOUNT_USB_FS + bool "mount usb file system" + default y + select MOUNT_USB + + if MOUNT_USB_FS + config MOUNT_USB_FS_TYPE + int "choose file system type : FATFS(0) LWEXT4(3)" + default 0 + endif endif diff --git a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/usb/connect_usb.c b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/usb/connect_usb.c index 536e52db3..dde0fab92 100644 --- a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/usb/connect_usb.c +++ b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/usb/connect_usb.c @@ -28,13 +28,14 @@ Modification: #include #include -#define BSP_USING_NXP_USBH #ifdef BSP_USING_NXP_USBH /*! @brief USB host msd command instance global variable */ extern usb_host_msd_command_instance_t g_MsdCommandInstance; usb_host_handle g_HostHandle; +static void UsbHostTask(void* parameter); + extern usb_status_t USB_HostMsdReadApi(usb_host_msd_command_instance_t *msdCommandInstance, uint8_t *buffer, uint32_t pos, uint32_t block_size, uint32_t block_num); extern usb_status_t USB_HostMsdWriteApi(usb_host_msd_command_instance_t *msdCommandInstance, const uint8_t *buffer, uint32_t pos, uint32_t block_size, uint32_t block_num); @@ -149,6 +150,22 @@ void UsbUnmountFileSystem() { UnmountFileSystem(UDISK_MOUNTPOINT); } + +#ifdef MOUNT_USB +int MountUsb(void) +{ + int32 usb_host_task = 0; + usb_host_task = KTaskCreate("usbh", UsbHostTask, NONE, + USB_HOST_STACK_SIZE, 8); + if(usb_host_task < 0) { + KPrintf("usb_host_task create failed ...%s %d.\n", __FUNCTION__,__LINE__); + return ERROR; + } + + StartupKTask(usb_host_task); + return 0; +} +#endif #endif static uint32 UsbHostOpen(void *dev) @@ -259,7 +276,6 @@ static int BoardUsbDevBend(void) int Imxrt1052HwUsbHostInit(void) { x_err_t ret = EOK; - int32 usb_host_task = 0; static struct UsbBus usb_bus; memset(&usb_bus, 0, sizeof(struct UsbBus)); @@ -281,15 +297,6 @@ int Imxrt1052HwUsbHostInit(void) return ERROR; } - usb_host_task = KTaskCreate("usbh", UsbHostTask, NONE, - USB_HOST_STACK_SIZE, 8); - if(usb_host_task < 0) { - KPrintf("usb_host_task create failed ...%s %d.\n", __FUNCTION__,__LINE__); - return ERROR; - } - - StartupKTask(usb_host_task); - return ret; } diff --git a/Ubiquitous/XiZi_IIoT/kernel/include/xs_init.h b/Ubiquitous/XiZi_IIoT/kernel/include/xs_init.h index 09e813178..8a40631c3 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/include/xs_init.h +++ b/Ubiquitous/XiZi_IIoT/kernel/include/xs_init.h @@ -44,7 +44,7 @@ extern int Lwext4Init(void); extern int LibcSystemInit(void); extern int RtcNtpSyncInit(void); extern int MountSDCard(void); -extern int MountUSB(void); +extern int MountUsb(void); extern int DfsMountTable(void); extern int userShellInit(void); extern int STM32USBHostRegister(void); diff --git a/Ubiquitous/XiZi_IIoT/kernel/kernel_test/Kconfig b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/Kconfig index 4a9ae18ee..0de9621a0 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/kernel_test/Kconfig +++ b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/Kconfig @@ -62,4 +62,7 @@ menuconfig KERNEL_TEST config KERNEL_TEST_SPI_FLASH bool "Config test spi flash" default n + config KERNEL_TEST_SOFT_SPI_SD + bool "Config test soft spi sd" + default n endif diff --git a/Ubiquitous/XiZi_IIoT/kernel/thread/init.c b/Ubiquitous/XiZi_IIoT/kernel/thread/init.c index 7e7bf03d8..84ca8c15a 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/thread/init.c +++ b/Ubiquitous/XiZi_IIoT/kernel/thread/init.c @@ -113,18 +113,11 @@ struct InitSequenceDesc components_init[] = }; struct InitSequenceDesc env_init[] = { -#ifdef BSP_USING_STM32_USBH - { "STM32USBHostRegister", STM32USBHostRegister }, - { "hw usb", Stm32HwUsbInit }, -#endif -#ifdef BSP_USING_NXP_USBH - { "nxp hw usb", Imxrt1052HwUsbHostInit }, -#endif #ifdef MOUNT_SDCARD { "MountSDCard", MountSDCard }, #endif #ifdef MOUNT_USB - { "MountUSB", MountUSB }, + { "MountUsb", MountUsb }, #endif #ifdef FS_VFS_MNTTABLE { "DfsMountTable", DfsMountTable }, @@ -164,7 +157,6 @@ void EnvInitKTask(void *parameter) _InitSubCmpts(components_init); _InitSubCmpts(env_init); ENABLE_INTERRUPT(lock); - _InitSubCmpts(communication_init); #ifdef ARCH_SMP diff --git a/Ubiquitous/XiZi_IIoT/path_kernel.mk b/Ubiquitous/XiZi_IIoT/path_kernel.mk index b5ff610c6..3731ae559 100755 --- a/Ubiquitous/XiZi_IIoT/path_kernel.mk +++ b/Ubiquitous/XiZi_IIoT/path_kernel.mk @@ -400,6 +400,12 @@ KERNELPATHS += \ -I$(BSP_ROOT)/include \ -I$(BSP_ROOT)/third_party_driver/include \ -I$(BSP_ROOT)/third_party_driver/CMSIS/include \ + -I$(BSP_ROOT)/third_party_driver/spi/third_party_spi_lora/sx12xx/inc \ + -I$(BSP_ROOT)/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio \ + -I$(BSP_ROOT)/third_party_driver/usb/hc32_usb_driver \ + -I$(BSP_ROOT)/third_party_driver/usb/hc32_usb_driver/usb_host_lib \ + -I$(BSP_ROOT)/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc \ + -I$(BSP_ROOT)/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core \ -I$(KERNEL_ROOT)/include # endif diff --git a/Ubiquitous/XiZi_IIoT/resources/include/dev_spi.h b/Ubiquitous/XiZi_IIoT/resources/include/dev_spi.h index f0bb6fd7c..75dc7d038 100644 --- a/Ubiquitous/XiZi_IIoT/resources/include/dev_spi.h +++ b/Ubiquitous/XiZi_IIoT/resources/include/dev_spi.h @@ -28,27 +28,27 @@ extern "C" { #endif #define SPI_MAX_CLOCK 40000000 -#define spi_device_max_num 4 +#define spi_device_max_num 4 -#define SPI_LINE_CPHA (1<<0) -#define SPI_LINE_CPOL (1<<1) +#define SPI_LINE_CPHA (1 << 0) +#define SPI_LINE_CPOL (1 << 1) -#define SPI_LSB (0<<2) -#define SPI_MSB (1<<2) +#define SPI_LSB (0 << 2) +#define SPI_MSB (1 << 2) -#define SPI_MASTER (0<<3) -#define DEV_SPI_SLAVE (1<<3) +#define SPI_DEV_MASTER (0 << 3) +#define SPI_DEV_SLAVE (1 << 3) -#define SPI_MODE_0 (0 | 0) -#define SPI_MODE_1 (0 | SPI_LINE_CPHA) -#define SPI_MODE_2 (SPI_LINE_CPOL | 0) -#define SPI_MODE_3 (SPI_LINE_CPOL | SPI_LINE_CPHA) -#define SPI_MODE_MASK (SPI_LINE_CPHA | SPI_LINE_CPOL | SPI_MSB) +#define SPI_MODE_0 (0 | 0) +#define SPI_MODE_1 (0 | SPI_LINE_CPHA) +#define SPI_MODE_2 (SPI_LINE_CPOL | 0) +#define SPI_MODE_3 (SPI_LINE_CPOL | SPI_LINE_CPHA) +#define SPI_MODE_MASK (SPI_LINE_CPHA | SPI_LINE_CPOL | SPI_MSB) -#define SPI_CS_HIGH (1<<4) -#define SPI_NO_CS (1<<5) -#define SPI_3WIRE (1<<6) -#define SPI_READY (1<<7) +#define SPI_CS_HIGH (1 << 4) +#define SPI_NO_CS (1 << 5) +#define SPI_3WIRE (1 << 6) +#define SPI_READY (1 << 7) struct SpiDataStandard { @@ -83,9 +83,10 @@ struct SpiDmaParam struct SpiSlaveParam { - uint8 spi_slave_id; - uint8 spi_cs_gpio_pin; - uint8 spi_cs_select_id; + uint32 spi_slave_id; + uint32 spi_cs_gpio_pin; + uint32 spi_cs_gpio_port; + uint32 spi_cs_select_id; }; typedef struct diff --git a/Ubiquitous/XiZi_IIoT/resources/include/device.h b/Ubiquitous/XiZi_IIoT/resources/include/device.h index 5c2d49a30..cf0e0a2ed 100644 --- a/Ubiquitous/XiZi_IIoT/resources/include/device.h +++ b/Ubiquitous/XiZi_IIoT/resources/include/device.h @@ -53,9 +53,11 @@ #include #include #ifdef RESOURCES_USB_HOST +#ifdef BSP_USING_STM32_USBH #include #endif #endif +#endif #ifdef RESOURCES_SERIAL #include diff --git a/Ubiquitous/XiZi_IIoT/resources/include/sd_spi.h b/Ubiquitous/XiZi_IIoT/resources/include/sd_spi.h index 387d26ae5..db9df22a2 100644 --- a/Ubiquitous/XiZi_IIoT/resources/include/sd_spi.h +++ b/Ubiquitous/XiZi_IIoT/resources/include/sd_spi.h @@ -28,11 +28,11 @@ extern "C" { #endif -#define SPI_SD_FREQUENCY 400000 +#define SPI_SD_FREQUENCY 400000 #define SPI_SD_TIMEOUT_NUM 100 #define SD_CMD_RESPONE_LENGTH 5 #define SD_CMD_CSD_LENGTH 16 -#define SD_BLOCK_LENGTH 512 +#define SD_BLOCK_LENGTH 512 #define SD_TIMEOUT(cnt, time) \ do \ diff --git a/Ubiquitous/XiZi_IIoT/resources/spi/sd_card_spi/sd_spi.c b/Ubiquitous/XiZi_IIoT/resources/spi/sd_card_spi/sd_spi.c index fa905bc2b..6eba43464 100644 --- a/Ubiquitous/XiZi_IIoT/resources/spi/sd_card_spi/sd_spi.c +++ b/Ubiquitous/XiZi_IIoT/resources/spi/sd_card_spi/sd_spi.c @@ -96,9 +96,8 @@ static uint32 SdSendCmdByte(SpiSdDeviceType spi_sd_dev, struct SdCmdParam *sd_cm if ((SD_CMD_17 == sd_cmd_param->sd_cmd_type) || (SD_CMD_18 == sd_cmd_param->sd_cmd_type)) { MdelayKTask(100); } - SD_TIMEOUT(start_time, 2 * SPI_SD_TIMEOUT_NUM); - }while((0 != (read[0] & 0x80))); + }while(0 != (read[0] & 0x80)); switch (sd_cmd_param->sd_respone_type) { @@ -672,7 +671,7 @@ static uint32 SdHwReadCSD(SpiSdDeviceType spi_sd_dev) g_sd_cmd_param.sd_cmd_type = SD_CMD_9; g_sd_cmd_param.sd_cmd_args = 0x00; g_sd_cmd_param.sd_cmd_crc = 0x00; - g_sd_cmd_param.sd_respone_type = SD_RESPONE_2; + g_sd_cmd_param.sd_respone_type = SD_RESPONE_1; /*pull down the cs pin*/ SpiDevConfigureCs(&spi_sd_dev->spi_dev->haldev, 1, 0); @@ -691,7 +690,7 @@ static uint32 SdHwReadCSD(SpiSdDeviceType spi_sd_dev) if (0xFE != g_sd_cmd_param.sd_respone_data[1]) { /*Step2 : SPI write data 0xFF until read 0xFE*/ uint8 data = 0xFF; - uint8 read_spi; + uint8 read_spi=0x00; uint32 start_time; write_param.buffer = (void *)&data; @@ -705,7 +704,6 @@ static uint32 SdHwReadCSD(SpiSdDeviceType spi_sd_dev) { BusDevWriteData(&spi_sd_dev->spi_dev->haldev, &write_param); BusDevReadData(&spi_sd_dev->spi_dev->haldev, &read_param); - SD_TIMEOUT(start_time, 10 * SPI_SD_TIMEOUT_NUM); }while(0xFE != read_spi); } @@ -768,7 +766,7 @@ static uint32 SdReadSingleBlock(SpiSdDeviceType spi_sd_dev, uint32 id, uint8 *re return ERROR; } - /*Step2 : SPI write data 0xFF until read 0xFE*/ + /*Step2 : SPI read until 0xFE*/ uint8 data = 0xFF; uint8 read[2]; uint32 start_time; @@ -782,7 +780,6 @@ static uint32 SdReadSingleBlock(SpiSdDeviceType spi_sd_dev, uint32 id, uint8 *re do { - BusDevWriteData(&spi_sd_dev->spi_dev->haldev, &write_param); BusDevReadData(&spi_sd_dev->spi_dev->haldev, &read_param); SD_TIMEOUT(start_time, 100 * SPI_SD_TIMEOUT_NUM); @@ -1077,6 +1074,7 @@ static uint32 SdWriteMultiBlock(SpiSdDeviceType spi_sd_dev, uint32 id, const voi } /*Step8 : SPI write 0xFD, multi block write data done*/ + data = 0xFD; write_param.buffer = (void *)&data; write_param.size = 1; BusDevWriteData(&spi_sd_dev->spi_dev->haldev, &write_param);