add can and flash driver for hc32f4a0 in XiZi_IIoT

This commit is contained in:
wuzheng 2023-02-22 09:38:41 +08:00
parent 002325c1d8
commit 73fbeea117
16 changed files with 486 additions and 2 deletions

View File

@ -171,6 +171,18 @@ menu "test app"
endif
endif
menuconfig USER_TEST_CAN
select BSP_USING_CAN
bool "Config test can"
default n
if USER_TEST_CAN
if ADD_XIZI_FETURES
config CAN_DEV_DRIVER
string "Set can dev path"
default "/dev/can2_dev1"
endif
endif
menuconfig USER_TEST_CAMERA
select BSP_USING_CAMERA
select BSP_USING_LCD

View File

@ -91,6 +91,10 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
ifeq ($(CONFIG_USER_TEST_FLASH),y)
SRC_FILES += test_flash.c
endif
ifeq ($(CONFIG_USER_TEST_CAN),y)
SRC_FILES += test_can.c
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,66 @@
#include <stdio.h>
#include <string.h>
#include <transform.h>
void TestCAN(void)
{
// config CAN pin(SCL:34.SDA:35) in menuconfig
int can_fd = PrivOpen(CAN_DEV_DRIVER, O_RDWR);
if (can_fd < 0)
{
printf("open can_fd fd error:%d\n", can_fd);
return;
}
printf("CAN open successful!\n");
struct PrivIoctlCfg ioctl_cfg;
ioctl_cfg.ioctl_driver_type = CAN_TYPE;
struct CanDriverConfigure can_config;
can_config.brp = 8U;
can_config.tbs1 = 1U + 8U;
can_config.tbs2 = 4U;
can_config.tsjw = 4U;
can_config.mode = 0U;
ioctl_cfg.args = (void *)&can_config;
if (0 != PrivIoctl(can_fd, OPE_INT, &ioctl_cfg))
{
printf("init can fd error %d\n", can_fd);
PrivClose(can_fd);
return;
}
printf("CAN configure successful!\n");
uint8_t data_buff[64u] = {1,2,3,4,4,3,2,1};
struct CanSendConfigure frame_send;
frame_send.ide=0;
frame_send.stdid = 0x55;
frame_send.rtr=0;
frame_send.data_lenth=8;
frame_send.data = data_buff;
struct CanSendConfigure frame_recv;
uint8_t recv_buff[65U] = {0};
frame_recv.data = recv_buff;
// CAN write
while (1)
{
PrivTaskDelay(500);
PrivWrite(can_fd, &frame_send, NONE);
PrivTaskDelay(500);
PrivRead(can_fd, &frame_recv, NONE);
// if any data has received,Then printf message
if(frame_recv.data_lenth > 0){
printf("ID %08x:%s\n",frame_recv.exdid,frame_recv.data);
}
}
PrivClose(can_fd);
return;
}
PRIV_SHELL_CMD_FUNCTION(TestCAN, a can test sample, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -105,6 +105,7 @@ void TestTouch(void)
graph_param.pixel_info.y_endpos = touch_pixel.y+10;
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
}
PrivClose(lcd_fd);
PrivClose(touch_fd);
}

View File

