From d3836f1a6f1a86fecb239b1c3c6e25d73a31be55 Mon Sep 17 00:00:00 2001 From: wuzheng Date: Wed, 9 Nov 2022 19:23:12 +0800 Subject: [PATCH 1/7] softspi driver and its app test --- APP_Framework/Applications/app_test/Kconfig | 13 + APP_Framework/Applications/app_test/Makefile | 4 + .../Applications/app_test/test_adc.c | 2 +- .../Applications/app_test/test_softspi_sd.c | 31 ++ .../XiZi_IIoT/board/edu-riscv64/board.c | 44 ++- .../edu-riscv64/third_party_driver/Kconfig | 10 + .../edu-riscv64/third_party_driver/Makefile | 4 + .../third_party_driver/gpio/drv_io_config.c | 8 +- .../include/connect_soft_spi.h | 14 + .../include/drv_io_config.h | 13 + .../third_party_driver/soft_spi/Kconfig | 47 +++ .../third_party_driver/soft_spi/Makefile | 3 + .../soft_spi/connect_soft_spi.c | 292 ++++++++++++++++++ .../XiZi_IIoT/kernel/kernel_test/Kconfig | 3 + .../XiZi_IIoT/kernel/kernel_test/Makefile | 4 + .../XiZi_IIoT/kernel/kernel_test/test_main.c | 2 + .../kernel/kernel_test/test_softspi_sd.c | 105 +++++++ Ubiquitous/XiZi_IIoT/kernel/thread/init.c | 1 - .../XiZi_IIoT/resources/include/sd_spi.h | 4 +- .../resources/spi/sd_card_spi/sd_spi.c | 12 +- 20 files changed, 590 insertions(+), 26 deletions(-) create mode 100644 APP_Framework/Applications/app_test/test_softspi_sd.c create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_soft_spi.h create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Kconfig create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c create mode 100644 Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_softspi_sd.c diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index bffda4b64..91550632a 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -26,6 +26,17 @@ menu "test app" endif endif + menuconfig USER_TEST_SD + bool "Config test sd" + default n + if USER_TEST_SD + if ADD_XIZI_FETURES + config SD_FPATH + string "Set sd file path" + default "/sdcard_testfile" + endif + endif + config USER_TEST_SEMC bool "Config test semc sdram" default n @@ -33,5 +44,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..2d68c4cc4 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -25,6 +25,10 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_FILES += test_dac.c endif + ifeq ($(CONFIG_USER_TEST_SD),y) + SRC_FILES += test_softspi_sd.c + endif + ifeq ($(CONFIG_USER_TEST_SEMC),y) SRC_FILES += test_extsram.c 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_softspi_sd.c b/APP_Framework/Applications/app_test/test_softspi_sd.c new file mode 100644 index 000000000..c49e324fa --- /dev/null +++ b/APP_Framework/Applications/app_test/test_softspi_sd.c @@ -0,0 +1,31 @@ +#include +#include +#include + +#define MAX_READ_LENGTH 1000 + +// sd card here is loaded as "/" +void TestSD(void) +{ + //open the file in sdcard + int fd = open(SD_FPATH,O_RDWR|O_CREAT); + char filewords[MAX_READ_LENGTH]; + memset(filewords,0,MAX_READ_LENGTH); + + //read and write then close file + read(fd,filewords,MAX_READ_LENGTH); + printf("read data is \n%s\n",filewords); + const char *input_words = "these words are going to write in sdcard\n"; + write(fd,input_words,strlen(input_words)); + close(fd); + + //re-open the file and re-read the file + fd = open(SD_FPATH,O_RDWR); + read(fd,filewords,MAX_READ_LENGTH); + printf("read data is \n%s\n",filewords); + close(fd); + + return; +} + +PRIV_SHELL_CMD_FUNCTION(TestSD, a sdcard test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c index 6dd32085d..9074c6e26 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c @@ -44,10 +44,11 @@ Modification: #include "fpioa.h" #include "dmac.h" #include "connect_gpio.h" +#include "connect_soft_spi.h" -#if defined(FS_VFS) -#include -#endif +// #if defined(FS_VFS) +// #include +// #endif #define CPU0 (0) #define CPU1 (1) @@ -60,8 +61,8 @@ 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 /** @@ -78,23 +79,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) { @@ -183,10 +195,14 @@ struct InitSequenceDesc _board_init[] = #endif #ifdef BSP_USING_TOUCH {"touch", HwTouchInit }, +#endif +#ifdef BSP_USING_SOFT_SPI + {"soft_spi", HwSoftSPIInit }, #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..eed2fa64b 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 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..7494b84fe 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,8 @@ ifeq ($(CONFIG_BSP_USING_LCD),y) SRC_DIR += lcd endif +ifeq ($(CONFIG_BSP_USING_SOFT_SPI),y) + SRC_DIR += soft_spi +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..c92ebcce1 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 @@ -95,7 +95,13 @@ 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 }; 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/drv_io_config.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h index c61e62412..7e4e214b5 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,19 @@ enum HS_GPIO_CONFIG #define BSP_CH438_INT_PIN 35 #endif +#define BSP_USING_SOFT_SPI +#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 + extern int IoConfigInit(void); #endif 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..d52a83176 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Kconfig @@ -0,0 +1,47 @@ +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 + + config SOFT_SPI_READ_DELAY + int "read after millisecond" + default 1 + +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..d9af16d84 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c @@ -0,0 +1,292 @@ +#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;ispi_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;ispi_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/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/kernel_test/Makefile b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/Makefile index 1c4f0656a..ed3599ccb 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/kernel_test/Makefile +++ b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/Makefile @@ -92,4 +92,8 @@ ifeq ($(CONFIG_KERNEL_TEST_SPI_FLASH),y) SRC_FILES += test_spi_flash.c endif +ifeq ($(KERNEL_TEST_SOFT_SPI_SD),y) + SRC_FILES += test_softspi_sd.c +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_main.c b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_main.c index 18d6f85f0..33f15d9a9 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_main.c +++ b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_main.c @@ -118,6 +118,8 @@ int TestMain(int argc, char*argv[]) #ifdef KERNEL_TEST_REALTIME if (argc > 2) TestRealtime(argc-2, &argv[2]); +#endif +#ifdef KERNEL_TEST_SOFT_SPI_SD #endif default: break; diff --git a/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_softspi_sd.c b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_softspi_sd.c new file mode 100644 index 000000000..b07c8a672 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_softspi_sd.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2016-09-28 armink first version. + */ + +/** +* @file test_spi_flash.c +* @brief support to test spi flash function +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-05-17 +*/ + +/************************************************* +File name: test_spi_flash.c +Description: support spi flash function test +Others: add spi flash test cmd from SFUD/blob/master/demo/stm32f2xx_rtt/RT-Thread-2.1.0/components/drivers/spi/spi_flash_sfud.c + https://github.com/armink/SFUD/ +History: +1. Date: 2021-05-17 +Author: AIIT XUOS Lab +Modification: +1. support spi flash open, read and write function +*************************************************/ + +#include +#include +#include + +// void SDpen(void) +// { +// x_err_t ret = EOK; + +// ret=HwTFInit(); +// if (ret < 0) { +// KPrintf("open spi flash fd error %d\n", ret); +// } + +// KPrintf("Spi Flash init succeed\n"); + +// return; +// } + +// SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +// SDpen, SDpen, open spi flash device); + +// void SDRead(int argc, char *argv[]) +// { +// x_err_t ret = EOK; + +// } +// SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +// SDRead, SDRead, read data from spi flash device); + +// void SDWrite(int argc, char *argv[]) +// { +// x_err_t ret = EOK; +// x_size_t i, j = 0; +// uint32 addr; +// uint32 size; +// uint8 data[16]; + +// struct BusBlockWriteParam write_param; +// memset(&write_param, 0, sizeof(struct BusBlockWriteParam)); + +// memset(data, 0, 16); + +// if (argc < 3) { +// KPrintf("FlashWrite cmd format: FlashWrite addr data.\n"); +// return; +// } else { +// addr = strtol(argv[1], NULL, 0); +// size = argc - 2; + +// write_param.buffer = data; +// write_param.pos = addr; +// write_param.size = size; + +// if (data) { +// for (i = 0; i < size; i++) { +// data[i] = strtol(argv[2 + i], NULL, 0); +// } + +// ret = write(spi_flash_fd, &write_param, size); +// if (EOK == ret) { +// KPrintf("Write the %s flash data success. Start from 0x%08X, size is %ld.\n", +// SPI_FLASH_PATH, addr, size); +// KPrintf("Write data: "); +// for (i = 0; i < size; i++) { +// KPrintf("%d ", data[i]); +// } +// KPrintf(".\n"); +// } +// } else { +// KPrintf("SpiFlashWrite alloc write buffer failed!\n"); +// } +// } +// } +// SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +// SDWrite, SDWrite, write data to spi flash device); diff --git a/Ubiquitous/XiZi_IIoT/kernel/thread/init.c b/Ubiquitous/XiZi_IIoT/kernel/thread/init.c index 7e7bf03d8..332057b23 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/thread/init.c +++ b/Ubiquitous/XiZi_IIoT/kernel/thread/init.c @@ -164,7 +164,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/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); From b8cf052d493a0c512a4ecdb7d603d603cfa71458 Mon Sep 17 00:00:00 2001 From: wuzheng Date: Wed, 9 Nov 2022 20:45:44 +0800 Subject: [PATCH 2/7] test framework --- APP_Framework/Applications/app_test/Kconfig | 38 ++++++++++++++++--- APP_Framework/Applications/app_test/Makefile | 12 +++++- .../app_test/{test_softspi_sd.c => test_fs.c} | 2 +- .../Applications/app_test/test_gpio.c | 10 +++++ .../Applications/app_test/test_i2c.c | 9 +++++ .../Applications/app_test/test_loraE220.c | 0 .../Applications/app_test/test_rs485.c | 0 .../third_party_driver/gpio/drv_io_config.c | 10 +++++ .../third_party_driver/soft_spi/Kconfig | 4 -- 9 files changed, 73 insertions(+), 12 deletions(-) rename APP_Framework/Applications/app_test/{test_softspi_sd.c => test_fs.c} (98%) create mode 100644 APP_Framework/Applications/app_test/test_gpio.c create mode 100644 APP_Framework/Applications/app_test/test_i2c.c create mode 100644 APP_Framework/Applications/app_test/test_loraE220.c create mode 100644 APP_Framework/Applications/app_test/test_rs485.c diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index 91550632a..36653101a 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -26,14 +26,42 @@ menu "test app" endif endif - menuconfig USER_TEST_SD - bool "Config test sd" + menuconfig USER_TEST_FS + bool "Config test fs with sd or usb" default n - if USER_TEST_SD + if USER_TEST_FS if ADD_XIZI_FETURES config SD_FPATH - string "Set sd file path" - default "/sdcard_testfile" + 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_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/i2c_dev" endif endif diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index 2d68c4cc4..5d5a5fc52 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -25,8 +25,8 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_FILES += test_dac.c endif - ifeq ($(CONFIG_USER_TEST_SD),y) - SRC_FILES += test_softspi_sd.c + ifeq ($(CONFIG_USER_TEST_FS),y) + SRC_FILES += test_fs.c endif ifeq ($(CONFIG_USER_TEST_SEMC),y) @@ -37,5 +37,13 @@ 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 + include $(KERNEL_ROOT)/compiler.mk endif diff --git a/APP_Framework/Applications/app_test/test_softspi_sd.c b/APP_Framework/Applications/app_test/test_fs.c similarity index 98% rename from APP_Framework/Applications/app_test/test_softspi_sd.c rename to APP_Framework/Applications/app_test/test_fs.c index c49e324fa..4711d0198 100644 --- a/APP_Framework/Applications/app_test/test_softspi_sd.c +++ b/APP_Framework/Applications/app_test/test_fs.c @@ -15,7 +15,7 @@ void TestSD(void) //read and write then close file read(fd,filewords,MAX_READ_LENGTH); printf("read data is \n%s\n",filewords); - const char *input_words = "these words are going to write in sdcard\n"; + const char *input_words = "these words are going to write in fs\n"; write(fd,input_words,strlen(input_words)); close(fd); 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..2841cff50 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_gpio.c @@ -0,0 +1,10 @@ +#include +#include +#include + + +void TestGpio(void) +{ + +} + 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..d41a215e8 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_i2c.c @@ -0,0 +1,9 @@ +#include +#include +#include + + +void TestI2C(void) +{ + +} 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..e69de29bb 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..e69de29bb 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 c92ebcce1..ee1c55960 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 @@ -97,12 +97,22 @@ static struct io_config IOCONFIG(BSP_CH438_D6_PIN, HS_GPIO(FPIOA_CH438_D6)), 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_LED + IOCONFIG(BSP_LED_PIN,FUNC_GPIO5); +#endif + +#ifdef BSP_USING_KEY + IOCONFIG(BSP_KEY_PIN,FUNC_GPIO6); +#endif + }; static int PrintIoConfig() 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 index d52a83176..73b7f7c4f 100644 --- 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 @@ -38,10 +38,6 @@ if BSP_USING_SOFT_SPI config SOFT_SPI_CLK_DELAY int "clk in microsecond" default 0 - - config SOFT_SPI_READ_DELAY - int "read after millisecond" - default 1 endif From 00b39cdd55e1e34ee6a357cdac737822e701b5b9 Mon Sep 17 00:00:00 2001 From: wuzheng Date: Thu, 10 Nov 2022 10:20:20 +0800 Subject: [PATCH 3/7] gpio test sample for edu-riscv64 --- APP_Framework/Applications/app_test/test_fs.c | 47 +++++++++--- .../Applications/app_test/test_gpio.c | 71 +++++++++++++++++++ .../include/drv_io_config.h | 3 + 3 files changed, 113 insertions(+), 8 deletions(-) diff --git a/APP_Framework/Applications/app_test/test_fs.c b/APP_Framework/Applications/app_test/test_fs.c index 4711d0198..69e323666 100644 --- a/APP_Framework/Applications/app_test/test_fs.c +++ b/APP_Framework/Applications/app_test/test_fs.c @@ -5,27 +5,58 @@ #define MAX_READ_LENGTH 1000 // sd card here is loaded as "/" -void TestSD(void) +void TestFs(void) { //open the file in sdcard int fd = open(SD_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 - read(fd,filewords,MAX_READ_LENGTH); + 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); - const char *input_words = "these words are going to write in fs\n"; - write(fd,input_words,strlen(input_words)); - close(fd); + + 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(SD_FPATH,O_RDWR); - read(fd,filewords,MAX_READ_LENGTH); + 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); - close(fd); + err_flag = close(fd); + if(err_flag<0){ + printf("close failed,error:%d\n",err_flag); + return; + } return; } -PRIV_SHELL_CMD_FUNCTION(TestSD, a sdcard test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file +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 index 2841cff50..7d160ec95 100644 --- a/APP_Framework/Applications/app_test/test_gpio.c +++ b/APP_Framework/Applications/app_test/test_gpio.c @@ -2,9 +2,80 @@ #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.cmd = GPIO_CONFIG_MODE; + parameter.pin = BSP_KEY_PIN; + parameter.mode = GPIO_CFG_INPUT; + + 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; + } + + 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; + if(0>PrivWrite(pin_fd,&pin_led,NULL_PARAMETER)){ + printf("write pin fd error %d\n", pin_fd); + PrivClose(pin_fd); + return; + } + }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/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 7e4e214b5..a8950d63b 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 @@ -89,6 +89,9 @@ enum HS_GPIO_CONFIG #define BSP_SOFT_SPI_MIOS_PIN 25 #define BSP_SOFT_SPI_MSOI_PIN 27 #define BSP_SOFT_SPI_NCS_PIN 28 + +#define BSP_LED_PIN 29 +#define BSP_KEY_PIN 31 #endif extern int IoConfigInit(void); From e746639f8ac7e11c56095d9291227bade20f513c Mon Sep 17 00:00:00 2001 From: wuzheng Date: Fri, 11 Nov 2022 15:32:38 +0800 Subject: [PATCH 4/7] add edu-riscv64 lora example and fix name problem --- APP_Framework/Applications/app_test/Kconfig | 33 +++- APP_Framework/Applications/app_test/Makefile | 8 + APP_Framework/Applications/app_test/test_fs.c | 4 +- .../Applications/app_test/test_gpio.c | 16 +- .../Applications/app_test/test_loraE220.c | 155 +++++++++++++++ .../XiZi_IIoT/board/edu-riscv64/.defconfig | 20 +- .../XiZi_IIoT/board/edu-riscv64/board.c | 6 + .../include/drv_io_config.h | 11 +- .../soft_spi/connect_soft_spi.c | 181 +++++++++--------- 9 files changed, 319 insertions(+), 115 deletions(-) diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index 36653101a..3302d3596 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -31,7 +31,7 @@ menu "test app" default n if USER_TEST_FS if ADD_XIZI_FETURES - config SD_FPATH + config FPATH string "Set test file path" default "/test_file" endif @@ -53,6 +53,37 @@ menu "test app" 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" + 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_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_I2C select BSP_USING_I2C bool "Config test i2c" diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index 5d5a5fc52..ad0368c10 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -45,5 +45,13 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),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 + include $(KERNEL_ROOT)/compiler.mk endif diff --git a/APP_Framework/Applications/app_test/test_fs.c b/APP_Framework/Applications/app_test/test_fs.c index 69e323666..74d7493b6 100644 --- a/APP_Framework/Applications/app_test/test_fs.c +++ b/APP_Framework/Applications/app_test/test_fs.c @@ -8,7 +8,7 @@ void TestFs(void) { //open the file in sdcard - int fd = open(SD_FPATH,O_RDWR|O_CREAT); + int fd = open(FPATH,O_RDWR|O_CREAT); if(fd<0){ printf("fs fd open error:%d\n",fd); return; @@ -38,7 +38,7 @@ void TestFs(void) } //re-open the file and re-read the file - fd = open(SD_FPATH,O_RDWR); + fd = open(FPATH,O_RDWR); if(fd<0){ printf("fs fd open error:%d\n",fd); return; diff --git a/APP_Framework/Applications/app_test/test_gpio.c b/APP_Framework/Applications/app_test/test_gpio.c index 7d160ec95..42c353dbf 100644 --- a/APP_Framework/Applications/app_test/test_gpio.c +++ b/APP_Framework/Applications/app_test/test_gpio.c @@ -31,13 +31,9 @@ void TestGpio(void) } //config key pin in board - parameter.cmd = GPIO_CONFIG_MODE; parameter.pin = BSP_KEY_PIN; parameter.mode = GPIO_CFG_INPUT; - 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); @@ -61,19 +57,15 @@ void TestGpio(void) //led on if key pressed,or led off if(pin_key.val){ pin_led.val = GPIO_HIGH; - if(0>PrivWrite(pin_fd,&pin_led,NULL_PARAMETER)){ - printf("write pin fd error %d\n", pin_fd); - PrivClose(pin_fd); - return; - } }else{ pin_led.val = GPIO_LOW; - if(0>PrivWrite(pin_fd,&pin_led,NULL_PARAMETER)){ + } + + if(0>PrivWrite(pin_fd,&pin_led,NULL_PARAMETER)){ printf("write pin fd error %d\n", pin_fd); PrivClose(pin_fd); return; - } - } + } } } diff --git a/APP_Framework/Applications/app_test/test_loraE220.c b/APP_Framework/Applications/app_test/test_loraE220.c index e69de29bb..4ea400669 100644 --- a/APP_Framework/Applications/app_test/test_loraE220.c +++ b/APP_Framework/Applications/app_test/test_loraE220.c @@ -0,0 +1,155 @@ +#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 *agrv[]) +{ + 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; + struct PinStat pin_key; + 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_INPUT; + + ioctl_cfg.ioctl_driver_type = PIN_TYPE; + ioctl_cfg.args = (void *)&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.mode = GPIO_CFG_OUTPUT; + pin_param.pin = BSP_E220_M0_PIN; + 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 2.4kps + + 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); + } +} + +PRIV_SHELL_CMD_FUNCTION(TestLora, a lora test sample, PRIV_SHELL_CMD_MAIN_ATTR); 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 9074c6e26..924e3e9a3 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c @@ -184,6 +184,12 @@ struct InitSequenceDesc _board_init[] = #ifdef BSP_USING_I2C { "hw_i2c", HwI2cInit }, #endif +#ifdef BSP_USING_RTC + { "hw_uart", HwRTC }, +#endif +#ifdef BSP_USING_UART + { "hw_uart", HwUartInit }, +#endif #ifdef BSP_USING_SPI { "hw_spi", HwSpiInit }, #endif 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 a8950d63b..43b7723b1 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,7 +78,6 @@ enum HS_GPIO_CONFIG #define BSP_CH438_INT_PIN 35 #endif -#define BSP_USING_SOFT_SPI #ifdef BSP_USING_SOFT_SPI #define FPIOA_SOFT_SPI_SCK 26 #define FPIOA_SOFT_SPI_MIOS 25 @@ -90,10 +89,20 @@ enum HS_GPIO_CONFIG #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 extern int IoConfigInit(void); #endif 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 index d9af16d84..9cf961d40 100644 --- 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 @@ -12,22 +12,20 @@ #include #include - static x_err_t softSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *cfg) { - NULL_PARAM_CHECK(spi_drv ); - NULL_PARAM_CHECK(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 + // 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); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); + KPrintf("%s init done\n", SOFT_SPI_BUS_NAME); - return EOK; } @@ -43,118 +41,118 @@ static uint32 softSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_ switch (configure_info->configure_cmd) { case OPE_INT: - softSPIinit(spi_drv,configure_info); + softSPIinit(spi_drv, configure_info); break; case OPE_CFG: - break; + break; default: break; } - - return ret; + 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++) + 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 ) + 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); + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_LOW); } else { - gpiohs_set_pin(SOFT_SPI_MOSI,GPIO_PV_HIGH); + 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_HIGH); + usleep(SOFT_SPI_CLK_DELAY); } - gpiohs_set_pin(SOFT_SPI_SCK,GPIO_PV_LOW); + 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++) - { + for (i = 0; i < 8; i++) + { read_data = read_data << 1; - gpiohs_set_pin(SOFT_SPI_SCK,GPIO_PV_LOW); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); usleep(SOFT_SPI_CLK_DELAY); - gpiohs_set_pin(SOFT_SPI_SCK,GPIO_PV_HIGH); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH); usleep(SOFT_SPI_CLK_DELAY); - if(1==gpiohs_get_pin(SOFT_SPI_MISO)) + if (1 == gpiohs_get_pin(SOFT_SPI_MISO)) { - read_data = read_data | 0x01; - } + read_data = read_data | 0x01; + } } return read_data; } - /* 读写一个字节 */ -//this funcition is unverify until now! +// 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++) + for (i = 0; i < 8; i++) { - temp = ((data&0x80)==0x80)? 1:0; - data = data<<1; - read_data = read_data<<1; - if(temp == 0) + 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); + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_LOW); } else { - gpiohs_set_pin(SOFT_SPI_MOSI,GPIO_PV_HIGH); + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_HIGH); } usleep(SOFT_SPI_CLK_DELAY); - gpiohs_set_pin(SOFT_SPI_SCK,GPIO_PV_HIGH); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH); usleep(SOFT_SPI_CLK_DELAY); - if(gpiohs_get_pin(SOFT_SPI_MISO)==1) + if (gpiohs_get_pin(SOFT_SPI_MISO) == 1) { - read_data = read_data + 1; - } + read_data = read_data + 1; } - return read_data; + } + return read_data; } - static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) { - SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + 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){ + 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;ispi_cs_release) { + 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; @@ -164,40 +162,41 @@ static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiData static uint32 softSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) { - SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + 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){ + if (NONE == spi_datacfg->rx_buff) + { recv_length = 0; - } + } - if (spi_datacfg->spi_chip_select) { + if (spi_datacfg->spi_chip_select) + { gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); - } + } - for(size_t i=0;ispi_cs_release) { + if (spi_datacfg->spi_cs_release) + { gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); } spi_datacfg = spi_datacfg->next; - return spi_datacfg->length; + return spi_datacfg->length; } - -const struct SpiDevDone soft_spi_dev_done={ +const struct SpiDevDone soft_spi_dev_done = { .dev_close = NONE, .dev_open = NONE, - .dev_read = softSpiReadData, - .dev_write = softSpiWriteData -}; - + .dev_read = softSpiReadData, + .dev_write = softSpiWriteData}; static int BoardSoftSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver) { @@ -205,24 +204,27 @@ static int BoardSoftSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_dri /*Init the spi bus */ ret = SpiBusInit(spi_bus, SOFT_SPI_BUS_NAME); - if (EOK != ret) { + 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) { + 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) { + if (EOK != ret) + { KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret); return ERROR; - } + } return ret; } @@ -247,21 +249,24 @@ static int BoardSoftSpiDevBend(void) 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) { + 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) { + if (EOK != ret) + { KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SOFT_SPI_DEVICE_NAME, ret); return ERROR; } - return ret; + return ret; } -int HwSoftSPIInit(void){ +int HwSoftSPIInit(void) +{ x_err_t ret = EOK; static struct SpiBus spi_bus; @@ -270,23 +275,21 @@ int HwSoftSPIInit(void){ 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) { + if (EOK != ret) + { KPrintf("Board_Spi_Init error ret %u\n", ret); return ERROR; } - - ret = BoardSoftSpiDevBend(); - if (EOK != ret) { + if (EOK != ret) + { KPrintf("Board_Spi_Init error ret %u\n", ret); return ERROR; - } + } return ret; } From e7175c27455dc48c164644ef3109ebef43466cd1 Mon Sep 17 00:00:00 2001 From: wuzheng Date: Fri, 11 Nov 2022 17:39:03 +0800 Subject: [PATCH 5/7] add edu-riscv64 RTC test example --- .../Applications/app_test/test_i2c.c | 2 + .../Applications/app_test/test_rtc.c | 38 ++ .../transform_layer/xizi/transform.c | 1 + .../transform_layer/xizi/transform.h | 7 + .../XiZi_IIoT/board/edu-riscv64/board.c | 3 +- .../edu-riscv64/third_party_driver/Kconfig | 8 + .../edu-riscv64/third_party_driver/Makefile | 5 + .../third_party_driver/gpio/drv_io_config.c | 5 + .../third_party_driver/include/connect_rtc.h | 36 ++ .../third_party_driver/include/hardware_rtc.h | 448 +++++++++++++ .../third_party_driver/rtc/Kconfig | 11 + .../third_party_driver/rtc/Makefile | 3 + .../third_party_driver/rtc/connect_rtc.c | 183 ++++++ .../third_party_driver/rtc/hardware_rtc.c | 597 ++++++++++++++++++ 14 files changed, 1346 insertions(+), 1 deletion(-) create mode 100644 APP_Framework/Applications/app_test/test_rtc.c create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_rtc.h create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_rtc.h create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Kconfig create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/connect_rtc.c create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/hardware_rtc.c diff --git a/APP_Framework/Applications/app_test/test_i2c.c b/APP_Framework/Applications/app_test/test_i2c.c index d41a215e8..77a62c5f9 100644 --- a/APP_Framework/Applications/app_test/test_i2c.c +++ b/APP_Framework/Applications/app_test/test_i2c.c @@ -7,3 +7,5 @@ void TestI2C(void) { } + +PRIV_SHELL_CMD_FUNCTION(TestI2C, a iic test sample, PRIV_SHELL_CMD_MAIN_ATTR); 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..683478dd1 --- /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 times %d\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;iargs); 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/XiZi_IIoT/board/edu-riscv64/board.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c index 924e3e9a3..63351f357 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c @@ -45,6 +45,7 @@ Modification: #include "dmac.h" #include "connect_gpio.h" #include "connect_soft_spi.h" +#include "connect_rtc.h" // #if defined(FS_VFS) // #include @@ -185,7 +186,7 @@ struct InitSequenceDesc _board_init[] = { "hw_i2c", HwI2cInit }, #endif #ifdef BSP_USING_RTC - { "hw_uart", HwRTC }, + { "hw_rtc", HwRtcInit }, #endif #ifdef BSP_USING_UART { "hw_uart", HwUartInit }, 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 eed2fa64b..ba7047a33 100755 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig @@ -88,3 +88,11 @@ 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 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 7494b84fe..b4ab9bb14 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile @@ -44,4 +44,9 @@ ifeq ($(CONFIG_BSP_USING_SOFT_SPI),y) SRC_DIR += soft_spi endif +ifeq ($(CONFIG_BSP_USING_RTC),y) + SRC_DIR += rtc +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 ee1c55960..f49c62d8f 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 @@ -105,6 +105,11 @@ static struct io_config 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_LED IOCONFIG(BSP_LED_PIN,FUNC_GPIO5); #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/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/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; +} From 8c929ba7015dfeb7c29ba395c0a3a75b1ce98437 Mon Sep 17 00:00:00 2001 From: wuzheng Date: Fri, 11 Nov 2022 20:29:35 +0800 Subject: [PATCH 6/7] rs485 test example --- APP_Framework/Applications/app_test/Kconfig | 20 ++++- APP_Framework/Applications/app_test/Makefile | 4 + .../Applications/app_test/test_loraE220.c | 20 ++--- .../Applications/app_test/test_rs485.c | 87 +++++++++++++++++++ .../Applications/app_test/test_rtc.c | 6 +- .../third_party_driver/gpio/drv_io_config.c | 4 + .../include/drv_io_config.h | 5 ++ 7 files changed, 128 insertions(+), 18 deletions(-) diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index 3302d3596..c3fde9f87 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -59,7 +59,7 @@ menu "test app" select RESOURCES_PIN select BSP_USING_UART2 select BSP_USING_LORA - bool "Config test uart" + bool "Config test uart(loraE220)" default n if USER_TEST_LORA if ADD_XIZI_FETURES @@ -72,6 +72,24 @@ menu "test app" 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" diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index ad0368c10..b511ec9e6 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -53,5 +53,9 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_FILES += test_rtc.c endif + ifeq ($(CONFIG_USER_TEST_RS485),y) + SRC_FILES += test_rs485.c + endif + include $(KERNEL_ROOT)/compiler.mk endif diff --git a/APP_Framework/Applications/app_test/test_loraE220.c b/APP_Framework/Applications/app_test/test_loraE220.c index 4ea400669..c4409dd21 100644 --- a/APP_Framework/Applications/app_test/test_loraE220.c +++ b/APP_Framework/Applications/app_test/test_loraE220.c @@ -17,7 +17,7 @@ #define BSP_E220_M0_PIN 32 #define BSP_E220_M1_PIN 33 -void TestLora(int argc, char *agrv[]) +void TestLora(int argc, char *argv[]) { char uart_recvbuff[100]; memset(uart_recvbuff, 0, sizeof(uart_recvbuff)); @@ -39,7 +39,6 @@ void TestLora(int argc, char *agrv[]) struct PinStat pin_m0; struct PinStat pin_m1; - struct PinStat pin_key; pin_m0.pin = BSP_E220_M0_PIN; pin_m1.pin = BSP_E220_M1_PIN; @@ -47,19 +46,10 @@ void TestLora(int argc, char *agrv[]) struct PrivIoctlCfg ioctl_cfg; struct PinParam pin_param; pin_param.cmd = GPIO_CONFIG_MODE; - pin_param.mode = GPIO_CFG_INPUT; - - ioctl_cfg.ioctl_driver_type = PIN_TYPE; - ioctl_cfg.args = (void *)&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.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); @@ -106,7 +96,7 @@ void TestLora(int argc, char *agrv[]) 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 2.4kps + char sendbuff[] = {0xC0, 0x00, 0x05, 0x19, 0x49, 0xE6, 0x00, 0x17}; // config as address 1949 CH17 36.8kps PrivTaskDelay(2000); @@ -150,6 +140,8 @@ void TestLora(int argc, char *agrv[]) 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_rs485.c b/APP_Framework/Applications/app_test/test_rs485.c index e69de29bb..8b9fd5e1e 100644 --- a/APP_Framework/Applications/app_test/test_rs485.c +++ b/APP_Framework/Applications/app_test/test_rs485.c @@ -0,0 +1,87 @@ +#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 index 683478dd1..3a95c6cea 100644 --- a/APP_Framework/Applications/app_test/test_rtc.c +++ b/APP_Framework/Applications/app_test/test_rtc.c @@ -13,7 +13,7 @@ void TestRTC(int argc,char *argv[]) if(argc>1){ int times = atoi(argv[1]); - printf("Time will be printf times %d\n",times); + 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; @@ -26,12 +26,12 @@ void TestRTC(int argc,char *argv[]) rtc_para.rtc_operation_cmd = OPER_RTC_GET_TIME; for(size_t i=0;i Date: Tue, 15 Nov 2022 15:47:48 +0800 Subject: [PATCH 7/7] example for edu-riscv64:watchdog,lcd and timer --- APP_Framework/Applications/app_test/Kconfig | 39 +- APP_Framework/Applications/app_test/Makefile | 12 + .../Applications/app_test/test_hwtimer.c | 62 +++ .../Applications/app_test/test_i2c.c | 43 +- .../Applications/app_test/test_lcd_edu.c | 50 +++ .../Applications/app_test/test_rs485.c | 1 - .../Applications/app_test/test_wdt.c | 45 ++ .../XiZi_IIoT/board/edu-riscv64/board.c | 11 +- .../edu-riscv64/third_party_driver/Kconfig | 16 + .../edu-riscv64/third_party_driver/Makefile | 8 + .../third_party_driver/gpio/drv_io_config.c | 3 +- .../third_party_driver/i2c/Kconfig | 4 +- .../include/connect_hwtimer.h | 37 ++ .../third_party_driver/include/connect_wdt.h | 36 ++ .../include/hardware_hwtimer.h | 171 ++++++++ .../third_party_driver/include/wdt.h | 180 ++++++++ .../third_party_driver/timer/Kconfig | 19 + .../third_party_driver/timer/Makefile | 5 + .../timer/connect_hwtimer.c | 153 +++++++ .../timer/hardware_hwtimer.c | 407 ++++++++++++++++++ .../third_party_driver/watchdog/Kconfig | 34 ++ .../third_party_driver/watchdog/Makefile | 6 + .../third_party_driver/watchdog/connect_wdt.c | 176 ++++++++ .../third_party_driver/watchdog/wdt.c | 125 ++++++ .../XiZi_IIoT/kernel/kernel_test/Makefile | 4 - .../XiZi_IIoT/kernel/kernel_test/test_main.c | 2 - .../kernel/kernel_test/test_softspi_sd.c | 105 ----- 27 files changed, 1632 insertions(+), 122 deletions(-) create mode 100644 APP_Framework/Applications/app_test/test_hwtimer.c create mode 100644 APP_Framework/Applications/app_test/test_lcd_edu.c create mode 100644 APP_Framework/Applications/app_test/test_wdt.c create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_hwtimer.h create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_wdt.h create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_hwtimer.h create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wdt.h create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Kconfig create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/connect_hwtimer.c create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/hardware_hwtimer.c create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Kconfig create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/connect_wdt.c create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/wdt.c delete mode 100644 Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_softspi_sd.c diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index c3fde9f87..e1e9b084e 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -102,6 +102,43 @@ menu "test app" 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" @@ -110,7 +147,7 @@ menu "test app" if ADD_XIZI_FETURES config I2C_DEV_DRIVER string "Set i2c dev path" - default "/dev/i2c_dev" + default "/dev/i2c1_dev0" endif endif diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index b511ec9e6..28e2f25e5 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -57,5 +57,17 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),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_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 index 77a62c5f9..43a2f224a 100644 --- a/APP_Framework/Applications/app_test/test_i2c.c +++ b/APP_Framework/Applications/app_test/test_i2c.c @@ -2,10 +2,49 @@ #include #include +#define I2C_SLAVE_ADDRESS 0x0012U -void TestI2C(void) +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_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_rs485.c b/APP_Framework/Applications/app_test/test_rs485.c index 8b9fd5e1e..029c7d4b1 100644 --- a/APP_Framework/Applications/app_test/test_rs485.c +++ b/APP_Framework/Applications/app_test/test_rs485.c @@ -81,7 +81,6 @@ void Test485(void) 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_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/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c index 63351f357..0107071e8 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c @@ -46,6 +46,8 @@ Modification: #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 @@ -188,9 +190,6 @@ struct InitSequenceDesc _board_init[] = #ifdef BSP_USING_RTC { "hw_rtc", HwRtcInit }, #endif -#ifdef BSP_USING_UART - { "hw_uart", HwUartInit }, -#endif #ifdef BSP_USING_SPI { "hw_spi", HwSpiInit }, #endif @@ -205,6 +204,12 @@ struct InitSequenceDesc _board_init[] = #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 }, }; 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 ba7047a33..11ecca978 100755 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig @@ -96,3 +96,19 @@ menuconfig BSP_USING_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 b4ab9bb14..b8f466166 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile @@ -48,5 +48,13 @@ 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 1bd31c747..fa2b4617f 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,7 +75,7 @@ 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 @@ -121,7 +121,6 @@ static struct io_config #ifdef BSP_USING_KEY IOCONFIG(BSP_KEY_PIN,FUNC_GPIO6); #endif - }; static int PrintIoConfig() 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_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/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/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/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/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/kernel/kernel_test/Makefile b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/Makefile index ed3599ccb..1c4f0656a 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/kernel_test/Makefile +++ b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/Makefile @@ -92,8 +92,4 @@ ifeq ($(CONFIG_KERNEL_TEST_SPI_FLASH),y) SRC_FILES += test_spi_flash.c endif -ifeq ($(KERNEL_TEST_SOFT_SPI_SD),y) - SRC_FILES += test_softspi_sd.c -endif - include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_main.c b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_main.c index 33f15d9a9..18d6f85f0 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_main.c +++ b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_main.c @@ -118,8 +118,6 @@ int TestMain(int argc, char*argv[]) #ifdef KERNEL_TEST_REALTIME if (argc > 2) TestRealtime(argc-2, &argv[2]); -#endif -#ifdef KERNEL_TEST_SOFT_SPI_SD #endif default: break; diff --git a/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_softspi_sd.c b/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_softspi_sd.c deleted file mode 100644 index b07c8a672..000000000 --- a/Ubiquitous/XiZi_IIoT/kernel/kernel_test/test_softspi_sd.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2016-09-28 armink first version. - */ - -/** -* @file test_spi_flash.c -* @brief support to test spi flash function -* @version 1.0 -* @author AIIT XUOS Lab -* @date 2021-05-17 -*/ - -/************************************************* -File name: test_spi_flash.c -Description: support spi flash function test -Others: add spi flash test cmd from SFUD/blob/master/demo/stm32f2xx_rtt/RT-Thread-2.1.0/components/drivers/spi/spi_flash_sfud.c - https://github.com/armink/SFUD/ -History: -1. Date: 2021-05-17 -Author: AIIT XUOS Lab -Modification: -1. support spi flash open, read and write function -*************************************************/ - -#include -#include -#include - -// void SDpen(void) -// { -// x_err_t ret = EOK; - -// ret=HwTFInit(); -// if (ret < 0) { -// KPrintf("open spi flash fd error %d\n", ret); -// } - -// KPrintf("Spi Flash init succeed\n"); - -// return; -// } - -// SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), -// SDpen, SDpen, open spi flash device); - -// void SDRead(int argc, char *argv[]) -// { -// x_err_t ret = EOK; - -// } -// SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), -// SDRead, SDRead, read data from spi flash device); - -// void SDWrite(int argc, char *argv[]) -// { -// x_err_t ret = EOK; -// x_size_t i, j = 0; -// uint32 addr; -// uint32 size; -// uint8 data[16]; - -// struct BusBlockWriteParam write_param; -// memset(&write_param, 0, sizeof(struct BusBlockWriteParam)); - -// memset(data, 0, 16); - -// if (argc < 3) { -// KPrintf("FlashWrite cmd format: FlashWrite addr data.\n"); -// return; -// } else { -// addr = strtol(argv[1], NULL, 0); -// size = argc - 2; - -// write_param.buffer = data; -// write_param.pos = addr; -// write_param.size = size; - -// if (data) { -// for (i = 0; i < size; i++) { -// data[i] = strtol(argv[2 + i], NULL, 0); -// } - -// ret = write(spi_flash_fd, &write_param, size); -// if (EOK == ret) { -// KPrintf("Write the %s flash data success. Start from 0x%08X, size is %ld.\n", -// SPI_FLASH_PATH, addr, size); -// KPrintf("Write data: "); -// for (i = 0; i < size; i++) { -// KPrintf("%d ", data[i]); -// } -// KPrintf(".\n"); -// } -// } else { -// KPrintf("SpiFlashWrite alloc write buffer failed!\n"); -// } -// } -// } -// SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), -// SDWrite, SDWrite, write data to spi flash device);