[STM32L476] bsp code, support for rs485,watchdog and can

This commit is contained in:
张超杰 2025-03-24 09:30:54 +08:00
parent 0291fb49d4
commit e70951972a
17 changed files with 721 additions and 31 deletions

View File

@ -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);

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -0,0 +1,4 @@
SRC_FILES := connect_can.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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

View File

@ -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 <device.h>
#ifdef __cplusplus
extern "C" {
#endif
int HwCanInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -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 <device.h>
#include "stm32l4xx_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
int HwWdtInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -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

View File

@ -20,7 +20,6 @@ Modification:
#include <board.h>
#include <connect_usart.h>
#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

View File

@ -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

View File

@ -0,0 +1,3 @@
SRC_FILES := connect_wdt.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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 <connect_wdt.h>
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