@ -26,3 +26,5 @@ void mnist_app(void);
int tfmnist(void) {
mnist_app();
}
PRIV_SHELL_CMD_FUNCTION(tfmnist, a mnist test sample, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -174,6 +174,7 @@ int PrivIoctl(int fd, int cmd, void *args)
case KPU_TYPE:
case TIME_TYPE:
case FLASH_TYPE:
case CAN_TYPE:
ret = ioctl(fd, cmd, ioctl_cfg->args);
break;
default:

View File

@ -151,6 +151,7 @@ enum IoctlDriverType
WDT_TYPE,
RTC_TYPE,
CAMERA_TYPE,
CAN_TYPE,
KPU_TYPE,
FLASH_TYPE,
TIME_TYPE,
@ -254,6 +255,25 @@ enum TCP_OPTION {
RECV_DATA,
};
struct CanDriverConfigure
{
uint8 tsjw;
uint8 tbs2 ;
uint8 tbs1;
uint8 mode;
uint16 brp;
};
struct CanSendConfigure
{
uint32 stdid;
uint32 exdid;
uint8 ide;
uint8 rtr;
uint8 data_lenth;
uint8 *data;
};
typedef struct
{
uint8_t *buffer;

View File

@ -66,9 +66,12 @@ Modification:
#include <connect_hwtimer.h>
#endif
#ifdef BSP_USING_CAN
#include <connect_can.h>
#endif
extern void entry(void);
extern int HwUsartInit();
extern int HwWdtInit();
/* Peripheral register WE/WP selection */
#define LL_PERIPH_SEL (LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | \
@ -189,6 +192,9 @@ struct InitSequenceDesc _board_init[] =
#endif
#ifdef BSP_USING_TIMER
{ "tmr", HwTimerInit },
#endif
#ifdef BSP_USING_CAN
{ "can", HwCanInit },
#endif
{ " NONE ", NONE },
};

View File

@ -77,3 +77,11 @@ menuconfig BSP_USING_TIMER
if BSP_USING_TIMER
source "$BSP_DIR/third_party_driver/timer/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

@ -40,4 +40,8 @@ ifeq ($(CONFIG_BSP_USING_TIMER),y)
SRC_DIR += timer
endif
ifeq ($(CONFIG_BSP_USING_CAN),y)
SRC_DIR += can
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,15 @@
config CAN_BUS_NAME_2
string "can bus name"
default "can2"
config CAN_DRIVER_NAME_2
string "can driver name"
default "can2_drv"
config CAN_2_DEVICE_NAME_1
string "can bus 1 device 1 name"
default "can2_dev1"
config CAN_USING_INTERRUPT
bool "can interrupt open"
default n

View File

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

View File

@ -0,0 +1,297 @@
/*
* Copyright (c) Guangzhou Xingyi Electronic Technology Co., Ltd
*
* Change Logs:
* Date Author Notes
* 2014-7-4 alientek first version
*/
/**
* @file connect_can.c
* @brief support hc32f4a0 can function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2023-02-20
*/
/*************************************************
File name: connect_can.c
Description: support can configure and spi bus register function for hc32f4a0
Others: connect_can.c for references
*************************************************/
#include "connect_can.h"
#define CAN_X (CM_CAN2)
#define CAN_TX_PORT (GPIO_PORT_D)
#define CAN_TX_PIN (GPIO_PIN_07)
#define CAN_RX_PORT (GPIO_PORT_D)
#define CAN_RX_PIN (GPIO_PIN_06)
#define CAN_TX_PIN_FUNC (GPIO_FUNC_62)
#define CAN_RX_PIN_FUNC (GPIO_FUNC_63)
#define INTSEL_REG ((uint32_t)(&CM_INTC->SEL0))
#define CANX_IRQ_SRC INT_SRC_CAN2_HOST
#define CANX_IRQ_NUM 17
#define IRQ_NUM_OFFSET 16
#define CAN_AF1_ID (0x123UL)
#define CAN_AF1_ID_MSK (0xFFFUL)
#define CAN_AF1_MSK_TYPE CAN_ID_STD
#define CAN_AF2_ID (0x005UL)
#define CAN_AF2_ID_MSK (0x00FUL)
#define CAN_AF2_MSK_TYPE CAN_ID_STD
#define CAN_AF3_ID (0x23UL)
#define CAN_AF3_ID_MSK (0xFFUL)
#define CAN_AF3_MSK_TYPE CAN_ID_STD
#ifdef CAN_USING_INTERRUPT
void CanIrqHandler(int vector, void *param)
{
stc_can_error_info_t err_info;
uint32_t status = CAN_GetStatusValue(CAN_X);
uint32_t error = CAN_GetErrorInfo(CAN_X,&err_info);
KPrintf("Irq entered\n");
CAN_ClearStatus(CAN_X, status);
}
static void CanIrqConfig(void)
{
// register IRQ src in IRQn
__IO uint32_t *INTC_SELx = (__IO uint32_t *)(INTSEL_REG+ 4U * (uint32_t)(CANX_IRQ_NUM));
WRITE_REG32(*INTC_SELx, CANX_IRQ_SRC);
isrManager.done->registerIrq(CANX_IRQ_NUM+IRQ_NUM_OFFSET,CanIrqHandler,NULL);
isrManager.done->enableIrq(CANX_IRQ_NUM);
}
#endif
static void CanInit(struct CanDriverConfigure *can_drv_config)
{
stc_can_init_t stcInit;
stc_can_filter_config_t astcAFCfg[] = { \
{CAN_AF1_ID, CAN_AF1_ID_MSK, CAN_AF1_MSK_TYPE}, \
{CAN_AF2_ID, CAN_AF2_ID_MSK, CAN_AF2_MSK_TYPE}, \
{CAN_AF3_ID, CAN_AF3_ID_MSK, CAN_AF3_MSK_TYPE}, \
};
CLK_SetCANClockSrc(CLK_CAN2,CLK_CANCLK_SYSCLK_DIV4);
/* Set the function of CAN pins. */
GPIO_SetFunc(CAN_TX_PORT, CAN_TX_PIN, CAN_TX_PIN_FUNC);
GPIO_SetFunc(CAN_RX_PORT, CAN_RX_PIN, CAN_RX_PIN_FUNC);
/* Initializes CAN. */
(void)CAN_StructInit(&stcInit);
stcInit.pstcFilter = astcAFCfg;
stcInit.u16FilterSelect = (CAN_FILTER1 | CAN_FILTER2 | CAN_FILTER3);
// Driver's config
stcInit.stcBitCfg.u32SJW = can_drv_config->tsjw;
stcInit.stcBitCfg.u32Prescaler = can_drv_config->brp;
stcInit.stcBitCfg.u32TimeSeg1 = can_drv_config->tbs1;
stcInit.stcBitCfg.u32TimeSeg2 = can_drv_config->tbs2;
stcInit.u8WorkMode = can_drv_config->mode;
#ifdef CAN_USING_FD
stcInit.stcFDCfg.u8TDCSSP = 16U;
stcInit.stcFDCfg.u8CANFDMode = CAN_FD_MODE_ISO_11898;
stcInit.stcFDCfg.stcFBT.u32SEG1 = 16U;
stcInit.stcFDCfg.stcFBT.u32SEG2 = 4U;
stcInit.stcFDCfg.stcFBT.u32SJW = 4U;
stcInit.stcFDCfg.stcFBT.u32Prescaler = 1U;
(void)CAN_FD_Init(APP_CAN_UNIT, &stcInit);
#else
FCG_Fcg1PeriphClockCmd(PWC_FCG1_CAN2, ENABLE);
(void)CAN_Init(CAN_X, &stcInit);
#endif
CAN_ClearStatus(CAN_X, 0xFFFF);
#ifdef CAN_USING_INTERRUPT
/* Configures the interrupts if needed. */
CAN_IntCmd(CAN_X, CAN_INT_RX, ENABLE);
CanIrqConfig();
#endif
}
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 CanWriteData(void * dev , struct BusBlockWriteParam *write_param)
{
x_err_t ret=EOK;
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(write_param);
struct CanSendConfigure *p_can_config = (struct CanSendConfigure*)write_param->buffer;
stc_can_tx_frame_t can_frame_obj;
memset(&can_frame_obj,0,sizeof(stc_can_tx_frame_t));
// configure CAN's flag bit
can_frame_obj.IDE = p_can_config->ide;
if(1==p_can_config->ide){
can_frame_obj.u32ID = p_can_config->exdid;
}else{
can_frame_obj.u32ID = p_can_config->stdid;
}
can_frame_obj.RTR = p_can_config->rtr;
memcpy(can_frame_obj.au8Data,p_can_config->data,p_can_config->data_lenth);
can_frame_obj.DLC = p_can_config->data_lenth;
//put frame_buffer in message queue
if(can_frame_obj.DLC){
ret = CAN_FillTxFrame(CAN_X,CAN_TX_BUF_STB,&can_frame_obj);
if(EOK != ret){
KPrintf("CAN fill tx frame failed(CODE:%d)!\n",ret);
return ERROR;
}
CAN_StartTx(CAN_X,CAN_TX_REQ_STB_ONE);
}
return ret;
}
static uint32 CanReadData(void *dev , struct BusBlockReadParam *databuf)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(databuf);
x_err_t ret=EOK;
stc_can_rx_frame_t frame_received;
struct CanSendConfigure *p_can_config = (struct CanSendConfigure*)databuf->buffer;
memset(&frame_received,0,sizeof(stc_can_rx_frame_t));
ret = CAN_GetRxFrame(CAN_X, &frame_received);
if(EOK != ret){
// KPrintf("CAN recv frame failed(CODE:%d)!\n",ret);
p_can_config->data_lenth = 0;
return ERROR;
}
//put message in frame_buffer
p_can_config->ide = frame_received.IDE;
p_can_config->rtr = frame_received.RTR;
if(p_can_config->ide==1){
p_can_config->exdid = frame_received.u32ID ;
}else{
p_can_config->stdid = frame_received.u32ID;
p_can_config->exdid = frame_received.u32ID ;
}
p_can_config->data_lenth = frame_received.DLC;
for(int i=0;i<p_can_config->data_lenth;i++){
p_can_config->data[i] = frame_received.au8Data[i];
}
return frame_received.DLC;
}
static struct CanDevDone can_dev_done =
{
.open = NONE,
.close = NONE,
.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_2);
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_2);
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_2, CAN_BUS_NAME_2);
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_device0;
memset(&can_device0, 0, sizeof(struct CanHardwareDevice));
can_device0.dev_done = &can_dev_done;
ret = CanDeviceRegister(&can_device0, NONE, CAN_2_DEVICE_NAME_1);
if (EOK != ret) {
KPrintf("board_can_init CanDeviceInit device %s error %d\n", CAN_2_DEVICE_NAME_1, ret);
return ERROR;
}
ret = CanDeviceAttachToBus(CAN_2_DEVICE_NAME_1, CAN_BUS_NAME_2);
if (EOK != ret) {
KPrintf("board_can_init CanDeviceAttachToBus device %s error %d\n", CAN_2_DEVICE_NAME_1, 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_2, ret);
return ERROR;
}
ret = BoardCanDevBend();
if (EOK != ret) {
KPrintf("board_can_init error ret %u\n", ret);
return ERROR;
}
return EOK;
}

View File

@ -36,4 +36,8 @@ ifeq ($(CONFIG_BSP_USING_WDT),y)
SRC_FILES += hc32_ll_wdt.c
endif
ifeq ($(CONFIG_BSP_USING_CAN),y)
SRC_FILES += hc32_ll_can.c
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,40 @@
/*
* 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 hc32f4a0-board can function and struct
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-02-21
*/
#ifndef CONNECT_CAN_H
#define CONNECT_CAN_H
#include <device.h>
#include <hc32_ll_can.h>
#include <hc32_ll_clk.h>
#include <hc32_ll_gpio.h>
#include <hardware_irq.h>
#ifdef __cplusplus
extern "C" {
#endif
int HwCanInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -19,7 +19,7 @@
*/
#include <connect_flash.h>
#define QSPI_DEVICE_SLAVE_ID_0 0
#define QSPI_DEVICE_SLAVE_ID_0 (0)
#define QSPI_UNIT (CM_QSPI)
#define QSPI_CS_PORT (GPIO_PORT_C)