diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/board.c b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/board.c index 4d5a2a97a..1b7d76c95 100644 --- a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/board.c +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/board.c @@ -26,6 +26,8 @@ #include "connect_usart.h" #include "connect_spi.h" #include "connect_usb.h" +#include "connect_wdt.h" +#include "connect_can.h" void Error_Handler(void) { @@ -47,8 +49,10 @@ void SystemClock_Config(void) __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); /** Initializes the CPU, AHB and APB busses clocks */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_LSE + |RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.MSICalibrationValue = 0; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6; @@ -69,7 +73,7 @@ void SystemClock_Config(void) |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV16; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) @@ -80,10 +84,10 @@ void SystemClock_Config(void) |RCC_PERIPHCLK_USART3|RCC_PERIPHCLK_UART4 |RCC_PERIPHCLK_UART5|RCC_PERIPHCLK_USB; PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; - PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; - PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1; - PeriphClkInit.Uart4ClockSelection = RCC_UART4CLKSOURCE_PCLK1; - PeriphClkInit.Uart5ClockSelection = RCC_UART5CLKSOURCE_PCLK1; + PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_SYSCLK; + PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_SYSCLK; + PeriphClkInit.Uart4ClockSelection = RCC_UART4CLKSOURCE_SYSCLK; + PeriphClkInit.Uart5ClockSelection = RCC_UART5CLKSOURCE_SYSCLK; PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1; PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI; PeriphClkInit.PLLSAI1.PLLSAI1M = 1; @@ -140,6 +144,14 @@ void InitBoardHardware() #ifdef BSP_USING_USB HwUsbDeviceInit(); #endif + +#ifdef BSP_USING_WDT + HwWdtInit(); +#endif + +#ifdef BSP_USING_CAN + HwCanInit(); +#endif /* disable interrupt */ __set_PRIMASK(1); diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/img/RS485.png b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/img/RS485.png new file mode 100644 index 000000000..60bedb9ba Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/img/RS485.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/img/can.png b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/img/can.png new file mode 100644 index 000000000..d18138b5b Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/img/can.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/img/watchdog.png b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/img/watchdog.png new file mode 100644 index 000000000..12cd1da61 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/img/watchdog.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/include/stm32l4xx_hal_conf.h b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/include/stm32l4xx_hal_conf.h index b8c83cb9e..5e4e7e379 100644 --- a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/include/stm32l4xx_hal_conf.h +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/include/stm32l4xx_hal_conf.h @@ -51,7 +51,7 @@ #define HAL_MODULE_ENABLED /*#define HAL_ADC_MODULE_ENABLED */ /*#define HAL_CRYP_MODULE_ENABLED */ -/*#define HAL_CAN_MODULE_ENABLED */ +#define HAL_CAN_MODULE_ENABLED /*#define HAL_COMP_MODULE_ENABLED */ /*#define HAL_CRC_MODULE_ENABLED */ /*#define HAL_CRYP_MODULE_ENABLED */ @@ -66,7 +66,7 @@ /*#define HAL_HASH_MODULE_ENABLED */ /*#define HAL_I2S_MODULE_ENABLED */ /*#define HAL_IRDA_MODULE_ENABLED */ -/*#define HAL_IWDG_MODULE_ENABLED */ +#define HAL_IWDG_MODULE_ENABLED /*#define HAL_LTDC_MODULE_ENABLED */ /*#define HAL_LCD_MODULE_ENABLED */ /*#define HAL_LPTIM_MODULE_ENABLED */ @@ -92,7 +92,7 @@ /*#define HAL_TSC_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED /*#define HAL_USART_MODULE_ENABLED */ -/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_WWDG_MODULE_ENABLED /*#define HAL_EXTI_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/Kconfig index 3444f758e..8c0fa384c 100755 --- a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/Kconfig @@ -1,25 +1,42 @@ menuconfig BSP_USING_UART -bool "Using UART device" -default y -select RESOURCES_SERIAL -if BSP_USING_UART -source "$BSP_DIR/third_party_driver/uart/Kconfig" -endif + bool "Using UART device" + default y + select RESOURCES_SERIAL + if BSP_USING_UART + source "$BSP_DIR/third_party_driver/uart/Kconfig" + endif menuconfig BSP_USING_SPI -bool "Using SPI device" -default y -select RESOURCES_SPI -if BSP_USING_SPI -source "$BSP_DIR/third_party_driver/spi/Kconfig" -endif + bool "Using SPI device" + default n + select RESOURCES_SPI + if BSP_USING_SPI + source "$BSP_DIR/third_party_driver/spi/Kconfig" + endif menuconfig BSP_USING_USB -bool "Using USB device" -default y -select RESOURCES_USB -if BSP_USING_USB -source "$BSP_DIR/third_party_driver/usb/Kconfig" -endif + bool "Using USB device" + default n + select RESOURCES_USB + if BSP_USING_USB + source "$BSP_DIR/third_party_driver/usb/Kconfig" + endif + +menuconfig BSP_USING_WDT + bool "Using WDT device" + default n + select RESOURCES_WDT + if BSP_USING_WDT + source "$BSP_DIR/third_party_driver/watchdog/Kconfig" + endif + +menuconfig BSP_USING_CAN + bool "Using CAN device" + default n + select RESOURCES_CAN + if BSP_USING_CAN + source "$BSP_DIR/third_party_driver/can/Kconfig" + endif + diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/Makefile index 754928db8..4b9e72ee9 100644 --- a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/Makefile @@ -12,4 +12,12 @@ ifeq ($(CONFIG_BSP_USING_USB),y) SRC_DIR += usb endif +ifeq ($(CONFIG_BSP_USING_WDT),y) + SRC_DIR += watchdog +endif + +ifeq ($(CONFIG_BSP_USING_CAN),y) + SRC_DIR += can +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/can/Kconfig b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/can/Kconfig new file mode 100644 index 000000000..cd17d6219 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/can/Kconfig @@ -0,0 +1,11 @@ +config CAN_BUS_NAME + string "can bus name" + default "can1" + +config CAN_DRIVER_NAME + string "can driver name" + default "can1_drv" + +config CAN_DEVICE_NAME + string "can device name" + default "can1_dev1" \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/can/Makefile b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/can/Makefile new file mode 100644 index 000000000..22aba4901 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/can/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := connect_can.c + + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/can/connect_can.c b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/can/connect_can.c new file mode 100644 index 000000000..9e5c78bc6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/can/connect_can.c @@ -0,0 +1,332 @@ +/* +* 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_can.c +* @brief support stm32l476 can function and register to bus framework +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2025-03-14 +*/ + +/************************************************* +File name: connect_can.c +Description: support stm32l476 can function and register to bus framework +Others: +History: +1. Date: 2025-03-14 +Author: AIIT XUOS Lab +Modification: +1. support stm32l476 can configure, write and read +2. support stm32l476 can bus device and driver register +*************************************************/ + +#include "connect_can.h" +#include "stm32l476xx.h" +#include "stm32l4xx_hal.h" + +CAN_HandleTypeDef hcan1; + +#define GET_CAN_BS2_TQ(x) ((x) == 1 ? CAN_BS2_1TQ : (x) == 2 ? CAN_BS2_2TQ : (x) == 3 ? CAN_BS2_3TQ : (x) == 4 ? CAN_BS2_4TQ : \ + (x) == 5 ? CAN_BS2_5TQ : (x) == 6 ? CAN_BS2_6TQ : (x) == 7 ? CAN_BS2_7TQ : (x) == 8 ? CAN_BS2_8TQ : CAN_BS2_1TQ) + +#define GET_CAN_BS1_TQ(x) ((x) == 1 ? CAN_BS1_1TQ : (x) == 2 ? CAN_BS1_2TQ : (x) == 3 ? CAN_BS1_3TQ : (x) == 4 ? CAN_BS1_4TQ : \ + (x) == 5 ? CAN_BS1_5TQ : (x) == 6 ? CAN_BS1_6TQ : (x) == 7 ? CAN_BS1_7TQ : (x) == 8 ? CAN_BS1_8TQ : \ + (x) == 9 ? CAN_BS1_9TQ : (x) == 10 ? CAN_BS1_10TQ : (x) == 11 ? CAN_BS1_11TQ : (x) == 12 ? CAN_BS1_12TQ : \ + (x) == 13 ? CAN_BS1_13TQ : (x) == 14 ? CAN_BS1_14TQ : (x) == 15 ? CAN_BS1_15TQ : (x) == 16 ? CAN_BS1_16TQ : CAN_BS1_1TQ) + +#define GET_CAN_SJW_TQ(x) ((x) == 1 ? CAN_SJW_1TQ : (x) == 2 ? CAN_SJW_2TQ : (x) == 3 ? CAN_SJW_3TQ : (x) == 4 ? CAN_SJW_4TQ : CAN_SJW_1TQ ) +#define GET_CAN_MODE(x) ((x) == 0 ? CAN_MODE_NORMAL : (x) == 1 ? CAN_MODE_LOOPBACK : (x) == 2 ? CAN_MODE_SILENT : (x) == 3 ? CAN_MODE_SILENT_LOOPBACK : CAN_MODE_NORMAL ) + +static void CanInit(struct CanDriverConfigure *can_drv_config) +{ + __HAL_RCC_CAN1_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /**CAN1 GPIO Configuration + PB8 ------> CAN1_RX + PB9 ------> CAN1_TX + */ + GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF9_CAN1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + hcan1.Instance = CAN1; + hcan1.Init.Prescaler = can_drv_config->brp; + hcan1.Init.Mode = GET_CAN_MODE(can_drv_config->mode); + hcan1.Init.SyncJumpWidth = GET_CAN_SJW_TQ(can_drv_config->tsjw); + hcan1.Init.TimeSeg1 = GET_CAN_BS1_TQ(can_drv_config->tbs1); + hcan1.Init.TimeSeg2 = GET_CAN_BS2_TQ(can_drv_config->tbs2); + hcan1.Init.TimeTriggeredMode = DISABLE; + hcan1.Init.AutoBusOff = DISABLE; + hcan1.Init.AutoWakeUp = DISABLE; + hcan1.Init.AutoRetransmission = DISABLE; + hcan1.Init.ReceiveFifoLocked = DISABLE; + hcan1.Init.TransmitFifoPriority = DISABLE; + int ret = HAL_CAN_Init(&hcan1); + if (ret != HAL_OK) + { + KPrintf("Can init failed! ret=%d\n", ret); + } + + CAN_FilterTypeDef filter; + filter.FilterIdHigh = 0x0000; + filter.FilterMaskIdHigh = 0x0000; + filter.FilterIdLow = 0x0000; + filter.FilterMaskIdLow = 0x0000; + filter.FilterFIFOAssignment = CAN_RX_FIFO0; + filter.FilterBank = 0; + filter.FilterMode = CAN_FILTERMODE_IDMASK; + filter.FilterScale = CAN_FILTERSCALE_32BIT; + filter.FilterActivation = ENABLE; + HAL_CAN_ConfigFilter(&hcan1, &filter); +} + +static uint32 CanConfig(void *can_drv_config) +{ + x_err_t ret = EOK; + return ret; +} + +static uint32 CanDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + x_err_t ret = EOK; + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + struct CanDriverConfigure *can_drv_config; + switch (configure_info->configure_cmd) + { + case OPE_INT: // can basic init + can_drv_config = (struct CanDriverConfigure *)configure_info->private_data; + CanInit(can_drv_config); + break; + case OPE_CFG: + CanConfig(configure_info->private_data); + break; + default: + break; + } + + return ret; +} + +static uint32 CanOpenDev(void * dev) +{ + HAL_CAN_Start(&hcan1); +} + +static uint32 CanCloseDev(void * dev) +{ + HAL_CAN_Stop(&hcan1); +} + +static uint32 CanWriteData(void * dev , struct BusBlockWriteParam *write_param) +{ + NULL_PARAM_CHECK(write_param); + uint32_t TxMailbox; + uint8 *data = (uint8 * ) write_param->buffer; + uint8 mbox; + uint16 i = 0; + uint16 timer_count = 1000; + CAN_TxHeaderTypeDef TxHeader; + int idx = 0; + while (idx < write_param->size) + { + int r_len = write_param->size - idx; + int size = r_len >= 8 ? 8 : r_len; + TxHeader.StdId = 0x55; + TxHeader.ExtId = 0x00; + TxHeader.RTR = CAN_RTR_DATA; + TxHeader.IDE = CAN_ID_STD; + TxHeader.DLC = size; + TxHeader.TransmitGlobalTime = DISABLE; + + // 发送消息 + int ret = HAL_CAN_AddTxMessage(&hcan1, &TxHeader, (uint8 *)(write_param->buffer + idx), &TxMailbox); + if ( ret != HAL_OK) { + KPrintf("Send message error: %d\n",ret); + } + idx += size; + } + + return EOK; +} + +static uint32 CanReadData(void *dev , struct BusBlockReadParam *databuf) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(databuf); + + CAN_RxHeaderTypeDef RxHeader; + uint8_t RxData[8]; + x_err_t ret=EOK; + uint32 len = -1; + struct CanSendConfigure *p_can_config = (struct CanSendConfigure*)databuf->buffer; + // while(HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) == 0); + if (HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) > 0) { + if (HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) { + len = databuf->size < RxHeader.DLC ? databuf->size : RxHeader.DLC; + uint8* buf = databuf->buffer; + for (uint8_t i = 0; i < RxHeader.DLC; i++) { + buf[i] = RxData[i]; + } + } + } + + return len; +} + +static struct CanDevDone can_dev_done = +{ + .open = CanOpenDev, + .close = CanCloseDev, + .write = CanWriteData, + .read = CanReadData +}; + +static int BoardCanBusInit(struct CanBus *can_bus, struct CanDriver *can_driver) +{ + x_err_t ret = EOK; + + /*Init the can bus */ + ret = CanBusInit(can_bus, CAN_BUS_NAME); + if (EOK != ret) { + KPrintf("Board_can_init canBusInit error %d\n", ret); + return ERROR; + } + + /*Init the can driver*/ + ret = CanDriverInit(can_driver, CAN_DRIVER_NAME); + if (EOK != ret) { + KPrintf("Board_can_init canDriverInit error %d\n", ret); + return ERROR; + } + /*Attach the can driver to the can bus*/ + ret = CanDriverAttachToBus(CAN_DRIVER_NAME, CAN_BUS_NAME); + if (EOK != ret) { + KPrintf("Board_can_init CanDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/* Attach the can device to the can bus*/ +static int BoardCanDevBend(void) +{ + x_err_t ret = EOK; + static struct CanHardwareDevice can_device; + memset(&can_device, 0, sizeof(struct CanHardwareDevice)); + + can_device.dev_done = &can_dev_done; + + ret = CanDeviceRegister(&can_device, NONE, CAN_DEVICE_NAME); + if (EOK != ret) { + KPrintf("board_can_init CanDeviceInit device %s error %d\n", CAN_DEVICE_NAME, ret); + return ERROR; + } + + ret = CanDeviceAttachToBus(CAN_DEVICE_NAME, CAN_BUS_NAME); + if (EOK != ret) { + KPrintf("board_can_init CanDeviceAttachToBus device %s error %d\n", CAN_DEVICE_NAME, ret); + return ERROR; + } + + return ret; +} + +int HwCanInit(void) +{ + x_err_t ret = EOK; + + static struct CanBus can_bus; + memset(&can_bus, 0, sizeof(struct CanBus)); + + static struct CanDriver can_driver; + memset(&can_driver, 0, sizeof(struct CanDriver)); + + can_driver.configure = &(CanDrvConfigure); + + ret = BoardCanBusInit(&can_bus, &can_driver); + if (EOK != ret) { + KPrintf(" can_bus_init %s error ret %u\n", CAN_BUS_NAME, ret); + return ERROR; + } + + ret = BoardCanDevBend(); + if (EOK != ret) { + KPrintf("board_can_init error ret %u\n", ret); + return ERROR; + } + return EOK; +} + +#ifdef TEST_CAN +static struct Bus *bus; +static struct HardwareDev *dev; +static struct Driver *drv; + +static uint32 TestCan(void) +{ + x_err_t ret = EOK; + bus = BusFind(CAN_BUS_NAME); + dev = BusFindDevice(bus, CAN_DEVICE_NAME); + drv = BusFindDriver(bus, CAN_DRIVER_NAME); + + struct BusConfigureInfo configure_info; + struct CanDriverConfigure can_config; + can_config.brp = 5; + can_config.mode = 0; + can_config.tbs1 = 7; + can_config.tbs2 = 2; + can_config.tsjw = 1; + // spi_master_param.spi_data_bit_width = 8; + // spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB; + + configure_info.configure_cmd = OPE_INT; + configure_info.private_data = (void *)&can_config; + ret = BusDrvConfigure(drv, &configure_info); + if (ret) { + // KPrintf("spi drv OPE_CFG error drv %8p cfg %8p\n", drv, &spi_master_param); + return ERROR; + } + + struct BusBlockWriteParam write_param; + struct BusBlockReadParam read_param; + + uint8 write_data[10] = {1,2,3,4,5,6,7,8,9,10}; + uint8 read_data = 0; + + BusDevOpen(dev); + + write_param.buffer = (void *)write_data; + write_param.size = 10; + BusDevWriteData(dev, &write_param); + + read_param.buffer = (void *)&read_data; + read_param.size = 1; + int n = BusDevReadData(dev, &read_param); + + // BusDevClose(dev); + KPrintf("write 1~10 data and receive %d data[0]=0x%x\n", n, read_data); + + return ret; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + TestCan, TestCan, open can device and write_read parameters); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/include/connect_can.h b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/include/connect_can.h new file mode 100644 index 000000000..9b7e62c4e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/include/connect_can.h @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2021 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_can.h +* @brief define stm32l476 can function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2025-03-14 +*/ + +#ifndef CONNECT_CAN_H +#define CONNECT_CAN_H + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +int HwCanInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/include/connect_wdt.h b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/include/connect_wdt.h new file mode 100644 index 000000000..2d602b39a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/include/connect_wdt.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_wdt.h +* @brief define stm32l476 watchdog function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2025-03-13 +*/ + +#ifndef CONNECT_WDT_H +#define CONNECT_WDT_H + +#include +#include "stm32l4xx_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int HwWdtInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/libraries/STM32L4xx_HAL_Driver/src/Makefile b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/libraries/STM32L4xx_HAL_Driver/src/Makefile index a6ef5432b..8218a778d 100644 --- a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/libraries/STM32L4xx_HAL_Driver/src/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/libraries/STM32L4xx_HAL_Driver/src/Makefile @@ -22,5 +22,7 @@ SRC_FILES := \ stm32l4xx_hal_spi_ex.c \ stm32l4xx_hal_pcd.c \ stm32l4xx_hal_pcd_ex.c \ - stm32l4xx_ll_usb.c + stm32l4xx_hal_can.c \ + stm32l4xx_ll_usb.c \ + stm32l4xx_hal_wwdg.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/uart/connect_usart.c b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/uart/connect_usart.c index 23a759c9d..a5dd58665 100644 --- a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/uart/connect_usart.c +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/uart/connect_usart.c @@ -20,7 +20,6 @@ Modification: #include #include -#define BSP_USING_UART1 #if defined(BSP_USING_UART1) UART_HandleTypeDef huart1; #endif @@ -416,8 +415,6 @@ static int SerialGetChar(struct SerialHardwareDevice *serial_dev) if (serial_hw_cfg->uart_device->Instance->ISR & UART_FLAG_RXNE) { ch = serial_hw_cfg->uart_device->Instance->RDR & 0xff; } - // uint8_t data = serial_hw_cfg->uart_device->Instance->RDR; - // HAL_UART_Receive(serial_hw_cfg->uart_device, &ch, 1, 100); return ch; } @@ -741,3 +738,37 @@ int HwUsartInit(void) return ret; } + + +#ifdef TEST_RS485 +static struct Bus *bus; +static struct HardwareDev *dev; +static struct Driver *drv; + +void RS485Test(void) +{ + x_err_t ret = EOK; + + bus = BusFind(SERIAL_BUS_NAME_4); + dev = BusFindDevice(bus, SERIAL_4_DEVICE_NAME_0); + drv = BusFindDriver(bus, SERIAL_DRV_NAME_4); + + struct BusConfigureInfo configure_info; + configure_info.configure_cmd = OPE_INT; + struct SerialCfgParam serial_cfg; + memset(&serial_cfg, 0, sizeof(struct SerialCfgParam)); + configure_info.private_data = &serial_cfg; + ret = BusDrvConfigure(drv, &configure_info); + + struct BusBlockWriteParam write_param; + memset(&write_param, 0, sizeof(struct BusBlockWriteParam)); + + uint8 write_data[] = "Message from stm32L476 by RS485(UART5)"; + + write_param.buffer = (void *)write_data; + write_param.size = sizeof(write_data); + BusDevWriteData(dev, &write_param); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + RS485Test, RS485Test, open uart device and use rs485 write_read parameters); +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/watchdog/Kconfig b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/watchdog/Kconfig new file mode 100644 index 000000000..b47dd9f77 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/watchdog/Kconfig @@ -0,0 +1,15 @@ +if BSP_USING_WDT + 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 + + diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/watchdog/Makefile b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/watchdog/Makefile new file mode 100644 index 000000000..9be59f003 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/watchdog/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_wdt.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/watchdog/connect_wdt.c b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/watchdog/connect_wdt.c new file mode 100644 index 000000000..eb1a3a398 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/stm32l476rgt6/third_party_driver/watchdog/connect_wdt.c @@ -0,0 +1,182 @@ +/* +* 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 stm32l476 watchdog function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2025-03-13 +*/ + +#include + +WWDG_HandleTypeDef hwwdg; + +static uint32 WdtOpen(void *dev) +{ + NULL_PARAM_CHECK(dev); + + hwwdg.Instance = WWDG; + hwwdg.Init.Prescaler = WWDG_PRESCALER_8; + hwwdg.Init.Window = 127; + hwwdg.Init.Counter = 127; + hwwdg.Init.EWIMode = WWDG_EWI_DISABLE; + int ret = HAL_WWDG_Init(&hwwdg); + if ( ret != HAL_OK) + { + KPrintf("WdtOpen error ret %u\n", ret); + } else { + KPrintf("WdtOpen success\n"); + } + __HAL_RCC_WWDG_CLK_ENABLE(); + HAL_WWDG_Refresh(&hwwdg); + __HAL_WWDG_ENABLE(&hwwdg); + return EOK; +} + +static uint32 WdtConfigure(void *drv, struct BusConfigureInfo *args) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(args); + + // stm32 window based on a 7-bit downcounter + // The timing for feeding the dog must be greater than 0x3F + // So the window minimal value is 0x40 + int window = *((int*)args->private_data); + if(window > 127) { + window = 127; + } else if (window < 0x40) { + window = 0x40; + } + + switch (args->configure_cmd) + { + case OPER_WDT_SET_TIMEOUT: + hwwdg.Instance = WWDG; + hwwdg.Init.Prescaler = WWDG_PRESCALER_8; + hwwdg.Init.Window = window; + hwwdg.Init.Counter = 127; + hwwdg.Init.EWIMode = WWDG_EWI_DISABLE; + if (HAL_WWDG_Init(&hwwdg) != 0) { + return ERROR; + } + break; + case OPER_WDT_KEEPALIVE: + HAL_WWDG_Refresh(&hwwdg); + 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) +{ + x_err_t ret = EOK; + + 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; + + 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; + + 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; + } + + return ret; +} + + +#ifdef TEST_WDT +static struct Bus *bus; +static struct HardwareDev *dev; +static struct Driver *drv; + +void WDTTest(void) +{ + x_err_t ret = EOK; + + bus = BusFind(WDT_BUS_NAME_0); + dev = BusFindDevice(bus, WDT_0_DEVICE_NAME_0); + drv = BusFindDriver(bus, WDT_DRIVER_NAME_0); + BusDevOpen(dev); + + struct BusConfigureInfo config; + memset(&config, 0 , sizeof(struct BusConfigureInfo)); + config.configure_cmd = OPER_WDT_KEEPALIVE; + + for (int i = 0; i < 1000; i++) + { + BusDrvConfigure(drv, &config); + HAL_Delay(5); + if (i%100 == 0) + { + KPrintf("feed dog for %d times\n", i); + } + + } + KPrintf("Stop feed dog, and waiting for reset...\n"); + int count = 0; + while(1); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + WDTTest, WDTTest, watchdog test); +#endif