apm32f103 fit can & uvcan with no shell
This commit is contained in:
parent
d0e822c757
commit
3f08641909
|
@ -18,6 +18,7 @@
|
|||
* @date: 2023/2/17
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
#ifdef ADD_XIZI_FEATURES
|
||||
|
@ -84,4 +85,51 @@ void TestCAN(void)
|
|||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestCAN, a can test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
||||
|
||||
void func_can(void)
|
||||
{
|
||||
int test2=0;
|
||||
KPrintf("%p\n", &test2);
|
||||
}
|
||||
|
||||
void TestcanMain(void)
|
||||
{
|
||||
KTaskDescriptorType task = NONE;
|
||||
task = GetKTaskDescriptor();
|
||||
KPrintf("TestcanMain task %x \n", task);
|
||||
KPrintf("TestcanMain task->Done %x \n", task->Done);
|
||||
int can_fd;
|
||||
KPrintf("Address of can_fd: %p\n", &can_fd);
|
||||
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
KPrintf("Address of ioctl_cfg: %p\n", &ioctl_cfg);
|
||||
|
||||
struct CanDriverConfigure can_config;
|
||||
KPrintf("Address of can_config: %p\n", &can_config);
|
||||
|
||||
uint8_t data_buff[64u] = {1,2,3,4,4,3,2,1};
|
||||
KPrintf("Address of data_buff: %p %ps\n", &data_buff, &data_buff[1]);
|
||||
|
||||
struct CanSendConfigure frame_send;
|
||||
KPrintf("Address of frame_send: %p\n", &frame_send);
|
||||
|
||||
struct CanSendConfigure frame_recv;
|
||||
KPrintf("Address of frame_recv: %p\n", &frame_recv);
|
||||
|
||||
uint8_t recv_buff[65U] = {0};
|
||||
KPrintf("Address of recv_buff: %p\n", &recv_buff);
|
||||
|
||||
func_can();
|
||||
KPrintf("add of func %p\n", func_can);
|
||||
|
||||
int *test;
|
||||
test = malloc(sizeof(int)*10);
|
||||
|
||||
task = GetKTaskDescriptor();
|
||||
KPrintf("TestcanMain task %x \n", task);
|
||||
KPrintf("TestcanMain task->Done %x \n", task->Done);
|
||||
}
|
||||
PRIV_SHELL_CMD_FUNCTION(TestcanMain, a shell CAN sample 1, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
||||
#endif
|
|
@ -20,8 +20,11 @@ extern int FrameworkInit();
|
|||
extern void ApplicationOtaTaskInit(void);
|
||||
int main(void)
|
||||
{
|
||||
printf("Hello, world! \n");
|
||||
int i=0;
|
||||
KPrintf("main KPrintf1\n");
|
||||
printf("Hello, world! %p\n",&i);
|
||||
FrameworkInit();
|
||||
TestcanMain();
|
||||
#ifdef APPLICATION_OTA
|
||||
ApplicationOtaTaskInit();
|
||||
#endif
|
||||
|
|
|
@ -96,10 +96,10 @@ InterruptVectors:
|
|||
.word IsrEntry
|
||||
.word IsrEntry
|
||||
.word IsrEntry
|
||||
.word IsrEntry
|
||||
.word IsrEntry
|
||||
.word IsrEntry
|
||||
.word IsrEntry
|
||||
.word IsrEntry // CAN1 发送中断处理函数 CAN1_TX_IRQHandler
|
||||
.word USB_LP_CAN1_RX0_IRQHandler // CAN1 接收中断0处理函数
|
||||
.word IsrEntry // CAN1 接收中断1处理函数 CAN1_RX1_IRQHandler
|
||||
.word IsrEntry // CAN1 状态变化中断处理函数 CAN1_SCE_IRQHandler
|
||||
.word IsrEntry
|
||||
.word IsrEntry
|
||||
.word IsrEntry
|
||||
|
|
|
@ -92,5 +92,7 @@ void InitBoardHardware()
|
|||
|
||||
InitBoardMemory((void*)HEAP_START, (void*)HEAP_END);
|
||||
InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME);
|
||||
|
||||
#ifdef BSP_USING_CAN
|
||||
InitHwCan();
|
||||
#endif // BSP_USING_CAN
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
|
||||
#include <stm32f1xx.h>
|
||||
#include <connect_uart.h>
|
||||
#ifdef BSP_USING_CAN
|
||||
#include <connect_can.h>
|
||||
#endif // BSP_USING_CAN
|
||||
|
||||
extern void *__bss_end;
|
||||
extern void *_heap_end;
|
||||
|
|
|
@ -0,0 +1,290 @@
|
|||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# XiZi_IIoT Project Configuration
|
||||
#
|
||||
CONFIG_BOARD_STM32F103_NANO=y
|
||||
CONFIG_ARCH_ARM=y
|
||||
|
||||
#
|
||||
# stm32f103-nano feature
|
||||
#
|
||||
CONFIG_BSP_USING_UART=y
|
||||
# CONFIG_BSP_USING_UART1 is not set
|
||||
CONFIG_BSP_USING_UART2=y
|
||||
CONFIG_SERIAL_BUS_NAME_2="uart2"
|
||||
CONFIG_SERIAL_DRV_NAME_2="uart2_drv"
|
||||
CONFIG_SERIAL_2_DEVICE_NAME_0="uart2_dev2"
|
||||
CONFIG_BSP_USING_CAN=y
|
||||
CONFIG_CAN_BUS_NAME_1="can1"
|
||||
CONFIG_CAN_DRIVER_NAME="can1_drv"
|
||||
CONFIG_CAN_1_DEVICE_NAME_1="can1_dev1"
|
||||
|
||||
#
|
||||
# config default board resources
|
||||
#
|
||||
|
||||
#
|
||||
# config board app name
|
||||
#
|
||||
CONFIG_BOARD_APP_NAME="/XiUOS_stm32f103nano_app.bin"
|
||||
|
||||
#
|
||||
# config board service table
|
||||
#
|
||||
CONFIG_SERVICE_TABLE_ADDRESS=0x20000000
|
||||
|
||||
#
|
||||
# Hardware feature
|
||||
#
|
||||
CONFIG_RESOURCES_SERIAL=y
|
||||
# CONFIG_SERIAL_USING_DMA is not set
|
||||
CONFIG_SERIAL_RB_BUFSZ=128
|
||||
CONFIG_RESOURCES_CAN=y
|
||||
|
||||
#
|
||||
# Kernel feature
|
||||
#
|
||||
|
||||
#
|
||||
# separate compile(choose none for compile once)
|
||||
#
|
||||
# CONFIG_SEPARATE_COMPILE is not set
|
||||
# CONFIG_COMPILER_APP is not set
|
||||
# CONFIG_APP_STARTUP_FROM_SDCARD is not set
|
||||
CONFIG_APP_STARTUP_FROM_FLASH=y
|
||||
# CONFIG_COMPILER_KERNEL is not set
|
||||
|
||||
#
|
||||
# Memory Management
|
||||
#
|
||||
# CONFIG_KERNEL_MEMBLOCK is not set
|
||||
CONFIG_MEM_ALIGN_SIZE=8
|
||||
# CONFIG_MEM_EXTERN_SRAM is not set
|
||||
CONFIG_MM_PAGE_SIZE=4096
|
||||
|
||||
#
|
||||
# Using small memory allocator
|
||||
#
|
||||
CONFIG_KERNEL_SMALL_MEM_ALLOC=y
|
||||
CONFIG_SMALL_NUMBER_32B=64
|
||||
CONFIG_SMALL_NUMBER_64B=32
|
||||
|
||||
#
|
||||
# Task feature
|
||||
#
|
||||
CONFIG_USER_APPLICATION=y
|
||||
# CONFIG_TASK_ISOLATION is not set
|
||||
|
||||
#
|
||||
# Inter-Task communication
|
||||
#
|
||||
CONFIG_KERNEL_SEMAPHORE=y
|
||||
CONFIG_KERNEL_MUTEX=y
|
||||
CONFIG_KERNEL_EVENT=y
|
||||
CONFIG_KERNEL_MESSAGEQUEUE=y
|
||||
CONFIG_KERNEL_SOFTTIMER=y
|
||||
CONFIG_SCHED_POLICY_RR_REMAINSLICE=y
|
||||
# CONFIG_SCHED_POLICY_RR is not set
|
||||
# CONFIG_SCHED_POLICY_FIFO is not set
|
||||
# CONFIG_KTASK_PRIORITY_8 is not set
|
||||
CONFIG_KTASK_PRIORITY_32=y
|
||||
# CONFIG_KTASK_PRIORITY_256 is not set
|
||||
CONFIG_KTASK_PRIORITY_MAX=32
|
||||
CONFIG_TICK_PER_SECOND=1000
|
||||
CONFIG_KERNEL_STACK_OVERFLOW_CHECK=y
|
||||
CONFIG_IDLE_KTASK_STACKSIZE=256
|
||||
CONFIG_ZOMBIE_KTASK_STACKSIZE=512
|
||||
|
||||
#
|
||||
# Kernel Console
|
||||
#
|
||||
CONFIG_KERNEL_CONSOLE=y
|
||||
CONFIG_KERNEL_BANNER=y
|
||||
CONFIG_KERNEL_CONSOLEBUF_SIZE=128
|
||||
|
||||
#
|
||||
# Kernel Hook
|
||||
#
|
||||
# CONFIG_KERNEL_HOOK is not set
|
||||
|
||||
#
|
||||
# Command shell
|
||||
#
|
||||
CONFIG_TOOL_SHELL=y
|
||||
CONFIG_SHELL_ENTER_CR=y
|
||||
CONFIG_SHELL_ENTER_LF=y
|
||||
CONFIG_SHELL_ENTER_CR_AND_LF=y
|
||||
# CONFIG_SHELL_ENTER_CRLF is not set
|
||||
|
||||
#
|
||||
# Set shell user control
|
||||
#
|
||||
CONFIG_SHELL_DEFAULT_USER="letter"
|
||||
CONFIG_SHELL_DEFAULT_USER_PASSWORD=""
|
||||
CONFIG_SHELL_LOCK_TIMEOUT=10000
|
||||
|
||||
#
|
||||
# Set shell config param
|
||||
#
|
||||
CONFIG_SHELL_TASK_STACK_SIZE=512
|
||||
CONFIG_SHELL_TASK_PRIORITY=20
|
||||
CONFIG_SHELL_MAX_NUMBER=5
|
||||
CONFIG_SHELL_PARAMETER_MAX_NUMBER=8
|
||||
CONFIG_SHELL_HISTORY_MAX_NUMBER=5
|
||||
CONFIG_SHELL_PRINT_BUFFER=128
|
||||
CONFIG_SHELL_HELP_SHOW_PERMISSION=y
|
||||
# CONFIG_SHELL_HELP_LIST_USER is not set
|
||||
# CONFIG_SHELL_HELP_LIST_VAR is not set
|
||||
# CONFIG_SHELL_HELP_LIST_KEY is not set
|
||||
|
||||
#
|
||||
# Kernel data structure Manage
|
||||
#
|
||||
CONFIG_KERNEL_QUEUEMANAGE=y
|
||||
CONFIG_KERNEL_WORKQUEUE=y
|
||||
CONFIG_WORKQUEUE_KTASK_STACKSIZE=2048
|
||||
CONFIG_WORKQUEUE_KTASK_PRIORITY=23
|
||||
CONFIG_QUEUE_MAX=16
|
||||
CONFIG_KERNEL_WAITQUEUE=y
|
||||
CONFIG_KERNEL_DATAQUEUE=y
|
||||
# CONFIG_KERNEL_CIRCULAR_AREA is not set
|
||||
# CONFIG_KERNEL_AVL_TREE is not set
|
||||
|
||||
#
|
||||
# Kernel components init
|
||||
#
|
||||
CONFIG_KERNEL_COMPONENTS_INIT=y
|
||||
CONFIG_ENV_INIT_KTASK_STACK_SIZE=512
|
||||
CONFIG_KERNEL_USER_MAIN=y
|
||||
CONFIG_NAME_NUM_MAX=32
|
||||
# CONFIG_KERNEL_DEBUG is not set
|
||||
# CONFIG_ARCH_SMP is not set
|
||||
|
||||
#
|
||||
# hash table config
|
||||
#
|
||||
CONFIG_ID_HTABLE_SIZE=16
|
||||
CONFIG_ID_NUM_MAX=128
|
||||
# CONFIG_KERNEL_TEST is not set
|
||||
|
||||
#
|
||||
# Kernel Lib
|
||||
#
|
||||
CONFIG_LIB=y
|
||||
CONFIG_LIB_POSIX=y
|
||||
CONFIG_LIB_NEWLIB=y
|
||||
# CONFIG_LIB_MUSLLIB is not set
|
||||
# CONFIG_LIB_OTHER is not set
|
||||
|
||||
#
|
||||
# C++ features
|
||||
#
|
||||
# CONFIG_LIB_CPLUSPLUS is not set
|
||||
|
||||
#
|
||||
# File system
|
||||
#
|
||||
# CONFIG_FS_VFS is not set
|
||||
|
||||
#
|
||||
# Tool feature
|
||||
#
|
||||
|
||||
#
|
||||
# OTA function
|
||||
#
|
||||
# CONFIG_TOOL_USING_OTA is not set
|
||||
|
||||
#
|
||||
# APP_Framework
|
||||
#
|
||||
|
||||
#
|
||||
# Framework
|
||||
#
|
||||
CONFIG_TRANSFORM_LAYER_ATTRIUBUTE=y
|
||||
CONFIG_ADD_XIZI_FEATURES=y
|
||||
# CONFIG_ADD_NUTTX_FEATURES is not set
|
||||
# CONFIG_ADD_RTTHREAD_FEATURES is not set
|
||||
# CONFIG_SUPPORT_SENSOR_FRAMEWORK is not set
|
||||
# CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set
|
||||
# CONFIG_SUPPORT_KNOWING_FRAMEWORK is not set
|
||||
# CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set
|
||||
|
||||
#
|
||||
# Security
|
||||
#
|
||||
# CONFIG_CRYPTO is not set
|
||||
# CONFIG_MBEDTLS is not set
|
||||
|
||||
#
|
||||
# Applications
|
||||
#
|
||||
|
||||
#
|
||||
# config stack size and priority of main task
|
||||
#
|
||||
CONFIG_MAIN_KTASK_STACK_SIZE=256
|
||||
CONFIG_MAIN_KTASK_PRIORITY=16
|
||||
|
||||
#
|
||||
# ota app
|
||||
#
|
||||
# CONFIG_APPLICATION_OTA is not set
|
||||
|
||||
#
|
||||
# test app
|
||||
#
|
||||
# CONFIG_USER_TEST is not set
|
||||
|
||||
#
|
||||
# connection app
|
||||
#
|
||||
# CONFIG_APPLICATION_CONNECTION is not set
|
||||
|
||||
#
|
||||
# control app
|
||||
#
|
||||
|
||||
#
|
||||
# knowing app
|
||||
#
|
||||
# CONFIG_APPLICATION_KNOWING is not set
|
||||
|
||||
#
|
||||
# sensor app
|
||||
#
|
||||
# CONFIG_APPLICATION_SENSOR is not set
|
||||
# CONFIG_USING_EMBEDDED_DATABASE_APP is not set
|
||||
# CONFIG_APP_USING_WEBNET is not set
|
||||
|
||||
#
|
||||
# app lib
|
||||
#
|
||||
CONFIG_APP_SELECT_NEWLIB=y
|
||||
# CONFIG_APP_SELECT_OTHER_LIB is not set
|
||||
|
||||
#
|
||||
# lib using cJSON
|
||||
#
|
||||
# CONFIG_LIB_USING_CJSON is not set
|
||||
|
||||
#
|
||||
# lib using queue
|
||||
#
|
||||
# CONFIG_LIB_USING_QUEUE is not set
|
||||
|
||||
#
|
||||
# lib using LVGL
|
||||
#
|
||||
# CONFIG_LIB_LV is not set
|
||||
|
||||
#
|
||||
# lib using embedded_database
|
||||
#
|
||||
# CONFIG_USING_EMBEDDED_DATABASE is not set
|
||||
|
||||
#
|
||||
# lib using LoRaWan
|
||||
#
|
||||
# CONFIG_LIB_USING_LORAWAN is not set
|
|
@ -5,7 +5,7 @@
|
|||
/* Program Entry, set to mark it as "used" and avoid gc */
|
||||
MEMORY
|
||||
{
|
||||
flash (rx) : ORIGIN = 0x08004000, LENGTH = 112k /* 128KB flash */
|
||||
flash (rx) : ORIGIN = 0x08000000, LENGTH = 128k /* 128KB flash */
|
||||
sram (rw) : ORIGIN = 0x20000000, LENGTH = 20k /* 20K sram */
|
||||
}
|
||||
OUTPUT_ARCH(arm)
|
||||
|
|
|
@ -5,3 +5,12 @@ select RESOURCES_SERIAL
|
|||
if BSP_USING_UART
|
||||
source "$BSP_DIR/third_party_driver/uart/Kconfig"
|
||||
endif
|
||||
|
||||
|
||||
menuconfig BSP_USING_CAN
|
||||
bool "Using CAN device"
|
||||
default y
|
||||
select RESOURCES_CAN
|
||||
if BSP_USING_CAN
|
||||
source "$BSP_DIR/third_party_driver/can/Kconfig"
|
||||
endif
|
||||
|
|
|
@ -3,6 +3,7 @@ SRC_DIR := libraries
|
|||
ifeq ($(CONFIG_BSP_USING_UART),y)
|
||||
SRC_DIR += uart
|
||||
SRC_DIR += common
|
||||
SRC_DIR += can
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -1,30 +1,11 @@
|
|||
menuconfig BSP_USING_CAN
|
||||
bool "Enable UART1"
|
||||
default y
|
||||
if BSP_USING_UART1
|
||||
config SERIAL_BUS_NAME_1
|
||||
string "serial bus 1 name"
|
||||
default "uart1"
|
||||
config SERIAL_DRV_NAME_1
|
||||
string "serial bus 1 driver name"
|
||||
default "uart1_drv"
|
||||
config SERIAL_1_DEVICE_NAME_0
|
||||
string "serial bus 1 device name"
|
||||
default "uart1_dev1"
|
||||
endif
|
||||
config CAN_BUS_NAME_1
|
||||
string "can bus name"
|
||||
default "can1"
|
||||
|
||||
menuconfig BSP_USING_UART2
|
||||
bool "Enable UART2"
|
||||
default n
|
||||
if BSP_USING_UART2
|
||||
config SERIAL_BUS_NAME_2
|
||||
string "serial bus 2 name"
|
||||
default "uart2"
|
||||
config SERIAL_DRV_NAME_2
|
||||
string "serial bus 2 driver name"
|
||||
default "uart2_drv"
|
||||
config SERIAL_2_DEVICE_NAME_0
|
||||
string "serial bus 2 device name"
|
||||
default "uart2_dev2"
|
||||
endif
|
||||
config CAN_DRIVER_NAME
|
||||
string "can driver name"
|
||||
default "can1_drv"
|
||||
|
||||
config CAN_1_DEVICE_NAME_1
|
||||
string "can bus 1 device 1 name"
|
||||
default "can1_dev1"
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
SRC_FILES := connect_can.c
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -1,438 +1,285 @@
|
|||
/*
|
||||
* 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_uart.c
|
||||
* @brief support stm32f103_nano board uart function and register to bus framework
|
||||
* @version 1.1
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-11-25
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include <connect_uart.h>
|
||||
#include <connect_can.h>
|
||||
|
||||
#ifdef BSP_USING_UART1
|
||||
static struct SerialBus serial_bus_1;
|
||||
static struct SerialDriver serial_driver_1;
|
||||
static struct SerialHardwareDevice serial_device_1;
|
||||
#endif
|
||||
#ifdef BSP_USING_UART2
|
||||
static struct SerialBus serial_bus_2;
|
||||
static struct SerialDriver serial_driver_2;
|
||||
static struct SerialHardwareDevice serial_device_2;
|
||||
#endif
|
||||
// #ifdef BSP_USING_CAN1 - TODO change to struct Stm32Can
|
||||
|
||||
static void SerialCfgParamCheck(struct SerialCfgParam *serial_cfg_default, struct SerialCfgParam *serial_cfg_new)
|
||||
{
|
||||
struct SerialDataCfg *data_cfg_default = &serial_cfg_default->data_cfg;
|
||||
struct SerialDataCfg *data_cfg_new = &serial_cfg_new->data_cfg;
|
||||
static struct Stm32Can *stm32_can1;
|
||||
|
||||
if ((data_cfg_default->serial_baud_rate != data_cfg_new->serial_baud_rate) && (data_cfg_new->serial_baud_rate)) {
|
||||
data_cfg_default->serial_baud_rate = data_cfg_new->serial_baud_rate;
|
||||
}
|
||||
// #endif // BSP_USING_CAN1
|
||||
|
||||
if ((data_cfg_default->serial_bit_order != data_cfg_new->serial_bit_order) && (data_cfg_new->serial_bit_order)) {
|
||||
data_cfg_default->serial_bit_order = data_cfg_new->serial_bit_order;
|
||||
}
|
||||
|
||||
if ((data_cfg_default->serial_buffer_size != data_cfg_new->serial_buffer_size) && (data_cfg_new->serial_buffer_size)) {
|
||||
data_cfg_default->serial_buffer_size = data_cfg_new->serial_buffer_size;
|
||||
}
|
||||
|
||||
if ((data_cfg_default->serial_data_bits != data_cfg_new->serial_data_bits) && (data_cfg_new->serial_data_bits)) {
|
||||
data_cfg_default->serial_data_bits = data_cfg_new->serial_data_bits;
|
||||
}
|
||||
|
||||
if ((data_cfg_default->serial_invert_mode != data_cfg_new->serial_invert_mode) && (data_cfg_new->serial_invert_mode)) {
|
||||
data_cfg_default->serial_invert_mode = data_cfg_new->serial_invert_mode;
|
||||
}
|
||||
|
||||
if ((data_cfg_default->serial_parity_mode != data_cfg_new->serial_parity_mode) && (data_cfg_new->serial_parity_mode)) {
|
||||
data_cfg_default->serial_parity_mode = data_cfg_new->serial_parity_mode;
|
||||
}
|
||||
|
||||
if ((data_cfg_default->serial_stop_bits != data_cfg_new->serial_stop_bits) && (data_cfg_new->serial_stop_bits)) {
|
||||
data_cfg_default->serial_stop_bits = data_cfg_new->serial_stop_bits;
|
||||
}
|
||||
|
||||
if ((data_cfg_default->serial_timeout != data_cfg_new->serial_timeout) && (data_cfg_new->serial_timeout)) {
|
||||
data_cfg_default->serial_timeout = data_cfg_new->serial_timeout;
|
||||
}
|
||||
}
|
||||
|
||||
static void UartHandler(struct SerialBus *serial_bus, struct SerialDriver *serial_drv)
|
||||
{
|
||||
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_bus->bus.owner_haldev;
|
||||
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data;
|
||||
struct Stm32UartHwCfg *serial_hw_cfg = (struct Stm32UartHwCfg *)serial_cfg->hw_cfg.private_data;
|
||||
|
||||
/* UART in mode Receiver -------------------------------------------------*/
|
||||
if ((__HAL_UART_GET_FLAG(&(serial_hw_cfg->uart_handle), UART_FLAG_RXNE) != RESET) &&
|
||||
(__HAL_UART_GET_IT_SOURCE(&(serial_hw_cfg->uart_handle), UART_IT_RXNE) != RESET))
|
||||
{
|
||||
SerialSetIsr(serial_dev, SERIAL_EVENT_RX_IND);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__HAL_UART_GET_FLAG(&(serial_hw_cfg->uart_handle), UART_FLAG_ORE) != RESET)
|
||||
{
|
||||
__HAL_UART_CLEAR_OREFLAG(&serial_hw_cfg->uart_handle);
|
||||
}
|
||||
if (__HAL_UART_GET_FLAG(&(serial_hw_cfg->uart_handle), UART_FLAG_NE) != RESET)
|
||||
{
|
||||
__HAL_UART_CLEAR_NEFLAG(&serial_hw_cfg->uart_handle);
|
||||
}
|
||||
if (__HAL_UART_GET_FLAG(&(serial_hw_cfg->uart_handle), UART_FLAG_FE) != RESET)
|
||||
{
|
||||
__HAL_UART_CLEAR_FEFLAG(&serial_hw_cfg->uart_handle);
|
||||
}
|
||||
if (__HAL_UART_GET_FLAG(&(serial_hw_cfg->uart_handle), UART_FLAG_PE) != RESET)
|
||||
{
|
||||
__HAL_UART_CLEAR_PEFLAG(&serial_hw_cfg->uart_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSP_USING_UART1
|
||||
void UartIsr1(int vector, void *param)
|
||||
{
|
||||
/* get serial bus 1 */
|
||||
UartHandler(&serial_bus_1, &serial_driver_1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_UART2
|
||||
void UartIsr2(int vector, void *param)
|
||||
{
|
||||
/* get serial bus 2 */
|
||||
UartHandler(&serial_bus_2, &serial_driver_2);
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32 SerialInit(struct SerialDriver *serial_drv, struct BusConfigureInfo *configure_info)
|
||||
{
|
||||
NULL_PARAM_CHECK(serial_drv);
|
||||
|
||||
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data;
|
||||
struct Stm32UartHwCfg *serial_hw_cfg = (struct Stm32UartHwCfg *)serial_cfg->hw_cfg.private_data;
|
||||
|
||||
if (configure_info->private_data) {
|
||||
struct SerialCfgParam *serial_cfg_new = (struct SerialCfgParam *)configure_info->private_data;
|
||||
SerialCfgParamCheck(serial_cfg, serial_cfg_new);
|
||||
}
|
||||
|
||||
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_drv->driver.owner_bus->owner_haldev;
|
||||
struct SerialDevParam *dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data;
|
||||
|
||||
// config serial receive sem timeout
|
||||
dev_param->serial_timeout = serial_cfg->data_cfg.serial_timeout;
|
||||
|
||||
serial_hw_cfg->uart_handle.Instance = serial_hw_cfg->uart_device;
|
||||
serial_hw_cfg->uart_handle.Init.BaudRate = serial_cfg->data_cfg.serial_baud_rate;
|
||||
serial_hw_cfg->uart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
serial_hw_cfg->uart_handle.Init.Mode = UART_MODE_TX_RX;
|
||||
serial_hw_cfg->uart_handle.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
|
||||
switch (serial_cfg->data_cfg.serial_data_bits)
|
||||
{
|
||||
case DATA_BITS_8:
|
||||
if (serial_cfg->data_cfg.serial_parity_mode == PARITY_ODD || serial_cfg->data_cfg.serial_parity_mode == PARITY_EVEN)
|
||||
serial_hw_cfg->uart_handle.Init.WordLength = UART_WORDLENGTH_9B;
|
||||
else
|
||||
serial_hw_cfg->uart_handle.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
break;
|
||||
case DATA_BITS_9:
|
||||
serial_hw_cfg->uart_handle.Init.WordLength = UART_WORDLENGTH_9B;
|
||||
break;
|
||||
default:
|
||||
serial_hw_cfg->uart_handle.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (serial_cfg->data_cfg.serial_stop_bits)
|
||||
{
|
||||
case STOP_BITS_1:
|
||||
serial_hw_cfg->uart_handle.Init.StopBits = UART_STOPBITS_1;
|
||||
break;
|
||||
case STOP_BITS_2:
|
||||
serial_hw_cfg->uart_handle.Init.StopBits = UART_STOPBITS_2;
|
||||
break;
|
||||
default:
|
||||
serial_hw_cfg->uart_handle.Init.StopBits = UART_STOPBITS_1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (serial_cfg->data_cfg.serial_parity_mode)
|
||||
{
|
||||
case PARITY_NONE:
|
||||
serial_hw_cfg->uart_handle.Init.Parity = UART_PARITY_NONE;
|
||||
break;
|
||||
case PARITY_ODD:
|
||||
serial_hw_cfg->uart_handle.Init.Parity = UART_PARITY_ODD;
|
||||
break;
|
||||
case PARITY_EVEN:
|
||||
serial_hw_cfg->uart_handle.Init.Parity = UART_PARITY_EVEN;
|
||||
break;
|
||||
default:
|
||||
serial_hw_cfg->uart_handle.Init.Parity = UART_PARITY_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (HAL_UART_Init(&serial_hw_cfg->uart_handle) != HAL_OK)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 SerialConfigure(struct SerialDriver *serial_drv, int serial_operation_cmd)
|
||||
{
|
||||
NULL_PARAM_CHECK(serial_drv);
|
||||
|
||||
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_drv->driver.owner_bus->owner_haldev;
|
||||
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data;
|
||||
struct Stm32UartHwCfg *serial_hw_cfg = (struct Stm32UartHwCfg *)serial_cfg->hw_cfg.private_data;
|
||||
struct SerialDevParam *serial_dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data;
|
||||
|
||||
if (OPER_CLR_INT == serial_operation_cmd) {
|
||||
if (SIGN_OPER_INT_RX & serial_dev_param->serial_work_mode) {
|
||||
/* disable rx irq */
|
||||
NVIC_DisableIRQ(serial_hw_cfg->irq_type);
|
||||
/* disable interrupt */
|
||||
__HAL_UART_DISABLE_IT(&(serial_hw_cfg->uart_handle), UART_IT_RXNE);
|
||||
}
|
||||
} else if (OPER_SET_INT == serial_operation_cmd) {
|
||||
/* enable rx irq */
|
||||
HAL_NVIC_SetPriority(serial_hw_cfg->irq_type, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(serial_hw_cfg->irq_type);
|
||||
/* enable interrupt */
|
||||
__HAL_UART_ENABLE_IT(&(serial_hw_cfg->uart_handle), UART_IT_RXNE);
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 SerialDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
|
||||
static unsigned int CanModeInit(void *drv, struct BusConfigureInfo *configure_info)
|
||||
{
|
||||
NULL_PARAM_CHECK(drv);
|
||||
NULL_PARAM_CHECK(configure_info);
|
||||
|
||||
x_err_t ret = EOK;
|
||||
int serial_operation_cmd;
|
||||
struct SerialDriver *serial_drv = (struct SerialDriver *)drv;
|
||||
|
||||
switch (configure_info->configure_cmd)
|
||||
struct CanDriverConfigure *config = (struct CanDriverConfigure *)configure_info->private_data;
|
||||
struct CanDriver *can_drv = (struct CanDriver *)drv;
|
||||
CAN_HandleTypeDef *hcan1 = &(stm32_can1->instance);
|
||||
// hcan1->Instance = CAN1;
|
||||
// hcan1->Init.Prescaler = config->brp;
|
||||
// hcan1->Init.Mode = config->mode;
|
||||
// hcan1->Init.SyncJumpWidth = config->tsjw;
|
||||
// hcan1->Init.TimeSeg1 = config->tbs1;
|
||||
// hcan1->Init.TimeSeg2 = config->tbs2;
|
||||
// hcan1->Init.TimeTriggeredMode = DISABLE;
|
||||
// hcan1->Init.AutoBusOff = ENABLE;
|
||||
// hcan1->Init.AutoWakeUp = ENABLE;
|
||||
// hcan1->Init.AutoRetransmission = DISABLE;
|
||||
// hcan1->Init.ReceiveFifoLocked = DISABLE;
|
||||
// hcan1->Init.TransmitFifoPriority = DISABLE;
|
||||
hcan1->Instance = CAN1;
|
||||
hcan1->Init.Prescaler = 6;
|
||||
hcan1->Init.Mode = CAN_MODE_NORMAL;
|
||||
hcan1->Init.SyncJumpWidth = CAN_SJW_1TQ;
|
||||
hcan1->Init.TimeSeg1 = CAN_BS1_6TQ;
|
||||
hcan1->Init.TimeSeg2 = CAN_BS2_5TQ;
|
||||
hcan1->Init.TimeTriggeredMode = DISABLE;
|
||||
hcan1->Init.AutoBusOff = DISABLE;
|
||||
hcan1->Init.AutoWakeUp = DISABLE;
|
||||
hcan1->Init.AutoRetransmission = DISABLE;
|
||||
hcan1->Init.ReceiveFifoLocked = DISABLE;
|
||||
hcan1->Init.TransmitFifoPriority = DISABLE;
|
||||
if (HAL_CAN_Init(hcan1) != HAL_OK)
|
||||
{
|
||||
case OPE_INT:
|
||||
ret = SerialInit(serial_drv, configure_info);
|
||||
break;
|
||||
case OPE_CFG:
|
||||
serial_operation_cmd = *(int *)configure_info->private_data;
|
||||
ret = SerialConfigure(serial_drv, serial_operation_cmd);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
CAN_FilterTypeDef sFilterConfig;
|
||||
sFilterConfig.FilterBank = 0; /* 过滤器组0 */
|
||||
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; /* 屏蔽位模式 */
|
||||
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; /* 32位。*/
|
||||
// sFilterConfig.FilterIdHigh = (((uint32_t)CAN_RxExtId << 3) & 0xFFFF0000) >> 16; /* 要过滤的ID高位 */
|
||||
// sFilterConfig.FilterIdLow = (((uint32_t)CAN_RxExtId << 3) | CAN_ID_EXT | CAN_RTR_DATA) & 0xFFFF; /* 要过滤的ID低位 */
|
||||
// sFilterConfig.FilterMaskIdHigh = 0xFFFF; /* 过滤器高16位每位必须匹配 */
|
||||
// sFilterConfig.FilterMaskIdLow = 0xFFFF; /* 过滤器低16位每位必须匹配 */
|
||||
sFilterConfig.FilterIdHigh = 0x0000;
|
||||
sFilterConfig.FilterIdLow = 0x0000;
|
||||
sFilterConfig.FilterMaskIdHigh = 0x0000;
|
||||
sFilterConfig.FilterMaskIdLow = 0x0000;
|
||||
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; /* 过滤器被关联到FIFO 0 */
|
||||
sFilterConfig.FilterActivation = ENABLE; /* 使能过滤器 */
|
||||
sFilterConfig.SlaveStartFilterBank = 14;
|
||||
if (HAL_CAN_ConfigFilter(hcan1, &sFilterConfig) != HAL_OK)
|
||||
{
|
||||
/* Filter configuration Error */
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (HAL_CAN_Start(hcan1) != HAL_OK)
|
||||
{
|
||||
/* Start Error */
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*##-4- Activate CAN RX notification #######################################*/
|
||||
if (HAL_CAN_ActivateNotification(hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
|
||||
{
|
||||
/* Start Error */
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static int SerialPutChar(struct SerialHardwareDevice *serial_dev, char c)
|
||||
static uint32 CanOpen(void *dev)
|
||||
{
|
||||
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
|
||||
struct Stm32UartHwCfg *serial_hw_cfg = (struct Stm32UartHwCfg *)serial_cfg->hw_cfg.private_data;
|
||||
KPrintf("Can open\n");
|
||||
KTaskDescriptorType task = NONE;
|
||||
task = GetKTaskDescriptor();
|
||||
KPrintf("CanOpen MdelayKTask2 %x\n", task);
|
||||
KPrintf("CanOpen task->Done %x \n", task->Done);
|
||||
return 0;
|
||||
}
|
||||
|
||||
UART_INSTANCE_CLEAR_FUNCTION(&(serial_hw_cfg->uart_handle), UART_FLAG_TC);
|
||||
static uint32 CanClose(void *dev)
|
||||
{
|
||||
KPrintf("Can close\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
serial_hw_cfg->uart_handle.Instance->DR = c;
|
||||
while (__HAL_UART_GET_FLAG(&(serial_hw_cfg->uart_handle), UART_FLAG_TC) == RESET);
|
||||
static uint32 CanSendMsg(void *dev, struct BusBlockWriteParam *write_param)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
|
||||
CAN_HandleTypeDef *hcan1 = &(stm32_can1->instance);
|
||||
uint8_t i = 0;
|
||||
uint32_t TxMailbox;
|
||||
uint8_t message[8];
|
||||
uint8_t *data = (uint8 *)write_param->buffer;
|
||||
uint16_t timer_count = 1000;
|
||||
CAN_TxHeaderTypeDef TxHeader; // 发送
|
||||
|
||||
TxHeader.ExtId = CAN_TxExtId; // 扩展标识符(29位)
|
||||
TxHeader.IDE = CAN_ID_EXT; // 使用扩展帧
|
||||
TxHeader.RTR = CAN_RTR_DATA; // 数据帧
|
||||
TxHeader.DLC = write_param->size;
|
||||
TxHeader.TransmitGlobalTime = DISABLE;
|
||||
|
||||
for (i = 0; i < TxHeader.DLC; i++)
|
||||
{
|
||||
message[i] = data[i];
|
||||
}
|
||||
|
||||
if (HAL_CAN_AddTxMessage(hcan1, &TxHeader, message, &TxMailbox) != HAL_OK) // 发送
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
while (HAL_CAN_GetTxMailboxesFreeLevel(hcan1) != 3 && timer_count)
|
||||
{
|
||||
timer_count--;
|
||||
}
|
||||
if (timer_count <= 0)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static int SerialGetChar(struct SerialHardwareDevice *serial_dev)
|
||||
{
|
||||
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
|
||||
struct Stm32UartHwCfg *serial_hw_cfg = (struct Stm32UartHwCfg *)serial_cfg->hw_cfg.private_data;
|
||||
|
||||
int ch = -1;
|
||||
if (__HAL_UART_GET_FLAG(&(serial_hw_cfg->uart_handle), UART_FLAG_RXNE) != RESET)
|
||||
static uint32 CanRecvMsg(void *dev, struct BusBlockReadParam *databuf)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
NULL_PARAM_CHECK(databuf);
|
||||
int size = stm32_can1->can_recv_flag;
|
||||
int i;
|
||||
uint8_t *buf = (uint8 *)(databuf->buffer);
|
||||
if (size != 0)
|
||||
{
|
||||
ch = serial_hw_cfg->uart_handle.Instance->DR & 0xff;
|
||||
for(i=0;i<size;i++)
|
||||
{
|
||||
buf[i]=stm32_can1->can_Rx_Data[i];
|
||||
//KPrintf("0x%02x ", buf[i]);
|
||||
stm32_can1->can_Rx_Data[i]=0;
|
||||
}
|
||||
//KPrintf("\n");
|
||||
|
||||
stm32_can1->can_recv_flag = 0;
|
||||
}
|
||||
return ch;
|
||||
return size;
|
||||
}
|
||||
|
||||
static const struct SerialDataCfg data_cfg_init =
|
||||
{
|
||||
.serial_baud_rate = BAUD_RATE_115200,
|
||||
.serial_data_bits = DATA_BITS_8,
|
||||
.serial_stop_bits = STOP_BITS_1,
|
||||
.serial_parity_mode = PARITY_NONE,
|
||||
.serial_bit_order = BIT_ORDER_LSB,
|
||||
.serial_invert_mode = NRZ_NORMAL,
|
||||
.serial_buffer_size = SERIAL_RB_BUFSZ,
|
||||
.serial_timeout = WAITING_FOREVER,
|
||||
};
|
||||
static struct CanDevDone can_dev_done =
|
||||
{
|
||||
.open = CanOpen,//None
|
||||
.close = CanClose,
|
||||
.write = CanSendMsg,
|
||||
.read = CanRecvMsg
|
||||
};
|
||||
|
||||
/*manage the serial device operations*/
|
||||
static const struct SerialDrvDone drv_done =
|
||||
{
|
||||
.init = SerialInit,
|
||||
.configure = SerialConfigure,
|
||||
};
|
||||
|
||||
/*manage the serial device hal operations*/
|
||||
static struct SerialHwDevDone hwdev_done =
|
||||
{
|
||||
.put_char = SerialPutChar,
|
||||
.get_char = SerialGetChar,
|
||||
};
|
||||
// #ifdef BSP_USING_CAN1
|
||||
|
||||
static int BoardSerialBusInit(struct SerialBus *serial_bus, struct SerialDriver *serial_driver, const char *bus_name, const char *drv_name)
|
||||
void USB_LP_CAN1_RX0_IRQHandler(void)
|
||||
{
|
||||
HAL_CAN_IRQHandler(&(stm32_can1->instance));
|
||||
}
|
||||
|
||||
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *CanNum)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t RxData[8];
|
||||
|
||||
KPrintf("in CAN1_RX0_IRQHandler\n");
|
||||
|
||||
CAN_HandleTypeDef *hcan1 = &(stm32_can1->instance);
|
||||
CAN_RxHeaderTypeDef RxHeader;
|
||||
HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &RxHeader, stm32_can1->can_Rx_Data);
|
||||
stm32_can1->can_recv_flag =RxHeader.DLC; //接收标志位
|
||||
|
||||
// for(i = 0; i<RxHeader.DLC;i++)
|
||||
// {
|
||||
// KPrintf("0x%02x ", stm32_can1->can_Rx_Data[i]);
|
||||
// }
|
||||
// KPrintf("\n%d",RxHeader.DLC);
|
||||
}
|
||||
|
||||
// #endif // BSP_USING_CAN1
|
||||
|
||||
|
||||
static int BoardCanBusInit(struct Stm32Can *stm32can_bus, struct CanDriver *can_driver)
|
||||
{
|
||||
|
||||
x_err_t ret = EOK;
|
||||
|
||||
/*Init the serial bus */
|
||||
ret = SerialBusInit(serial_bus, bus_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("InitHwUart SerialBusInit error %d\n", ret);
|
||||
/*Init the can bus */
|
||||
ret = CanBusInit(&stm32can_bus->can_bus, stm32can_bus->bus_name);
|
||||
if (EOK != ret)
|
||||
{
|
||||
KPrintf("Board_can_init canBusInit error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*Init the serial driver*/
|
||||
ret = SerialDriverInit(serial_driver, drv_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("InitHwUart SerialDriverInit error %d\n", ret);
|
||||
/*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 serial driver to the serial bus*/
|
||||
ret = SerialDriverAttachToBus(drv_name, bus_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("InitHwUart SerialDriverAttachToBus error %d\n", ret);
|
||||
/*Attach the can driver to the can bus*/
|
||||
ret = CanDriverAttachToBus(CAN_DRIVER_NAME, stm32can_bus->bus_name);
|
||||
if (EOK != ret)
|
||||
{
|
||||
KPrintf("Board_can_init CanDriverAttachToBus error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*Attach the serial device to the serial bus*/
|
||||
static int BoardSerialDevBend(struct SerialHardwareDevice *serial_device, void *serial_param, const char *bus_name, const char *dev_name)
|
||||
static x_err_t HwCanDeviceAttach(const char *bus_name, const char *device_name, struct Stm32Can *can1)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
ret = SerialDeviceRegister(serial_device, serial_param, dev_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("InitHwUart SerialDeviceInit device %s error %d\n", dev_name, ret);
|
||||
NULL_PARAM_CHECK(bus_name);
|
||||
NULL_PARAM_CHECK(device_name);
|
||||
x_err_t result;
|
||||
struct CanHardwareDevice *can_device;
|
||||
/* attach the device to can bus*/
|
||||
can_device = (struct CanHardwareDevice *)x_malloc(sizeof(struct CanHardwareDevice));
|
||||
memset(can_device, 0, sizeof(struct CanHardwareDevice));
|
||||
can_device->dev_done = &can_dev_done;
|
||||
can_device->private_data = stm32_can1;
|
||||
result = CanDeviceRegister(can_device, NONE, device_name);
|
||||
if (EOK != result)
|
||||
{
|
||||
KPrintf("board_can_init canDeviceInit device %s error %d\n", "can1", result);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = SerialDeviceAttachToBus(dev_name, bus_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("InitHwUart SerialDeviceAttachToBus device %s error %d\n", dev_name, ret);
|
||||
return ERROR;
|
||||
result = CanDeviceAttachToBus(device_name, bus_name);
|
||||
if (result != EOK)
|
||||
{
|
||||
SYS_ERR("%s attach to %s faild, %d\n", device_name, bus_name, result);
|
||||
}
|
||||
CHECK(result == EOK);
|
||||
|
||||
return ret;
|
||||
KPrintf("%s attach to %s done\n", device_name, bus_name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int InitHwUart(void)
|
||||
int InitHwCan(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
struct CanDriver *can_driver;
|
||||
|
||||
#ifdef BSP_USING_UART1
|
||||
memset(&serial_bus_1, 0, sizeof(struct SerialBus));
|
||||
memset(&serial_driver_1, 0, sizeof(struct SerialDriver));
|
||||
memset(&serial_device_1, 0, sizeof(struct SerialHardwareDevice));
|
||||
stm32_can1 = (struct Stm32Can *)x_malloc(sizeof(struct Stm32Can));
|
||||
memset(stm32_can1, 0, sizeof(struct Stm32Can));
|
||||
stm32_can1->bus_name = CAN_BUS_NAME_1;
|
||||
stm32_can1->can_bus.private_data = stm32_can1;
|
||||
|
||||
static struct SerialCfgParam serial_cfg_1;
|
||||
memset(&serial_cfg_1, 0, sizeof(struct SerialCfgParam));
|
||||
can_driver = (struct CanDriver *)x_malloc(sizeof(struct CanDriver));
|
||||
memset(can_driver, 0, sizeof(struct CanDriver));
|
||||
can_driver->configure = CanModeInit;
|
||||
can_driver->private_data = stm32_can1;
|
||||
|
||||
static struct Stm32UartHwCfg serial_hw_cfg_1;
|
||||
memset(&serial_hw_cfg_1, 0, sizeof(struct Stm32UartHwCfg));
|
||||
|
||||
static struct SerialDevParam serial_dev_param_1;
|
||||
memset(&serial_dev_param_1, 0, sizeof(struct SerialDevParam));
|
||||
|
||||
serial_driver_1.drv_done = &drv_done;
|
||||
serial_driver_1.configure = &SerialDrvConfigure;
|
||||
serial_device_1.hwdev_done = &hwdev_done;
|
||||
|
||||
serial_cfg_1.data_cfg = data_cfg_init;
|
||||
|
||||
serial_cfg_1.hw_cfg.private_data = (void *)&serial_hw_cfg_1;
|
||||
serial_hw_cfg_1.uart_device = USART1;
|
||||
serial_hw_cfg_1.irq_type = USART1_IRQn;
|
||||
serial_driver_1.private_data = (void *)&serial_cfg_1;
|
||||
|
||||
serial_dev_param_1.serial_work_mode = SIGN_OPER_INT_RX;
|
||||
serial_device_1.haldev.private_data = (void *)&serial_dev_param_1;
|
||||
|
||||
ret = BoardSerialBusInit(&serial_bus_1, &serial_driver_1, SERIAL_BUS_NAME_1, SERIAL_DRV_NAME_1);
|
||||
if (EOK != ret) {
|
||||
KPrintf("InitHwUart uarths error ret %u\n", ret);
|
||||
ret = BoardCanBusInit(stm32_can1, can_driver);
|
||||
if (EOK != ret)
|
||||
{
|
||||
KPrintf(" can_bus_init %s error ret %u\n", stm32_can1->bus_name, ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = BoardSerialDevBend(&serial_device_1, (void *)&serial_cfg_1, SERIAL_BUS_NAME_1, SERIAL_1_DEVICE_NAME_0);
|
||||
if (EOK != ret) {
|
||||
KPrintf("InitHwUart uarths error ret %u\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_UART2
|
||||
memset(&serial_bus_2, 0, sizeof(struct SerialBus));
|
||||
memset(&serial_driver_2, 0, sizeof(struct SerialDriver));
|
||||
memset(&serial_device_2, 0, sizeof(struct SerialHardwareDevice));
|
||||
|
||||
static struct SerialCfgParam serial_cfg_2;
|
||||
memset(&serial_cfg_2, 0, sizeof(struct SerialCfgParam));
|
||||
|
||||
static struct Stm32UartHwCfg serial_hw_cfg_2;
|
||||
memset(&serial_hw_cfg_2, 0, sizeof(struct Stm32UartHwCfg));
|
||||
|
||||
static struct SerialDevParam serial_dev_param_2;
|
||||
memset(&serial_dev_param_2, 0, sizeof(struct SerialDevParam));
|
||||
|
||||
serial_driver_2.drv_done = &drv_done;
|
||||
serial_driver_2.configure = &SerialDrvConfigure;
|
||||
serial_device_2.hwdev_done = &hwdev_done;
|
||||
|
||||
serial_cfg_2.data_cfg = data_cfg_init;
|
||||
|
||||
serial_cfg_2.hw_cfg.private_data = (void *)&serial_hw_cfg_2;
|
||||
serial_hw_cfg_2.uart_device = USART2;
|
||||
serial_hw_cfg_2.irq_type = USART2_IRQn;
|
||||
serial_driver_2.private_data = (void *)&serial_cfg_2;
|
||||
|
||||
serial_dev_param_2.serial_work_mode = SIGN_OPER_INT_RX;
|
||||
serial_device_2.haldev.private_data = (void *)&serial_dev_param_2;
|
||||
|
||||
ret = BoardSerialBusInit(&serial_bus_2, &serial_driver_2, SERIAL_BUS_NAME_2, SERIAL_DRV_NAME_2);
|
||||
if (EOK != ret) {
|
||||
KPrintf("InitHwUart uarths error ret %u\n", ret);
|
||||
ret = HwCanDeviceAttach(CAN_BUS_NAME_1, CAN_1_DEVICE_NAME_1, stm32_can1);
|
||||
if (EOK != ret)
|
||||
{
|
||||
KPrintf(" HwCanDeviceAttach %s error ret %u\n", stm32_can1->bus_name, ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = BoardSerialDevBend(&serial_device_2, (void *)&serial_cfg_2, SERIAL_BUS_NAME_2, SERIAL_2_DEVICE_NAME_0);
|
||||
if (EOK != ret) {
|
||||
KPrintf("InitHwUart uarths error ret %u\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
return EOK;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
SRC_FILES := ymodem.c
|
||||
SRC_FILES :=
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -25,7 +25,9 @@ DMA_HandleTypeDef hdma_usart1_rx;
|
|||
|
||||
void ymodem_uart_init(void)
|
||||
{
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
// need UART1 IRQ --> void UartIsr1(int vector, void *param)
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
__HAL_RCC_USART1_CLK_ENABLE();
|
||||
|
@ -265,7 +267,8 @@ void ymodem_fun(void)
|
|||
|
||||
KPrintf("in ymodem func\n");
|
||||
ymodem_uart_init();
|
||||
|
||||
while (1)
|
||||
{
|
||||
if(Get_state()==TO_START)
|
||||
{
|
||||
KPrintf("in ymodem wait\n");
|
||||
|
@ -359,6 +362,7 @@ void ymodem_fun(void)
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.h
|
||||
* @brief define aiit-arm32-board can function and struct
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-22
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_CAN_H
|
||||
#define CONNECT_CAN_H
|
||||
|
||||
#include <device.h>
|
||||
#include "stm32f1xx_hal_can.h"
|
||||
#include "stm32f103xb.h"
|
||||
#include "stm32f1xx_hal_def.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Stm32Can
|
||||
{
|
||||
CAN_HandleTypeDef instance;
|
||||
char *bus_name;
|
||||
struct CanBus can_bus;
|
||||
uint8 can_recv_flag;
|
||||
uint8_t can_Rx_Data[8];
|
||||
};
|
||||
|
||||
#define CAN_RxExtId 0x1800D8D0
|
||||
#define CAN_TxExtId 0x1800D0D8
|
||||
|
||||
int InitHwCan(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,859 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_can.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of CAN HAL module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32F1xx_HAL_CAN_H
|
||||
#define STM32F1xx_HAL_CAN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal_def.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (CAN1)
|
||||
/** @addtogroup CAN
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/** @defgroup CAN_Exported_Types CAN Exported Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief HAL State structures definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_CAN_STATE_RESET = 0x00U, /*!< CAN not yet initialized or disabled */
|
||||
HAL_CAN_STATE_READY = 0x01U, /*!< CAN initialized and ready for use */
|
||||
HAL_CAN_STATE_LISTENING = 0x02U, /*!< CAN receive process is ongoing */
|
||||
HAL_CAN_STATE_SLEEP_PENDING = 0x03U, /*!< CAN sleep request is pending */
|
||||
HAL_CAN_STATE_SLEEP_ACTIVE = 0x04U, /*!< CAN sleep mode is active */
|
||||
HAL_CAN_STATE_ERROR = 0x05U /*!< CAN error state */
|
||||
|
||||
} HAL_CAN_StateTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN init structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Prescaler; /*!< Specifies the length of a time quantum.
|
||||
This parameter must be a number between Min_Data = 1 and Max_Data = 1024. */
|
||||
|
||||
uint32_t Mode; /*!< Specifies the CAN operating mode.
|
||||
This parameter can be a value of @ref CAN_operating_mode */
|
||||
|
||||
uint32_t SyncJumpWidth; /*!< Specifies the maximum number of time quanta the CAN hardware
|
||||
is allowed to lengthen or shorten a bit to perform resynchronization.
|
||||
This parameter can be a value of @ref CAN_synchronisation_jump_width */
|
||||
|
||||
uint32_t TimeSeg1; /*!< Specifies the number of time quanta in Bit Segment 1.
|
||||
This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */
|
||||
|
||||
uint32_t TimeSeg2; /*!< Specifies the number of time quanta in Bit Segment 2.
|
||||
This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */
|
||||
|
||||
FunctionalState TimeTriggeredMode; /*!< Enable or disable the time triggered communication mode.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
FunctionalState AutoBusOff; /*!< Enable or disable the automatic bus-off management.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
FunctionalState AutoWakeUp; /*!< Enable or disable the automatic wake-up mode.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
FunctionalState AutoRetransmission; /*!< Enable or disable the non-automatic retransmission mode.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
FunctionalState ReceiveFifoLocked; /*!< Enable or disable the Receive FIFO Locked mode.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
FunctionalState TransmitFifoPriority;/*!< Enable or disable the transmit FIFO priority.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
} CAN_InitTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN filter configuration structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit
|
||||
configuration, first one for a 16-bit configuration).
|
||||
This parameter must be a number between
|
||||
Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit
|
||||
configuration, second one for a 16-bit configuration).
|
||||
This parameter must be a number between
|
||||
Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number,
|
||||
according to the mode (MSBs for a 32-bit configuration,
|
||||
first one for a 16-bit configuration).
|
||||
This parameter must be a number between
|
||||
Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterMaskIdLow; /*!< Specifies the filter mask number or identification number,
|
||||
according to the mode (LSBs for a 32-bit configuration,
|
||||
second one for a 16-bit configuration).
|
||||
This parameter must be a number between
|
||||
Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1U) which will be assigned to the filter.
|
||||
This parameter can be a value of @ref CAN_filter_FIFO */
|
||||
|
||||
uint32_t FilterBank; /*!< Specifies the filter bank which will be initialized.
|
||||
For single CAN instance(14 dedicated filter banks),
|
||||
this parameter must be a number between Min_Data = 0 and Max_Data = 13.
|
||||
For dual CAN instances(28 filter banks shared),
|
||||
this parameter must be a number between Min_Data = 0 and Max_Data = 27. */
|
||||
|
||||
uint32_t FilterMode; /*!< Specifies the filter mode to be initialized.
|
||||
This parameter can be a value of @ref CAN_filter_mode */
|
||||
|
||||
uint32_t FilterScale; /*!< Specifies the filter scale.
|
||||
This parameter can be a value of @ref CAN_filter_scale */
|
||||
|
||||
uint32_t FilterActivation; /*!< Enable or disable the filter.
|
||||
This parameter can be a value of @ref CAN_filter_activation */
|
||||
|
||||
uint32_t SlaveStartFilterBank; /*!< Select the start filter bank for the slave CAN instance.
|
||||
For single CAN instances, this parameter is meaningless.
|
||||
For dual CAN instances, all filter banks with lower index are assigned to master
|
||||
CAN instance, whereas all filter banks with greater index are assigned to slave
|
||||
CAN instance.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 27. */
|
||||
|
||||
} CAN_FilterTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN Tx message header structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t StdId; /*!< Specifies the standard identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */
|
||||
|
||||
uint32_t ExtId; /*!< Specifies the extended identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */
|
||||
|
||||
uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
|
||||
This parameter can be a value of @ref CAN_identifier_type */
|
||||
|
||||
uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
|
||||
This parameter can be a value of @ref CAN_remote_transmission_request */
|
||||
|
||||
uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 8. */
|
||||
|
||||
FunctionalState TransmitGlobalTime; /*!< Specifies whether the timestamp counter value captured on start
|
||||
of frame transmission, is sent in DATA6 and DATA7 replacing pData[6] and pData[7].
|
||||
@note: Time Triggered Communication Mode must be enabled.
|
||||
@note: DLC must be programmed as 8 bytes, in order these 2 bytes are sent.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
} CAN_TxHeaderTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN Rx message header structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t StdId; /*!< Specifies the standard identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */
|
||||
|
||||
uint32_t ExtId; /*!< Specifies the extended identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */
|
||||
|
||||
uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
|
||||
This parameter can be a value of @ref CAN_identifier_type */
|
||||
|
||||
uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
|
||||
This parameter can be a value of @ref CAN_remote_transmission_request */
|
||||
|
||||
uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 8. */
|
||||
|
||||
uint32_t Timestamp; /*!< Specifies the timestamp counter value captured on start of frame reception.
|
||||
@note: Time Triggered Communication Mode must be enabled.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterMatchIndex; /*!< Specifies the index of matching acceptance filter element.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF. */
|
||||
|
||||
} CAN_RxHeaderTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN handle Structure definition
|
||||
*/
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
typedef struct __CAN_HandleTypeDef
|
||||
#else
|
||||
typedef struct
|
||||
#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
|
||||
{
|
||||
CAN_TypeDef *Instance; /*!< Register base address */
|
||||
|
||||
CAN_InitTypeDef Init; /*!< CAN required parameters */
|
||||
|
||||
__IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */
|
||||
|
||||
__IO uint32_t ErrorCode; /*!< CAN Error code.
|
||||
This parameter can be a value of @ref CAN_Error_Code */
|
||||
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
void (* TxMailbox0CompleteCallback)(struct __CAN_HandleTypeDef *hcan);/*!< CAN Tx Mailbox 0 complete callback */
|
||||
void (* TxMailbox1CompleteCallback)(struct __CAN_HandleTypeDef *hcan);/*!< CAN Tx Mailbox 1 complete callback */
|
||||
void (* TxMailbox2CompleteCallback)(struct __CAN_HandleTypeDef *hcan);/*!< CAN Tx Mailbox 2 complete callback */
|
||||
void (* TxMailbox0AbortCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Tx Mailbox 0 abort callback */
|
||||
void (* TxMailbox1AbortCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Tx Mailbox 1 abort callback */
|
||||
void (* TxMailbox2AbortCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Tx Mailbox 2 abort callback */
|
||||
void (* RxFifo0MsgPendingCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Rx FIFO 0 msg pending callback */
|
||||
void (* RxFifo0FullCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Rx FIFO 0 full callback */
|
||||
void (* RxFifo1MsgPendingCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Rx FIFO 1 msg pending callback */
|
||||
void (* RxFifo1FullCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Rx FIFO 1 full callback */
|
||||
void (* SleepCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Sleep callback */
|
||||
void (* WakeUpFromRxMsgCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Wake Up from Rx msg callback */
|
||||
void (* ErrorCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Error callback */
|
||||
|
||||
void (* MspInitCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Msp Init callback */
|
||||
void (* MspDeInitCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Msp DeInit callback */
|
||||
|
||||
#endif /* (USE_HAL_CAN_REGISTER_CALLBACKS) */
|
||||
} CAN_HandleTypeDef;
|
||||
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
/**
|
||||
* @brief HAL CAN common Callback ID enumeration definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID = 0x00U, /*!< CAN Tx Mailbox 0 complete callback ID */
|
||||
HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID = 0x01U, /*!< CAN Tx Mailbox 1 complete callback ID */
|
||||
HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID = 0x02U, /*!< CAN Tx Mailbox 2 complete callback ID */
|
||||
HAL_CAN_TX_MAILBOX0_ABORT_CB_ID = 0x03U, /*!< CAN Tx Mailbox 0 abort callback ID */
|
||||
HAL_CAN_TX_MAILBOX1_ABORT_CB_ID = 0x04U, /*!< CAN Tx Mailbox 1 abort callback ID */
|
||||
HAL_CAN_TX_MAILBOX2_ABORT_CB_ID = 0x05U, /*!< CAN Tx Mailbox 2 abort callback ID */
|
||||
HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID = 0x06U, /*!< CAN Rx FIFO 0 message pending callback ID */
|
||||
HAL_CAN_RX_FIFO0_FULL_CB_ID = 0x07U, /*!< CAN Rx FIFO 0 full callback ID */
|
||||
HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID = 0x08U, /*!< CAN Rx FIFO 1 message pending callback ID */
|
||||
HAL_CAN_RX_FIFO1_FULL_CB_ID = 0x09U, /*!< CAN Rx FIFO 1 full callback ID */
|
||||
HAL_CAN_SLEEP_CB_ID = 0x0AU, /*!< CAN Sleep callback ID */
|
||||
HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID = 0x0BU, /*!< CAN Wake Up from Rx msg callback ID */
|
||||
HAL_CAN_ERROR_CB_ID = 0x0CU, /*!< CAN Error callback ID */
|
||||
|
||||
HAL_CAN_MSPINIT_CB_ID = 0x0DU, /*!< CAN MspInit callback ID */
|
||||
HAL_CAN_MSPDEINIT_CB_ID = 0x0EU, /*!< CAN MspDeInit callback ID */
|
||||
|
||||
} HAL_CAN_CallbackIDTypeDef;
|
||||
|
||||
/**
|
||||
* @brief HAL CAN Callback pointer definition
|
||||
*/
|
||||
typedef void (*pCAN_CallbackTypeDef)(CAN_HandleTypeDef *hcan); /*!< pointer to a CAN callback function */
|
||||
|
||||
#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup CAN_Exported_Constants CAN Exported Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Error_Code CAN Error Code
|
||||
* @{
|
||||
*/
|
||||
#define HAL_CAN_ERROR_NONE (0x00000000U) /*!< No error */
|
||||
#define HAL_CAN_ERROR_EWG (0x00000001U) /*!< Protocol Error Warning */
|
||||
#define HAL_CAN_ERROR_EPV (0x00000002U) /*!< Error Passive */
|
||||
#define HAL_CAN_ERROR_BOF (0x00000004U) /*!< Bus-off error */
|
||||
#define HAL_CAN_ERROR_STF (0x00000008U) /*!< Stuff error */
|
||||
#define HAL_CAN_ERROR_FOR (0x00000010U) /*!< Form error */
|
||||
#define HAL_CAN_ERROR_ACK (0x00000020U) /*!< Acknowledgment error */
|
||||
#define HAL_CAN_ERROR_BR (0x00000040U) /*!< Bit recessive error */
|
||||
#define HAL_CAN_ERROR_BD (0x00000080U) /*!< Bit dominant error */
|
||||
#define HAL_CAN_ERROR_CRC (0x00000100U) /*!< CRC error */
|
||||
#define HAL_CAN_ERROR_RX_FOV0 (0x00000200U) /*!< Rx FIFO0 overrun error */
|
||||
#define HAL_CAN_ERROR_RX_FOV1 (0x00000400U) /*!< Rx FIFO1 overrun error */
|
||||
#define HAL_CAN_ERROR_TX_ALST0 (0x00000800U) /*!< TxMailbox 0 transmit failure due to arbitration lost */
|
||||
#define HAL_CAN_ERROR_TX_TERR0 (0x00001000U) /*!< TxMailbox 0 transmit failure due to transmit error */
|
||||
#define HAL_CAN_ERROR_TX_ALST1 (0x00002000U) /*!< TxMailbox 1 transmit failure due to arbitration lost */
|
||||
#define HAL_CAN_ERROR_TX_TERR1 (0x00004000U) /*!< TxMailbox 1 transmit failure due to transmit error */
|
||||
#define HAL_CAN_ERROR_TX_ALST2 (0x00008000U) /*!< TxMailbox 2 transmit failure due to arbitration lost */
|
||||
#define HAL_CAN_ERROR_TX_TERR2 (0x00010000U) /*!< TxMailbox 2 transmit failure due to transmit error */
|
||||
#define HAL_CAN_ERROR_TIMEOUT (0x00020000U) /*!< Timeout error */
|
||||
#define HAL_CAN_ERROR_NOT_INITIALIZED (0x00040000U) /*!< Peripheral not initialized */
|
||||
#define HAL_CAN_ERROR_NOT_READY (0x00080000U) /*!< Peripheral not ready */
|
||||
#define HAL_CAN_ERROR_NOT_STARTED (0x00100000U) /*!< Peripheral not started */
|
||||
#define HAL_CAN_ERROR_PARAM (0x00200000U) /*!< Parameter error */
|
||||
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
#define HAL_CAN_ERROR_INVALID_CALLBACK (0x00400000U) /*!< Invalid Callback error */
|
||||
#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
|
||||
#define HAL_CAN_ERROR_INTERNAL (0x00800000U) /*!< Internal error */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_InitStatus CAN InitStatus
|
||||
* @{
|
||||
*/
|
||||
#define CAN_INITSTATUS_FAILED (0x00000000U) /*!< CAN initialization failed */
|
||||
#define CAN_INITSTATUS_SUCCESS (0x00000001U) /*!< CAN initialization OK */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_operating_mode CAN Operating Mode
|
||||
* @{
|
||||
*/
|
||||
#define CAN_MODE_NORMAL (0x00000000U) /*!< Normal mode */
|
||||
#define CAN_MODE_LOOPBACK ((uint32_t)CAN_BTR_LBKM) /*!< Loopback mode */
|
||||
#define CAN_MODE_SILENT ((uint32_t)CAN_BTR_SILM) /*!< Silent mode */
|
||||
#define CAN_MODE_SILENT_LOOPBACK ((uint32_t)(CAN_BTR_LBKM | CAN_BTR_SILM)) /*!< Loopback combined with
|
||||
silent mode */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup CAN_synchronisation_jump_width CAN Synchronization Jump Width
|
||||
* @{
|
||||
*/
|
||||
#define CAN_SJW_1TQ (0x00000000U) /*!< 1 time quantum */
|
||||
#define CAN_SJW_2TQ ((uint32_t)CAN_BTR_SJW_0) /*!< 2 time quantum */
|
||||
#define CAN_SJW_3TQ ((uint32_t)CAN_BTR_SJW_1) /*!< 3 time quantum */
|
||||
#define CAN_SJW_4TQ ((uint32_t)CAN_BTR_SJW) /*!< 4 time quantum */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_time_quantum_in_bit_segment_1 CAN Time Quantum in Bit Segment 1
|
||||
* @{
|
||||
*/
|
||||
#define CAN_BS1_1TQ (0x00000000U) /*!< 1 time quantum */
|
||||
#define CAN_BS1_2TQ ((uint32_t)CAN_BTR_TS1_0) /*!< 2 time quantum */
|
||||
#define CAN_BS1_3TQ ((uint32_t)CAN_BTR_TS1_1) /*!< 3 time quantum */
|
||||
#define CAN_BS1_4TQ ((uint32_t)(CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 4 time quantum */
|
||||
#define CAN_BS1_5TQ ((uint32_t)CAN_BTR_TS1_2) /*!< 5 time quantum */
|
||||
#define CAN_BS1_6TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 6 time quantum */
|
||||
#define CAN_BS1_7TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 7 time quantum */
|
||||
#define CAN_BS1_8TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 8 time quantum */
|
||||
#define CAN_BS1_9TQ ((uint32_t)CAN_BTR_TS1_3) /*!< 9 time quantum */
|
||||
#define CAN_BS1_10TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_0)) /*!< 10 time quantum */
|
||||
#define CAN_BS1_11TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1)) /*!< 11 time quantum */
|
||||
#define CAN_BS1_12TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 12 time quantum */
|
||||
#define CAN_BS1_13TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2)) /*!< 13 time quantum */
|
||||
#define CAN_BS1_14TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 14 time quantum */
|
||||
#define CAN_BS1_15TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 15 time quantum */
|
||||
#define CAN_BS1_16TQ ((uint32_t)CAN_BTR_TS1) /*!< 16 time quantum */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_time_quantum_in_bit_segment_2 CAN Time Quantum in Bit Segment 2
|
||||
* @{
|
||||
*/
|
||||
#define CAN_BS2_1TQ (0x00000000U) /*!< 1 time quantum */
|
||||
#define CAN_BS2_2TQ ((uint32_t)CAN_BTR_TS2_0) /*!< 2 time quantum */
|
||||
#define CAN_BS2_3TQ ((uint32_t)CAN_BTR_TS2_1) /*!< 3 time quantum */
|
||||
#define CAN_BS2_4TQ ((uint32_t)(CAN_BTR_TS2_1 | CAN_BTR_TS2_0)) /*!< 4 time quantum */
|
||||
#define CAN_BS2_5TQ ((uint32_t)CAN_BTR_TS2_2) /*!< 5 time quantum */
|
||||
#define CAN_BS2_6TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_0)) /*!< 6 time quantum */
|
||||
#define CAN_BS2_7TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_1)) /*!< 7 time quantum */
|
||||
#define CAN_BS2_8TQ ((uint32_t)CAN_BTR_TS2) /*!< 8 time quantum */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_filter_mode CAN Filter Mode
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FILTERMODE_IDMASK (0x00000000U) /*!< Identifier mask mode */
|
||||
#define CAN_FILTERMODE_IDLIST (0x00000001U) /*!< Identifier list mode */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_filter_scale CAN Filter Scale
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FILTERSCALE_16BIT (0x00000000U) /*!< Two 16-bit filters */
|
||||
#define CAN_FILTERSCALE_32BIT (0x00000001U) /*!< One 32-bit filter */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_filter_activation CAN Filter Activation
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FILTER_DISABLE (0x00000000U) /*!< Disable filter */
|
||||
#define CAN_FILTER_ENABLE (0x00000001U) /*!< Enable filter */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_filter_FIFO CAN Filter FIFO
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FILTER_FIFO0 (0x00000000U) /*!< Filter FIFO 0 assignment for filter x */
|
||||
#define CAN_FILTER_FIFO1 (0x00000001U) /*!< Filter FIFO 1 assignment for filter x */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_identifier_type CAN Identifier Type
|
||||
* @{
|
||||
*/
|
||||
#define CAN_ID_STD (0x00000000U) /*!< Standard Id */
|
||||
#define CAN_ID_EXT (0x00000004U) /*!< Extended Id */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_remote_transmission_request CAN Remote Transmission Request
|
||||
* @{
|
||||
*/
|
||||
#define CAN_RTR_DATA (0x00000000U) /*!< Data frame */
|
||||
#define CAN_RTR_REMOTE (0x00000002U) /*!< Remote frame */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_receive_FIFO_number CAN Receive FIFO Number
|
||||
* @{
|
||||
*/
|
||||
#define CAN_RX_FIFO0 (0x00000000U) /*!< CAN receive FIFO 0 */
|
||||
#define CAN_RX_FIFO1 (0x00000001U) /*!< CAN receive FIFO 1 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Tx_Mailboxes CAN Tx Mailboxes
|
||||
* @{
|
||||
*/
|
||||
#define CAN_TX_MAILBOX0 (0x00000001U) /*!< Tx Mailbox 0 */
|
||||
#define CAN_TX_MAILBOX1 (0x00000002U) /*!< Tx Mailbox 1 */
|
||||
#define CAN_TX_MAILBOX2 (0x00000004U) /*!< Tx Mailbox 2 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_flags CAN Flags
|
||||
* @{
|
||||
*/
|
||||
/* Transmit Flags */
|
||||
#define CAN_FLAG_RQCP0 (0x00000500U) /*!< Request complete MailBox 0 flag */
|
||||
#define CAN_FLAG_TXOK0 (0x00000501U) /*!< Transmission OK MailBox 0 flag */
|
||||
#define CAN_FLAG_ALST0 (0x00000502U) /*!< Arbitration Lost MailBox 0 flag */
|
||||
#define CAN_FLAG_TERR0 (0x00000503U) /*!< Transmission error MailBox 0 flag */
|
||||
#define CAN_FLAG_RQCP1 (0x00000508U) /*!< Request complete MailBox1 flag */
|
||||
#define CAN_FLAG_TXOK1 (0x00000509U) /*!< Transmission OK MailBox 1 flag */
|
||||
#define CAN_FLAG_ALST1 (0x0000050AU) /*!< Arbitration Lost MailBox 1 flag */
|
||||
#define CAN_FLAG_TERR1 (0x0000050BU) /*!< Transmission error MailBox 1 flag */
|
||||
#define CAN_FLAG_RQCP2 (0x00000510U) /*!< Request complete MailBox2 flag */
|
||||
#define CAN_FLAG_TXOK2 (0x00000511U) /*!< Transmission OK MailBox 2 flag */
|
||||
#define CAN_FLAG_ALST2 (0x00000512U) /*!< Arbitration Lost MailBox 2 flag */
|
||||
#define CAN_FLAG_TERR2 (0x00000513U) /*!< Transmission error MailBox 2 flag */
|
||||
#define CAN_FLAG_TME0 (0x0000051AU) /*!< Transmit mailbox 0 empty flag */
|
||||
#define CAN_FLAG_TME1 (0x0000051BU) /*!< Transmit mailbox 1 empty flag */
|
||||
#define CAN_FLAG_TME2 (0x0000051CU) /*!< Transmit mailbox 2 empty flag */
|
||||
#define CAN_FLAG_LOW0 (0x0000051DU) /*!< Lowest priority mailbox 0 flag */
|
||||
#define CAN_FLAG_LOW1 (0x0000051EU) /*!< Lowest priority mailbox 1 flag */
|
||||
#define CAN_FLAG_LOW2 (0x0000051FU) /*!< Lowest priority mailbox 2 flag */
|
||||
|
||||
/* Receive Flags */
|
||||
#define CAN_FLAG_FF0 (0x00000203U) /*!< RX FIFO 0 Full flag */
|
||||
#define CAN_FLAG_FOV0 (0x00000204U) /*!< RX FIFO 0 Overrun flag */
|
||||
#define CAN_FLAG_FF1 (0x00000403U) /*!< RX FIFO 1 Full flag */
|
||||
#define CAN_FLAG_FOV1 (0x00000404U) /*!< RX FIFO 1 Overrun flag */
|
||||
|
||||
/* Operating Mode Flags */
|
||||
#define CAN_FLAG_INAK (0x00000100U) /*!< Initialization acknowledge flag */
|
||||
#define CAN_FLAG_SLAK (0x00000101U) /*!< Sleep acknowledge flag */
|
||||
#define CAN_FLAG_ERRI (0x00000102U) /*!< Error flag */
|
||||
#define CAN_FLAG_WKU (0x00000103U) /*!< Wake up interrupt flag */
|
||||
#define CAN_FLAG_SLAKI (0x00000104U) /*!< Sleep acknowledge interrupt flag */
|
||||
|
||||
/* Error Flags */
|
||||
#define CAN_FLAG_EWG (0x00000300U) /*!< Error warning flag */
|
||||
#define CAN_FLAG_EPV (0x00000301U) /*!< Error passive flag */
|
||||
#define CAN_FLAG_BOF (0x00000302U) /*!< Bus-Off flag */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup CAN_Interrupts CAN Interrupts
|
||||
* @{
|
||||
*/
|
||||
/* Transmit Interrupt */
|
||||
#define CAN_IT_TX_MAILBOX_EMPTY ((uint32_t)CAN_IER_TMEIE) /*!< Transmit mailbox empty interrupt */
|
||||
|
||||
/* Receive Interrupts */
|
||||
#define CAN_IT_RX_FIFO0_MSG_PENDING ((uint32_t)CAN_IER_FMPIE0) /*!< FIFO 0 message pending interrupt */
|
||||
#define CAN_IT_RX_FIFO0_FULL ((uint32_t)CAN_IER_FFIE0) /*!< FIFO 0 full interrupt */
|
||||
#define CAN_IT_RX_FIFO0_OVERRUN ((uint32_t)CAN_IER_FOVIE0) /*!< FIFO 0 overrun interrupt */
|
||||
#define CAN_IT_RX_FIFO1_MSG_PENDING ((uint32_t)CAN_IER_FMPIE1) /*!< FIFO 1 message pending interrupt */
|
||||
#define CAN_IT_RX_FIFO1_FULL ((uint32_t)CAN_IER_FFIE1) /*!< FIFO 1 full interrupt */
|
||||
#define CAN_IT_RX_FIFO1_OVERRUN ((uint32_t)CAN_IER_FOVIE1) /*!< FIFO 1 overrun interrupt */
|
||||
|
||||
/* Operating Mode Interrupts */
|
||||
#define CAN_IT_WAKEUP ((uint32_t)CAN_IER_WKUIE) /*!< Wake-up interrupt */
|
||||
#define CAN_IT_SLEEP_ACK ((uint32_t)CAN_IER_SLKIE) /*!< Sleep acknowledge interrupt */
|
||||
|
||||
/* Error Interrupts */
|
||||
#define CAN_IT_ERROR_WARNING ((uint32_t)CAN_IER_EWGIE) /*!< Error warning interrupt */
|
||||
#define CAN_IT_ERROR_PASSIVE ((uint32_t)CAN_IER_EPVIE) /*!< Error passive interrupt */
|
||||
#define CAN_IT_BUSOFF ((uint32_t)CAN_IER_BOFIE) /*!< Bus-off interrupt */
|
||||
#define CAN_IT_LAST_ERROR_CODE ((uint32_t)CAN_IER_LECIE) /*!< Last error code interrupt */
|
||||
#define CAN_IT_ERROR ((uint32_t)CAN_IER_ERRIE) /*!< Error Interrupt */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/** @defgroup CAN_Exported_Macros CAN Exported Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Reset CAN handle state
|
||||
* @param __HANDLE__ CAN handle.
|
||||
* @retval None
|
||||
*/
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
#define __HAL_CAN_RESET_HANDLE_STATE(__HANDLE__) do{ \
|
||||
(__HANDLE__)->State = HAL_CAN_STATE_RESET; \
|
||||
(__HANDLE__)->MspInitCallback = NULL; \
|
||||
(__HANDLE__)->MspDeInitCallback = NULL; \
|
||||
} while(0)
|
||||
#else
|
||||
#define __HAL_CAN_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CAN_STATE_RESET)
|
||||
#endif /*USE_HAL_CAN_REGISTER_CALLBACKS */
|
||||
|
||||
/**
|
||||
* @brief Enable the specified CAN interrupts.
|
||||
* @param __HANDLE__ CAN handle.
|
||||
* @param __INTERRUPT__ CAN Interrupt sources to enable.
|
||||
* This parameter can be any combination of @arg CAN_Interrupts
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_CAN_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) |= (__INTERRUPT__))
|
||||
|
||||
/**
|
||||
* @brief Disable the specified CAN interrupts.
|
||||
* @param __HANDLE__ CAN handle.
|
||||
* @param __INTERRUPT__ CAN Interrupt sources to disable.
|
||||
* This parameter can be any combination of @arg CAN_Interrupts
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_CAN_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) &= ~(__INTERRUPT__))
|
||||
|
||||
/** @brief Check if the specified CAN interrupt source is enabled or disabled.
|
||||
* @param __HANDLE__ specifies the CAN Handle.
|
||||
* @param __INTERRUPT__ specifies the CAN interrupt source to check.
|
||||
* This parameter can be a value of @arg CAN_Interrupts
|
||||
* @retval The state of __IT__ (TRUE or FALSE).
|
||||
*/
|
||||
#define __HAL_CAN_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) & (__INTERRUPT__))
|
||||
|
||||
/** @brief Check whether the specified CAN flag is set or not.
|
||||
* @param __HANDLE__ specifies the CAN Handle.
|
||||
* @param __FLAG__ specifies the flag to check.
|
||||
* This parameter can be one of @arg CAN_flags
|
||||
* @retval The state of __FLAG__ (TRUE or FALSE).
|
||||
*/
|
||||
#define __HAL_CAN_GET_FLAG(__HANDLE__, __FLAG__) \
|
||||
((((__FLAG__) >> 8U) == 5U)? ((((__HANDLE__)->Instance->TSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 2U)? ((((__HANDLE__)->Instance->RF0R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 4U)? ((((__HANDLE__)->Instance->RF1R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 1U)? ((((__HANDLE__)->Instance->MSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 3U)? ((((__HANDLE__)->Instance->ESR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): 0U)
|
||||
|
||||
/** @brief Clear the specified CAN pending flag.
|
||||
* @param __HANDLE__ specifies the CAN Handle.
|
||||
* @param __FLAG__ specifies the flag to check.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg CAN_FLAG_RQCP0: Request complete MailBox 0 Flag
|
||||
* @arg CAN_FLAG_TXOK0: Transmission OK MailBox 0 Flag
|
||||
* @arg CAN_FLAG_ALST0: Arbitration Lost MailBox 0 Flag
|
||||
* @arg CAN_FLAG_TERR0: Transmission error MailBox 0 Flag
|
||||
* @arg CAN_FLAG_RQCP1: Request complete MailBox 1 Flag
|
||||
* @arg CAN_FLAG_TXOK1: Transmission OK MailBox 1 Flag
|
||||
* @arg CAN_FLAG_ALST1: Arbitration Lost MailBox 1 Flag
|
||||
* @arg CAN_FLAG_TERR1: Transmission error MailBox 1 Flag
|
||||
* @arg CAN_FLAG_RQCP2: Request complete MailBox 2 Flag
|
||||
* @arg CAN_FLAG_TXOK2: Transmission OK MailBox 2 Flag
|
||||
* @arg CAN_FLAG_ALST2: Arbitration Lost MailBox 2 Flag
|
||||
* @arg CAN_FLAG_TERR2: Transmission error MailBox 2 Flag
|
||||
* @arg CAN_FLAG_FF0: RX FIFO 0 Full Flag
|
||||
* @arg CAN_FLAG_FOV0: RX FIFO 0 Overrun Flag
|
||||
* @arg CAN_FLAG_FF1: RX FIFO 1 Full Flag
|
||||
* @arg CAN_FLAG_FOV1: RX FIFO 1 Overrun Flag
|
||||
* @arg CAN_FLAG_WKUI: Wake up Interrupt Flag
|
||||
* @arg CAN_FLAG_SLAKI: Sleep acknowledge Interrupt Flag
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_CAN_CLEAR_FLAG(__HANDLE__, __FLAG__) \
|
||||
((((__FLAG__) >> 8U) == 5U)? (((__HANDLE__)->Instance->TSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 2U)? (((__HANDLE__)->Instance->RF0R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 4U)? (((__HANDLE__)->Instance->RF1R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 1U)? (((__HANDLE__)->Instance->MSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): 0U)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup CAN_Exported_Functions CAN Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Initialization and de-initialization functions *****************************/
|
||||
HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan);
|
||||
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
/* Callbacks Register/UnRegister functions ***********************************/
|
||||
HAL_StatusTypeDef HAL_CAN_RegisterCallback(CAN_HandleTypeDef *hcan, HAL_CAN_CallbackIDTypeDef CallbackID,
|
||||
void (* pCallback)(CAN_HandleTypeDef *_hcan));
|
||||
HAL_StatusTypeDef HAL_CAN_UnRegisterCallback(CAN_HandleTypeDef *hcan, HAL_CAN_CallbackIDTypeDef CallbackID);
|
||||
|
||||
#endif /* (USE_HAL_CAN_REGISTER_CALLBACKS) */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group2 Configuration functions
|
||||
* @brief Configuration functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Configuration functions ****************************************************/
|
||||
HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, const CAN_FilterTypeDef *sFilterConfig);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group3 Control functions
|
||||
* @brief Control functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Control functions **********************************************************/
|
||||
HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan);
|
||||
uint32_t HAL_CAN_IsSleepActive(const CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, const CAN_TxHeaderTypeDef *pHeader,
|
||||
const uint8_t aData[], uint32_t *pTxMailbox);
|
||||
HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes);
|
||||
uint32_t HAL_CAN_GetTxMailboxesFreeLevel(const CAN_HandleTypeDef *hcan);
|
||||
uint32_t HAL_CAN_IsTxMessagePending(const CAN_HandleTypeDef *hcan, uint32_t TxMailboxes);
|
||||
uint32_t HAL_CAN_GetTxTimestamp(const CAN_HandleTypeDef *hcan, uint32_t TxMailbox);
|
||||
HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo,
|
||||
CAN_RxHeaderTypeDef *pHeader, uint8_t aData[]);
|
||||
uint32_t HAL_CAN_GetRxFifoFillLevel(const CAN_HandleTypeDef *hcan, uint32_t RxFifo);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group4 Interrupts management
|
||||
* @brief Interrupts management
|
||||
* @{
|
||||
*/
|
||||
/* Interrupts management ******************************************************/
|
||||
HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs);
|
||||
HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs);
|
||||
void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group5 Callback functions
|
||||
* @brief Callback functions
|
||||
* @{
|
||||
*/
|
||||
/* Callbacks functions ********************************************************/
|
||||
|
||||
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group6 Peripheral State and Error functions
|
||||
* @brief CAN Peripheral State functions
|
||||
* @{
|
||||
*/
|
||||
/* Peripheral State and Error functions ***************************************/
|
||||
HAL_CAN_StateTypeDef HAL_CAN_GetState(const CAN_HandleTypeDef *hcan);
|
||||
uint32_t HAL_CAN_GetError(const CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/** @defgroup CAN_Private_Types CAN Private Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/** @defgroup CAN_Private_Variables CAN Private Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @defgroup CAN_Private_Constants CAN Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FLAG_MASK (0x000000FFU)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private Macros -----------------------------------------------------------*/
|
||||
/** @defgroup CAN_Private_Macros CAN Private Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IS_CAN_MODE(MODE) (((MODE) == CAN_MODE_NORMAL) || \
|
||||
((MODE) == CAN_MODE_LOOPBACK)|| \
|
||||
((MODE) == CAN_MODE_SILENT) || \
|
||||
((MODE) == CAN_MODE_SILENT_LOOPBACK))
|
||||
#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1TQ) || ((SJW) == CAN_SJW_2TQ) || \
|
||||
((SJW) == CAN_SJW_3TQ) || ((SJW) == CAN_SJW_4TQ))
|
||||
#define IS_CAN_BS1(BS1) (((BS1) == CAN_BS1_1TQ) || ((BS1) == CAN_BS1_2TQ) || \
|
||||
((BS1) == CAN_BS1_3TQ) || ((BS1) == CAN_BS1_4TQ) || \
|
||||
((BS1) == CAN_BS1_5TQ) || ((BS1) == CAN_BS1_6TQ) || \
|
||||
((BS1) == CAN_BS1_7TQ) || ((BS1) == CAN_BS1_8TQ) || \
|
||||
((BS1) == CAN_BS1_9TQ) || ((BS1) == CAN_BS1_10TQ)|| \
|
||||
((BS1) == CAN_BS1_11TQ)|| ((BS1) == CAN_BS1_12TQ)|| \
|
||||
((BS1) == CAN_BS1_13TQ)|| ((BS1) == CAN_BS1_14TQ)|| \
|
||||
((BS1) == CAN_BS1_15TQ)|| ((BS1) == CAN_BS1_16TQ))
|
||||
#define IS_CAN_BS2(BS2) (((BS2) == CAN_BS2_1TQ) || ((BS2) == CAN_BS2_2TQ) || \
|
||||
((BS2) == CAN_BS2_3TQ) || ((BS2) == CAN_BS2_4TQ) || \
|
||||
((BS2) == CAN_BS2_5TQ) || ((BS2) == CAN_BS2_6TQ) || \
|
||||
((BS2) == CAN_BS2_7TQ) || ((BS2) == CAN_BS2_8TQ))
|
||||
#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1U) && ((PRESCALER) <= 1024U))
|
||||
#define IS_CAN_FILTER_ID_HALFWORD(HALFWORD) ((HALFWORD) <= 0xFFFFU)
|
||||
#if defined(CAN2)
|
||||
#define IS_CAN_FILTER_BANK_DUAL(BANK) ((BANK) <= 27U)
|
||||
#endif
|
||||
#define IS_CAN_FILTER_BANK_SINGLE(BANK) ((BANK) <= 13U)
|
||||
#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FILTERMODE_IDMASK) || \
|
||||
((MODE) == CAN_FILTERMODE_IDLIST))
|
||||
#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FILTERSCALE_16BIT) || \
|
||||
((SCALE) == CAN_FILTERSCALE_32BIT))
|
||||
#define IS_CAN_FILTER_ACTIVATION(ACTIVATION) (((ACTIVATION) == CAN_FILTER_DISABLE) || \
|
||||
((ACTIVATION) == CAN_FILTER_ENABLE))
|
||||
#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FILTER_FIFO0) || \
|
||||
((FIFO) == CAN_FILTER_FIFO1))
|
||||
#define IS_CAN_TX_MAILBOX(TRANSMITMAILBOX) (((TRANSMITMAILBOX) == CAN_TX_MAILBOX0 ) || \
|
||||
((TRANSMITMAILBOX) == CAN_TX_MAILBOX1 ) || \
|
||||
((TRANSMITMAILBOX) == CAN_TX_MAILBOX2 ))
|
||||
#define IS_CAN_TX_MAILBOX_LIST(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= (CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | \
|
||||
CAN_TX_MAILBOX2))
|
||||
#define IS_CAN_STDID(STDID) ((STDID) <= 0x7FFU)
|
||||
#define IS_CAN_EXTID(EXTID) ((EXTID) <= 0x1FFFFFFFU)
|
||||
#define IS_CAN_DLC(DLC) ((DLC) <= 8U)
|
||||
#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_ID_STD) || \
|
||||
((IDTYPE) == CAN_ID_EXT))
|
||||
#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_DATA) || ((RTR) == CAN_RTR_REMOTE))
|
||||
#define IS_CAN_RX_FIFO(FIFO) (((FIFO) == CAN_RX_FIFO0) || ((FIFO) == CAN_RX_FIFO1))
|
||||
#define IS_CAN_IT(IT) ((IT) <= (CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_RX_FIFO0_MSG_PENDING | \
|
||||
CAN_IT_RX_FIFO0_FULL | CAN_IT_RX_FIFO0_OVERRUN | \
|
||||
CAN_IT_RX_FIFO1_MSG_PENDING | CAN_IT_RX_FIFO1_FULL | \
|
||||
CAN_IT_RX_FIFO1_OVERRUN | CAN_IT_WAKEUP | \
|
||||
CAN_IT_SLEEP_ACK | CAN_IT_ERROR_WARNING | \
|
||||
CAN_IT_ERROR_PASSIVE | CAN_IT_BUSOFF | \
|
||||
CAN_IT_LAST_ERROR_CODE | CAN_IT_ERROR))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* End of private macros -----------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#endif /* CAN1 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32F1xx_HAL_CAN_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_can_ex_legacy.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of CAN HAL Extension module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F1xx_HAL_CAN_EX_LEGACY_H
|
||||
#define __STM32F1xx_HAL_CAN_EX_LEGACY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || \
|
||||
defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal_def.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CANEx CANEx
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief CAN filter configuration structure definition
|
||||
*/
|
||||
/* CAN filter banks differences over STM32F1 devices: */
|
||||
/* - STM32F1 Connectivity line: 28 filter banks shared between CAN1 and CAN2 */
|
||||
/* - Other STM32F10x devices: 14 filter banks */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit
|
||||
configuration, first one for a 16-bit configuration).
|
||||
This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit
|
||||
configuration, second one for a 16-bit configuration).
|
||||
This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number,
|
||||
according to the mode (MSBs for a 32-bit configuration,
|
||||
first one for a 16-bit configuration).
|
||||
This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterMaskIdLow; /*!< Specifies the filter mask number or identification number,
|
||||
according to the mode (LSBs for a 32-bit configuration,
|
||||
second one for a 16-bit configuration).
|
||||
This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1) which will be assigned to the filter.
|
||||
This parameter can be a value of @ref CAN_filter_FIFO */
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
uint32_t FilterNumber; /*!< Specifies the filter which will be initialized.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 27. */
|
||||
#else
|
||||
uint32_t FilterNumber; /*!< Specifies the filter which will be initialized.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 13. */
|
||||
#endif /* STM32F105xC || STM32F107xC */
|
||||
uint32_t FilterMode; /*!< Specifies the filter mode to be initialized.
|
||||
This parameter can be a value of @ref CAN_filter_mode */
|
||||
|
||||
uint32_t FilterScale; /*!< Specifies the filter scale.
|
||||
This parameter can be a value of @ref CAN_filter_scale */
|
||||
|
||||
uint32_t FilterActivation; /*!< Enable or disable the filter.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
uint32_t BankNumber; /*!< Select the start slave bank filter
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 28. */
|
||||
|
||||
}CAN_FilterConfTypeDef;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
|
||||
/** @defgroup CANEx_Private_Macros CAN Extended Private Macros
|
||||
* @{
|
||||
*/
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
#define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 27U)
|
||||
#else
|
||||
#define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 13U)
|
||||
#endif /* STM32F105xC || STM32F107xC */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* STM32F103x6) || STM32F103xB || STM32F103xE || STM32F103xG) || STM32F105xC || STM32F107xC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F1xx_HAL_CAN_EX_LEGACY_H */
|
|
@ -0,0 +1,776 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_can_legacy.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of CAN HAL module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F1xx_HAL_CAN_LEGACY_H
|
||||
#define __STM32F1xx_HAL_CAN_LEGACY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || \
|
||||
defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal_def.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/** @defgroup CAN_Exported_Types CAN Exported Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief HAL State structures definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_CAN_STATE_RESET = 0x00U, /*!< CAN not yet initialized or disabled */
|
||||
HAL_CAN_STATE_READY = 0x01U, /*!< CAN initialized and ready for use */
|
||||
HAL_CAN_STATE_BUSY = 0x02U, /*!< CAN process is ongoing */
|
||||
HAL_CAN_STATE_BUSY_TX = 0x12U, /*!< CAN process is ongoing */
|
||||
HAL_CAN_STATE_BUSY_RX0 = 0x22U, /*!< CAN process is ongoing */
|
||||
HAL_CAN_STATE_BUSY_RX1 = 0x32U, /*!< CAN process is ongoing */
|
||||
HAL_CAN_STATE_BUSY_TX_RX0 = 0x42U, /*!< CAN process is ongoing */
|
||||
HAL_CAN_STATE_BUSY_TX_RX1 = 0x52U, /*!< CAN process is ongoing */
|
||||
HAL_CAN_STATE_BUSY_RX0_RX1 = 0x62U, /*!< CAN process is ongoing */
|
||||
HAL_CAN_STATE_BUSY_TX_RX0_RX1 = 0x72U, /*!< CAN process is ongoing */
|
||||
HAL_CAN_STATE_TIMEOUT = 0x03U, /*!< CAN in Timeout state */
|
||||
HAL_CAN_STATE_ERROR = 0x04U /*!< CAN error state */
|
||||
|
||||
}HAL_CAN_StateTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN init structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Prescaler; /*!< Specifies the length of a time quantum.
|
||||
This parameter must be a number between Min_Data = 1 and Max_Data = 1024 */
|
||||
|
||||
uint32_t Mode; /*!< Specifies the CAN operating mode.
|
||||
This parameter can be a value of @ref CAN_operating_mode */
|
||||
|
||||
uint32_t SJW; /*!< Specifies the maximum number of time quanta
|
||||
the CAN hardware is allowed to lengthen or
|
||||
shorten a bit to perform resynchronization.
|
||||
This parameter can be a value of @ref CAN_synchronisation_jump_width */
|
||||
|
||||
uint32_t BS1; /*!< Specifies the number of time quanta in Bit Segment 1.
|
||||
This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */
|
||||
|
||||
uint32_t BS2; /*!< Specifies the number of time quanta in Bit Segment 2.
|
||||
This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */
|
||||
|
||||
uint32_t TTCM; /*!< Enable or disable the time triggered communication mode.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
uint32_t ABOM; /*!< Enable or disable the automatic bus-off management.
|
||||
This parameter can be set to ENABLE or DISABLE */
|
||||
|
||||
uint32_t AWUM; /*!< Enable or disable the automatic wake-up mode.
|
||||
This parameter can be set to ENABLE or DISABLE */
|
||||
|
||||
uint32_t NART; /*!< Enable or disable the non-automatic retransmission mode.
|
||||
This parameter can be set to ENABLE or DISABLE */
|
||||
|
||||
uint32_t RFLM; /*!< Enable or disable the receive FIFO Locked mode.
|
||||
This parameter can be set to ENABLE or DISABLE */
|
||||
|
||||
uint32_t TXFP; /*!< Enable or disable the transmit FIFO priority.
|
||||
This parameter can be set to ENABLE or DISABLE */
|
||||
}CAN_InitTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN Tx message structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t StdId; /*!< Specifies the standard identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */
|
||||
|
||||
uint32_t ExtId; /*!< Specifies the extended identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */
|
||||
|
||||
uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
|
||||
This parameter can be a value of @ref CAN_Identifier_Type */
|
||||
|
||||
uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
|
||||
This parameter can be a value of @ref CAN_remote_transmission_request */
|
||||
|
||||
uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 8 */
|
||||
|
||||
uint8_t Data[8]; /*!< Contains the data to be transmitted.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
|
||||
|
||||
}CanTxMsgTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN Rx message structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t StdId; /*!< Specifies the standard identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */
|
||||
|
||||
uint32_t ExtId; /*!< Specifies the extended identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */
|
||||
|
||||
uint32_t IDE; /*!< Specifies the type of identifier for the message that will be received.
|
||||
This parameter can be a value of @ref CAN_Identifier_Type */
|
||||
|
||||
uint32_t RTR; /*!< Specifies the type of frame for the received message.
|
||||
This parameter can be a value of @ref CAN_remote_transmission_request */
|
||||
|
||||
uint32_t DLC; /*!< Specifies the length of the frame that will be received.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 8 */
|
||||
|
||||
uint8_t Data[8]; /*!< Contains the data to be received.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
|
||||
|
||||
uint32_t FMI; /*!< Specifies the index of the filter the message stored in the mailbox passes through.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
|
||||
|
||||
uint32_t FIFONumber; /*!< Specifies the receive FIFO number.
|
||||
This parameter can be CAN_FIFO0 or CAN_FIFO1 */
|
||||
|
||||
}CanRxMsgTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN handle Structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
CAN_TypeDef *Instance; /*!< Register base address */
|
||||
|
||||
CAN_InitTypeDef Init; /*!< CAN required parameters */
|
||||
|
||||
CanTxMsgTypeDef* pTxMsg; /*!< Pointer to transmit structure */
|
||||
|
||||
CanRxMsgTypeDef* pRxMsg; /*!< Pointer to reception structure for RX FIFO0 msg */
|
||||
|
||||
CanRxMsgTypeDef* pRx1Msg; /*!< Pointer to reception structure for RX FIFO1 msg */
|
||||
|
||||
__IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */
|
||||
|
||||
HAL_LockTypeDef Lock; /*!< CAN locking object */
|
||||
|
||||
__IO uint32_t ErrorCode; /*!< CAN Error code */
|
||||
|
||||
}CAN_HandleTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/** @defgroup CAN_Exported_Constants CAN Exported Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Error_Code CAN Error Code
|
||||
* @{
|
||||
*/
|
||||
#define HAL_CAN_ERROR_NONE 0x00000000U /*!< No error */
|
||||
#define HAL_CAN_ERROR_EWG 0x00000001U /*!< EWG error */
|
||||
#define HAL_CAN_ERROR_EPV 0x00000002U /*!< EPV error */
|
||||
#define HAL_CAN_ERROR_BOF 0x00000004U /*!< BOF error */
|
||||
#define HAL_CAN_ERROR_STF 0x00000008U /*!< Stuff error */
|
||||
#define HAL_CAN_ERROR_FOR 0x00000010U /*!< Form error */
|
||||
#define HAL_CAN_ERROR_ACK 0x00000020U /*!< Acknowledgment error */
|
||||
#define HAL_CAN_ERROR_BR 0x00000040U /*!< Bit recessive */
|
||||
#define HAL_CAN_ERROR_BD 0x00000080U /*!< LEC dominant */
|
||||
#define HAL_CAN_ERROR_CRC 0x00000100U /*!< LEC transfer error */
|
||||
#define HAL_CAN_ERROR_FOV0 0x00000200U /*!< FIFO0 overrun error */
|
||||
#define HAL_CAN_ERROR_FOV1 0x00000400U /*!< FIFO1 overrun error */
|
||||
#define HAL_CAN_ERROR_TXFAIL 0x00000800U /*!< Transmit failure */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_InitStatus CAN initialization Status
|
||||
* @{
|
||||
*/
|
||||
#define CAN_INITSTATUS_FAILED 0x00000000U /*!< CAN initialization failed */
|
||||
#define CAN_INITSTATUS_SUCCESS 0x00000001U /*!< CAN initialization OK */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_operating_mode CAN Operating Mode
|
||||
* @{
|
||||
*/
|
||||
#define CAN_MODE_NORMAL 0x00000000U /*!< Normal mode */
|
||||
#define CAN_MODE_LOOPBACK ((uint32_t)CAN_BTR_LBKM) /*!< Loopback mode */
|
||||
#define CAN_MODE_SILENT ((uint32_t)CAN_BTR_SILM) /*!< Silent mode */
|
||||
#define CAN_MODE_SILENT_LOOPBACK ((uint32_t)(CAN_BTR_LBKM | CAN_BTR_SILM)) /*!< Loopback combined with silent mode */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_synchronisation_jump_width CAN Synchronization Jump Width
|
||||
* @{
|
||||
*/
|
||||
#define CAN_SJW_1TQ 0x00000000U /*!< 1 time quantum */
|
||||
#define CAN_SJW_2TQ ((uint32_t)CAN_BTR_SJW_0) /*!< 2 time quantum */
|
||||
#define CAN_SJW_3TQ ((uint32_t)CAN_BTR_SJW_1) /*!< 3 time quantum */
|
||||
#define CAN_SJW_4TQ ((uint32_t)CAN_BTR_SJW) /*!< 4 time quantum */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_time_quantum_in_bit_segment_1 CAN Time Quantum in Bit Segment 1
|
||||
* @{
|
||||
*/
|
||||
#define CAN_BS1_1TQ 0x00000000U /*!< 1 time quantum */
|
||||
#define CAN_BS1_2TQ ((uint32_t)CAN_BTR_TS1_0) /*!< 2 time quantum */
|
||||
#define CAN_BS1_3TQ ((uint32_t)CAN_BTR_TS1_1) /*!< 3 time quantum */
|
||||
#define CAN_BS1_4TQ ((uint32_t)(CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 4 time quantum */
|
||||
#define CAN_BS1_5TQ ((uint32_t)CAN_BTR_TS1_2) /*!< 5 time quantum */
|
||||
#define CAN_BS1_6TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 6 time quantum */
|
||||
#define CAN_BS1_7TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 7 time quantum */
|
||||
#define CAN_BS1_8TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 8 time quantum */
|
||||
#define CAN_BS1_9TQ ((uint32_t)CAN_BTR_TS1_3) /*!< 9 time quantum */
|
||||
#define CAN_BS1_10TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_0)) /*!< 10 time quantum */
|
||||
#define CAN_BS1_11TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1)) /*!< 11 time quantum */
|
||||
#define CAN_BS1_12TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 12 time quantum */
|
||||
#define CAN_BS1_13TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2)) /*!< 13 time quantum */
|
||||
#define CAN_BS1_14TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 14 time quantum */
|
||||
#define CAN_BS1_15TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 15 time quantum */
|
||||
#define CAN_BS1_16TQ ((uint32_t)CAN_BTR_TS1) /*!< 16 time quantum */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_time_quantum_in_bit_segment_2 CAN Time Quantum in bit segment 2
|
||||
* @{
|
||||
*/
|
||||
#define CAN_BS2_1TQ 0x00000000U /*!< 1 time quantum */
|
||||
#define CAN_BS2_2TQ ((uint32_t)CAN_BTR_TS2_0) /*!< 2 time quantum */
|
||||
#define CAN_BS2_3TQ ((uint32_t)CAN_BTR_TS2_1) /*!< 3 time quantum */
|
||||
#define CAN_BS2_4TQ ((uint32_t)(CAN_BTR_TS2_1 | CAN_BTR_TS2_0)) /*!< 4 time quantum */
|
||||
#define CAN_BS2_5TQ ((uint32_t)CAN_BTR_TS2_2) /*!< 5 time quantum */
|
||||
#define CAN_BS2_6TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_0)) /*!< 6 time quantum */
|
||||
#define CAN_BS2_7TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_1)) /*!< 7 time quantum */
|
||||
#define CAN_BS2_8TQ ((uint32_t)CAN_BTR_TS2) /*!< 8 time quantum */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_filter_mode CAN Filter Mode
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FILTERMODE_IDMASK ((uint8_t)0x00) /*!< Identifier mask mode */
|
||||
#define CAN_FILTERMODE_IDLIST ((uint8_t)0x01) /*!< Identifier list mode */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_filter_scale CAN Filter Scale
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FILTERSCALE_16BIT ((uint8_t)0x00) /*!< Two 16-bit filters */
|
||||
#define CAN_FILTERSCALE_32BIT ((uint8_t)0x01) /*!< One 32-bit filter */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_filter_FIFO CAN Filter FIFO
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FILTER_FIFO0 ((uint8_t)0x00) /*!< Filter FIFO 0 assignment for filter x */
|
||||
#define CAN_FILTER_FIFO1 ((uint8_t)0x01) /*!< Filter FIFO 1 assignment for filter x */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Identifier_Type CAN Identifier Type
|
||||
* @{
|
||||
*/
|
||||
#define CAN_ID_STD 0x00000000U /*!< Standard Id */
|
||||
#define CAN_ID_EXT 0x00000004U /*!< Extended Id */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_remote_transmission_request CAN Remote Transmission Request
|
||||
* @{
|
||||
*/
|
||||
#define CAN_RTR_DATA 0x00000000U /*!< Data frame */
|
||||
#define CAN_RTR_REMOTE 0x00000002U /*!< Remote frame */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_transmit_constants CAN Transmit Constants
|
||||
* @{
|
||||
*/
|
||||
#define CAN_TXSTATUS_NOMAILBOX ((uint8_t)0x04) /*!< CAN cell did not provide CAN_TxStatus_NoMailBox */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_receive_FIFO_number_constants CAN Receive FIFO Number
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FIFO0 ((uint8_t)0x00) /*!< CAN FIFO 0 used to receive */
|
||||
#define CAN_FIFO1 ((uint8_t)0x01) /*!< CAN FIFO 1 used to receive */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_flags CAN Flags
|
||||
* @{
|
||||
*/
|
||||
/* If the flag is 0x3XXXXXXX, it means that it can be used with CAN_GetFlagStatus()
|
||||
and CAN_ClearFlag() functions. */
|
||||
/* If the flag is 0x1XXXXXXX, it means that it can only be used with
|
||||
CAN_GetFlagStatus() function. */
|
||||
|
||||
/* Transmit Flags */
|
||||
#define CAN_FLAG_RQCP0 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_RQCP0_BIT_POSITION)) /*!< Request MailBox0 flag */
|
||||
#define CAN_FLAG_RQCP1 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_RQCP1_BIT_POSITION)) /*!< Request MailBox1 flag */
|
||||
#define CAN_FLAG_RQCP2 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_RQCP2_BIT_POSITION)) /*!< Request MailBox2 flag */
|
||||
#define CAN_FLAG_TXOK0 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TXOK0_BIT_POSITION)) /*!< Transmission OK MailBox0 flag */
|
||||
#define CAN_FLAG_TXOK1 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TXOK1_BIT_POSITION)) /*!< Transmission OK MailBox1 flag */
|
||||
#define CAN_FLAG_TXOK2 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TXOK2_BIT_POSITION)) /*!< Transmission OK MailBox2 flag */
|
||||
#define CAN_FLAG_TME0 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TME0_BIT_POSITION)) /*!< Transmit mailbox 0 empty flag */
|
||||
#define CAN_FLAG_TME1 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TME1_BIT_POSITION)) /*!< Transmit mailbox 0 empty flag */
|
||||
#define CAN_FLAG_TME2 ((uint32_t)((TSR_REGISTER_INDEX << 8U) | CAN_TSR_TME2_BIT_POSITION)) /*!< Transmit mailbox 0 empty flag */
|
||||
|
||||
/* Receive Flags */
|
||||
#define CAN_FLAG_FF0 ((uint32_t)((RF0R_REGISTER_INDEX << 8U) | CAN_RF0R_FF0_BIT_POSITION)) /*!< FIFO 0 Full flag */
|
||||
#define CAN_FLAG_FOV0 ((uint32_t)((RF0R_REGISTER_INDEX << 8U) | CAN_RF0R_FOV0_BIT_POSITION)) /*!< FIFO 0 Overrun flag */
|
||||
|
||||
#define CAN_FLAG_FF1 ((uint32_t)((RF1R_REGISTER_INDEX << 8U) | CAN_RF1R_FF1_BIT_POSITION)) /*!< FIFO 1 Full flag */
|
||||
#define CAN_FLAG_FOV1 ((uint32_t)((RF1R_REGISTER_INDEX << 8U) | CAN_RF1R_FOV1_BIT_POSITION)) /*!< FIFO 1 Overrun flag */
|
||||
|
||||
/* Operating Mode Flags */
|
||||
#define CAN_FLAG_WKU ((uint32_t)((MSR_REGISTER_INDEX << 8U) | CAN_MSR_WKU_BIT_POSITION)) /*!< Wake up flag */
|
||||
#define CAN_FLAG_SLAK ((uint32_t)((MSR_REGISTER_INDEX << 8U) | CAN_MSR_SLAK_BIT_POSITION)) /*!< Sleep acknowledge flag */
|
||||
#define CAN_FLAG_SLAKI ((uint32_t)((MSR_REGISTER_INDEX << 8U) | CAN_MSR_SLAKI_BIT_POSITION)) /*!< Sleep acknowledge flag */
|
||||
|
||||
/* @note When SLAK interrupt is disabled (SLKIE=0), no polling on SLAKI is possible.
|
||||
In this case the SLAK bit can be polled.*/
|
||||
|
||||
/* Error Flags */
|
||||
#define CAN_FLAG_EWG ((uint32_t)((ESR_REGISTER_INDEX << 8U) | CAN_ESR_EWG_BIT_POSITION)) /*!< Error warning flag */
|
||||
#define CAN_FLAG_EPV ((uint32_t)((ESR_REGISTER_INDEX << 8U) | CAN_ESR_EPV_BIT_POSITION)) /*!< Error passive flag */
|
||||
#define CAN_FLAG_BOF ((uint32_t)((ESR_REGISTER_INDEX << 8U) | CAN_ESR_BOF_BIT_POSITION)) /*!< Bus-Off flag */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Interrupts CAN Interrupts
|
||||
* @{
|
||||
*/
|
||||
#define CAN_IT_TME ((uint32_t)CAN_IER_TMEIE) /*!< Transmit mailbox empty interrupt */
|
||||
|
||||
/* Receive Interrupts */
|
||||
#define CAN_IT_FMP0 ((uint32_t)CAN_IER_FMPIE0) /*!< FIFO 0 message pending interrupt */
|
||||
#define CAN_IT_FF0 ((uint32_t)CAN_IER_FFIE0) /*!< FIFO 0 full interrupt */
|
||||
#define CAN_IT_FOV0 ((uint32_t)CAN_IER_FOVIE0) /*!< FIFO 0 overrun interrupt */
|
||||
#define CAN_IT_FMP1 ((uint32_t)CAN_IER_FMPIE1) /*!< FIFO 1 message pending interrupt */
|
||||
#define CAN_IT_FF1 ((uint32_t)CAN_IER_FFIE1) /*!< FIFO 1 full interrupt */
|
||||
#define CAN_IT_FOV1 ((uint32_t)CAN_IER_FOVIE1) /*!< FIFO 1 overrun interrupt */
|
||||
|
||||
/* Operating Mode Interrupts */
|
||||
#define CAN_IT_WKU ((uint32_t)CAN_IER_WKUIE) /*!< Wake-up interrupt */
|
||||
#define CAN_IT_SLK ((uint32_t)CAN_IER_SLKIE) /*!< Sleep acknowledge interrupt */
|
||||
|
||||
/* Error Interrupts */
|
||||
#define CAN_IT_EWG ((uint32_t)CAN_IER_EWGIE) /*!< Error warning interrupt */
|
||||
#define CAN_IT_EPV ((uint32_t)CAN_IER_EPVIE) /*!< Error passive interrupt */
|
||||
#define CAN_IT_BOF ((uint32_t)CAN_IER_BOFIE) /*!< Bus-off interrupt */
|
||||
#define CAN_IT_LEC ((uint32_t)CAN_IER_LECIE) /*!< Last error code interrupt */
|
||||
#define CAN_IT_ERR ((uint32_t)CAN_IER_ERRIE) /*!< Error Interrupt */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Private_Constants CAN Private Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* CAN intermediate shift values used for CAN flags */
|
||||
#define TSR_REGISTER_INDEX 0x5U
|
||||
#define RF0R_REGISTER_INDEX 0x2U
|
||||
#define RF1R_REGISTER_INDEX 0x4U
|
||||
#define MSR_REGISTER_INDEX 0x1U
|
||||
#define ESR_REGISTER_INDEX 0x3U
|
||||
|
||||
/* CAN flags bits position into their respective register (TSR, RF0R, RF1R or MSR registers) */
|
||||
/* Transmit Flags */
|
||||
#define CAN_TSR_RQCP0_BIT_POSITION 0x00000000U
|
||||
#define CAN_TSR_RQCP1_BIT_POSITION 0x00000008U
|
||||
#define CAN_TSR_RQCP2_BIT_POSITION 0x00000010U
|
||||
#define CAN_TSR_TXOK0_BIT_POSITION 0x00000001U
|
||||
#define CAN_TSR_TXOK1_BIT_POSITION 0x00000009U
|
||||
#define CAN_TSR_TXOK2_BIT_POSITION 0x00000011U
|
||||
#define CAN_TSR_TME0_BIT_POSITION 0x0000001AU
|
||||
#define CAN_TSR_TME1_BIT_POSITION 0x0000001BU
|
||||
#define CAN_TSR_TME2_BIT_POSITION 0x0000001CU
|
||||
|
||||
/* Receive Flags */
|
||||
#define CAN_RF0R_FF0_BIT_POSITION 0x00000003U
|
||||
#define CAN_RF0R_FOV0_BIT_POSITION 0x00000004U
|
||||
|
||||
#define CAN_RF1R_FF1_BIT_POSITION 0x00000003U
|
||||
#define CAN_RF1R_FOV1_BIT_POSITION 0x00000004U
|
||||
|
||||
/* Operating Mode Flags */
|
||||
#define CAN_MSR_WKU_BIT_POSITION 0x00000003U
|
||||
#define CAN_MSR_SLAK_BIT_POSITION 0x00000001U
|
||||
#define CAN_MSR_SLAKI_BIT_POSITION 0x00000004U
|
||||
|
||||
/* Error Flags */
|
||||
#define CAN_ESR_EWG_BIT_POSITION 0x00000000U
|
||||
#define CAN_ESR_EPV_BIT_POSITION 0x00000001U
|
||||
#define CAN_ESR_BOF_BIT_POSITION 0x00000002U
|
||||
|
||||
/* Mask used by macro to get/clear CAN flags*/
|
||||
#define CAN_FLAG_MASK 0x000000FFU
|
||||
|
||||
/* Mailboxes definition */
|
||||
#define CAN_TXMAILBOX_0 ((uint8_t)0x00)
|
||||
#define CAN_TXMAILBOX_1 ((uint8_t)0x01)
|
||||
#define CAN_TXMAILBOX_2 ((uint8_t)0x02)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/** @defgroup CAN_Exported_Macros CAN Exported Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Reset CAN handle state
|
||||
* @param __HANDLE__: CAN handle.
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_CAN_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CAN_STATE_RESET)
|
||||
|
||||
/**
|
||||
* @brief Enable the specified CAN interrupts
|
||||
* @param __HANDLE__: CAN handle.
|
||||
* @param __INTERRUPT__: CAN Interrupt.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg CAN_IT_TME: Transmit mailbox empty interrupt enable
|
||||
* @arg CAN_IT_FMP0: FIFO 0 message pending interrupt
|
||||
* @arg CAN_IT_FF0 : FIFO 0 full interrupt
|
||||
* @arg CAN_IT_FOV0: FIFO 0 overrun interrupt
|
||||
* @arg CAN_IT_FMP1: FIFO 1 message pending interrupt
|
||||
* @arg CAN_IT_FF1 : FIFO 1 full interrupt
|
||||
* @arg CAN_IT_FOV1: FIFO 1 overrun interrupt
|
||||
* @arg CAN_IT_WKU : Wake-up interrupt
|
||||
* @arg CAN_IT_SLK : Sleep acknowledge interrupt
|
||||
* @arg CAN_IT_EWG : Error warning interrupt
|
||||
* @arg CAN_IT_EPV : Error passive interrupt
|
||||
* @arg CAN_IT_BOF : Bus-off interrupt
|
||||
* @arg CAN_IT_LEC : Last error code interrupt
|
||||
* @arg CAN_IT_ERR : Error Interrupt
|
||||
* @retval None.
|
||||
*/
|
||||
#define __HAL_CAN_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) |= (__INTERRUPT__))
|
||||
|
||||
/**
|
||||
* @brief Disable the specified CAN interrupts
|
||||
* @param __HANDLE__: CAN handle.
|
||||
* @param __INTERRUPT__: CAN Interrupt.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg CAN_IT_TME: Transmit mailbox empty interrupt enable
|
||||
* @arg CAN_IT_FMP0: FIFO 0 message pending interrupt
|
||||
* @arg CAN_IT_FF0 : FIFO 0 full interrupt
|
||||
* @arg CAN_IT_FOV0: FIFO 0 overrun interrupt
|
||||
* @arg CAN_IT_FMP1: FIFO 1 message pending interrupt
|
||||
* @arg CAN_IT_FF1 : FIFO 1 full interrupt
|
||||
* @arg CAN_IT_FOV1: FIFO 1 overrun interrupt
|
||||
* @arg CAN_IT_WKU : Wake-up interrupt
|
||||
* @arg CAN_IT_SLK : Sleep acknowledge interrupt
|
||||
* @arg CAN_IT_EWG : Error warning interrupt
|
||||
* @arg CAN_IT_EPV : Error passive interrupt
|
||||
* @arg CAN_IT_BOF : Bus-off interrupt
|
||||
* @arg CAN_IT_LEC : Last error code interrupt
|
||||
* @arg CAN_IT_ERR : Error Interrupt
|
||||
* @retval None.
|
||||
*/
|
||||
#define __HAL_CAN_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) &= ~(__INTERRUPT__))
|
||||
|
||||
/**
|
||||
* @brief Return the number of pending received messages.
|
||||
* @param __HANDLE__: CAN handle.
|
||||
* @param __FIFONUMBER__: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
|
||||
* @retval The number of pending message.
|
||||
*/
|
||||
#define __HAL_CAN_MSG_PENDING(__HANDLE__, __FIFONUMBER__) (((__FIFONUMBER__) == CAN_FIFO0)? \
|
||||
((uint8_t)((__HANDLE__)->Instance->RF0R & 0x03U)) : ((uint8_t)((__HANDLE__)->Instance->RF1R & 0x03U)))
|
||||
|
||||
/** @brief Check whether the specified CAN flag is set or not.
|
||||
* @param __HANDLE__: specifies the CAN Handle.
|
||||
* @param __FLAG__: specifies the flag to check.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg CAN_TSR_RQCP0: Request MailBox0 Flag
|
||||
* @arg CAN_TSR_RQCP1: Request MailBox1 Flag
|
||||
* @arg CAN_TSR_RQCP2: Request MailBox2 Flag
|
||||
* @arg CAN_FLAG_TXOK0: Transmission OK MailBox0 Flag
|
||||
* @arg CAN_FLAG_TXOK1: Transmission OK MailBox1 Flag
|
||||
* @arg CAN_FLAG_TXOK2: Transmission OK MailBox2 Flag
|
||||
* @arg CAN_FLAG_TME0: Transmit mailbox 0 empty Flag
|
||||
* @arg CAN_FLAG_TME1: Transmit mailbox 1 empty Flag
|
||||
* @arg CAN_FLAG_TME2: Transmit mailbox 2 empty Flag
|
||||
* @arg CAN_FLAG_FMP0: FIFO 0 Message Pending Flag
|
||||
* @arg CAN_FLAG_FF0: FIFO 0 Full Flag
|
||||
* @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag
|
||||
* @arg CAN_FLAG_FMP1: FIFO 1 Message Pending Flag
|
||||
* @arg CAN_FLAG_FF1: FIFO 1 Full Flag
|
||||
* @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag
|
||||
* @arg CAN_FLAG_WKU: Wake up Flag
|
||||
* @arg CAN_FLAG_SLAK: Sleep acknowledge Flag
|
||||
* @arg CAN_FLAG_SLAKI: Sleep acknowledge Flag
|
||||
* @arg CAN_FLAG_EWG: Error Warning Flag
|
||||
* @arg CAN_FLAG_EPV: Error Passive Flag
|
||||
* @arg CAN_FLAG_BOF: Bus-Off Flag
|
||||
* @retval The new state of __FLAG__ (TRUE or FALSE).
|
||||
*/
|
||||
#define __HAL_CAN_GET_FLAG(__HANDLE__, __FLAG__) \
|
||||
((((__FLAG__) >> 8U) == 5U)? ((((__HANDLE__)->Instance->TSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 2U)? ((((__HANDLE__)->Instance->RF0R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 4U)? ((((__HANDLE__)->Instance->RF1R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 1U)? ((((__HANDLE__)->Instance->MSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
((((__HANDLE__)->Instance->ESR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))))
|
||||
|
||||
/** @brief Clear the specified CAN pending flag.
|
||||
* @param __HANDLE__: specifies the CAN Handle.
|
||||
* @param __FLAG__: specifies the flag to check.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg CAN_TSR_RQCP0: Request MailBox0 Flag
|
||||
* @arg CAN_TSR_RQCP1: Request MailBox1 Flag
|
||||
* @arg CAN_TSR_RQCP2: Request MailBox2 Flag
|
||||
* @arg CAN_FLAG_TXOK0: Transmission OK MailBox0 Flag
|
||||
* @arg CAN_FLAG_TXOK1: Transmission OK MailBox1 Flag
|
||||
* @arg CAN_FLAG_TXOK2: Transmission OK MailBox2 Flag
|
||||
* @arg CAN_FLAG_TME0: Transmit mailbox 0 empty Flag
|
||||
* @arg CAN_FLAG_TME1: Transmit mailbox 1 empty Flag
|
||||
* @arg CAN_FLAG_TME2: Transmit mailbox 2 empty Flag
|
||||
* @arg CAN_FLAG_FMP0: FIFO 0 Message Pending Flag
|
||||
* @arg CAN_FLAG_FF0: FIFO 0 Full Flag
|
||||
* @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag
|
||||
* @arg CAN_FLAG_FMP1: FIFO 1 Message Pending Flag
|
||||
* @arg CAN_FLAG_FF1: FIFO 1 Full Flag
|
||||
* @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag
|
||||
* @arg CAN_FLAG_WKU: Wake up Flag
|
||||
* @arg CAN_FLAG_SLAKI: Sleep acknowledge Flag
|
||||
* @retval The new state of __FLAG__ (TRUE or FALSE).
|
||||
*/
|
||||
#define __HAL_CAN_CLEAR_FLAG(__HANDLE__, __FLAG__) \
|
||||
((((__FLAG__) >> 8U) == TSR_REGISTER_INDEX) ? (((__HANDLE__)->Instance->TSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == RF0R_REGISTER_INDEX)? (((__HANDLE__)->Instance->RF0R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == RF1R_REGISTER_INDEX)? (((__HANDLE__)->Instance->RF1R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == MSR_REGISTER_INDEX) ? (((__HANDLE__)->Instance->MSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): 0U)
|
||||
|
||||
/** @brief Check if the specified CAN interrupt source is enabled or disabled.
|
||||
* @param __HANDLE__: specifies the CAN Handle.
|
||||
* @param __INTERRUPT__: specifies the CAN interrupt source to check.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg CAN_IT_TME: Transmit mailbox empty interrupt enable
|
||||
* @arg CAN_IT_FMP0: FIFO 0 message pending interrupt
|
||||
* @arg CAN_IT_FF0 : FIFO 0 full interrupt
|
||||
* @arg CAN_IT_FOV0: FIFO 0 overrun interrupt
|
||||
* @arg CAN_IT_FMP1: FIFO 1 message pending interrupt
|
||||
* @arg CAN_IT_FF1 : FIFO 1 full interrupt
|
||||
* @arg CAN_IT_FOV1: FIFO 1 overrun interrupt
|
||||
* @arg CAN_IT_WKU : Wake-up interrupt
|
||||
* @arg CAN_IT_SLK : Sleep acknowledge interrupt
|
||||
* @arg CAN_IT_EWG : Error warning interrupt
|
||||
* @arg CAN_IT_EPV : Error passive interrupt
|
||||
* @arg CAN_IT_BOF : Bus-off interrupt
|
||||
* @arg CAN_IT_LEC : Last error code interrupt
|
||||
* @arg CAN_IT_ERR : Error Interrupt
|
||||
* @retval The new state of __IT__ (TRUE or FALSE).
|
||||
*/
|
||||
#define __HAL_CAN_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IER & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
|
||||
|
||||
/**
|
||||
* @brief Check the transmission status of a CAN Frame.
|
||||
* @param __HANDLE__: specifies the CAN Handle.
|
||||
* @param __TRANSMITMAILBOX__: the number of the mailbox that is used for transmission.
|
||||
* @retval The new status of transmission (TRUE or FALSE).
|
||||
*/
|
||||
#define __HAL_CAN_TRANSMIT_STATUS(__HANDLE__, __TRANSMITMAILBOX__)\
|
||||
(((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_0)? ((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP0 | CAN_TSR_TME0)) == (CAN_TSR_RQCP0 | CAN_TSR_TME0)) :\
|
||||
((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_1)? ((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP1 | CAN_TSR_TME1)) == (CAN_TSR_RQCP1 | CAN_TSR_TME1)) :\
|
||||
((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP2 | CAN_TSR_TME2)) == (CAN_TSR_RQCP2 | CAN_TSR_TME2)))
|
||||
|
||||
/**
|
||||
* @brief Release the specified receive FIFO.
|
||||
* @param __HANDLE__: CAN handle.
|
||||
* @param __FIFONUMBER__: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
|
||||
* @retval None.
|
||||
*/
|
||||
#define __HAL_CAN_FIFO_RELEASE(__HANDLE__, __FIFONUMBER__) (((__FIFONUMBER__) == CAN_FIFO0)? \
|
||||
((__HANDLE__)->Instance->RF0R = CAN_RF0R_RFOM0) : ((__HANDLE__)->Instance->RF1R = CAN_RF1R_RFOM1))
|
||||
|
||||
/**
|
||||
* @brief Cancel a transmit request.
|
||||
* @param __HANDLE__: specifies the CAN Handle.
|
||||
* @param __TRANSMITMAILBOX__: the number of the mailbox that is used for transmission.
|
||||
* @retval None.
|
||||
*/
|
||||
#define __HAL_CAN_CANCEL_TRANSMIT(__HANDLE__, __TRANSMITMAILBOX__)\
|
||||
(((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_0)? ((__HANDLE__)->Instance->TSR = CAN_TSR_ABRQ0) :\
|
||||
((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_1)? ((__HANDLE__)->Instance->TSR = CAN_TSR_ABRQ1) :\
|
||||
((__HANDLE__)->Instance->TSR = CAN_TSR_ABRQ2))
|
||||
|
||||
/**
|
||||
* @brief Enable or disables the DBG Freeze for CAN.
|
||||
* @param __HANDLE__: specifies the CAN Handle.
|
||||
* @param __NEWSTATE__: new state of the CAN peripheral.
|
||||
* This parameter can be: ENABLE (CAN reception/transmission is frozen
|
||||
* during debug. Reception FIFOs can still be accessed/controlled normally)
|
||||
* or DISABLE (CAN is working during debug).
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_CAN_DBG_FREEZE(__HANDLE__, __NEWSTATE__) (((__NEWSTATE__) == ENABLE)? \
|
||||
((__HANDLE__)->Instance->MCR |= CAN_MCR_DBF) : ((__HANDLE__)->Instance->MCR &= ~CAN_MCR_DBF))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Include CAN HAL Extension module */
|
||||
#include "stm32f1xx_hal_can_ex_legacy.h"
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup CAN_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group1
|
||||
* @brief Initialization and Configuration functions
|
||||
* @{
|
||||
*/
|
||||
/* Initialization and de-initialization functions *****************************/
|
||||
HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig);
|
||||
HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan);
|
||||
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan);
|
||||
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group2
|
||||
* @brief I/O operation functions
|
||||
* @{
|
||||
*/
|
||||
/* I/O operation functions *****************************************************/
|
||||
HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef *hcan, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef *hcan, uint8_t FIFONumber, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef *hcan, uint8_t FIFONumber);
|
||||
HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan);
|
||||
void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan);
|
||||
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan);
|
||||
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group3
|
||||
* @brief CAN Peripheral State functions
|
||||
* @{
|
||||
*/
|
||||
/* Peripheral State and Error functions ***************************************/
|
||||
uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan);
|
||||
HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros --------------------------------------------------------*/
|
||||
/** @defgroup CAN_Private_Macros CAN Private Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IS_CAN_MODE(MODE) (((MODE) == CAN_MODE_NORMAL) || \
|
||||
((MODE) == CAN_MODE_LOOPBACK)|| \
|
||||
((MODE) == CAN_MODE_SILENT) || \
|
||||
((MODE) == CAN_MODE_SILENT_LOOPBACK))
|
||||
#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1TQ) || ((SJW) == CAN_SJW_2TQ)|| \
|
||||
((SJW) == CAN_SJW_3TQ) || ((SJW) == CAN_SJW_4TQ))
|
||||
#define IS_CAN_BS1(BS1) ((BS1) <= CAN_BS1_16TQ)
|
||||
#define IS_CAN_BS2(BS2) ((BS2) <= CAN_BS2_8TQ)
|
||||
#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1U) && ((PRESCALER) <= 1024U))
|
||||
|
||||
#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FILTERMODE_IDMASK) || \
|
||||
((MODE) == CAN_FILTERMODE_IDLIST))
|
||||
#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FILTERSCALE_16BIT) || \
|
||||
((SCALE) == CAN_FILTERSCALE_32BIT))
|
||||
#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FILTER_FIFO0) || \
|
||||
((FIFO) == CAN_FILTER_FIFO1))
|
||||
#define IS_CAN_BANKNUMBER(BANKNUMBER) ((BANKNUMBER) <= 28U)
|
||||
|
||||
#define IS_CAN_TRANSMITMAILBOX(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= ((uint8_t)0x02))
|
||||
#define IS_CAN_STDID(STDID) ((STDID) <= 0x00007FFU)
|
||||
#define IS_CAN_EXTID(EXTID) ((EXTID) <= 0x1FFFFFFFU)
|
||||
#define IS_CAN_DLC(DLC) ((DLC) <= ((uint8_t)0x08))
|
||||
|
||||
#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_ID_STD) || \
|
||||
((IDTYPE) == CAN_ID_EXT))
|
||||
#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_DATA) || ((RTR) == CAN_RTR_REMOTE))
|
||||
#define IS_CAN_FIFO(FIFO) (((FIFO) == CAN_FIFO0) || ((FIFO) == CAN_FIFO1))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* STM32F103x6) || STM32F103xB || STM32F103xE || STM32F103xG) || STM32F105xC || STM32F107xC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F1xx_HAL_CAN_LEGACY_H */
|
|
@ -0,0 +1,859 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_can.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of CAN HAL module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32F1xx_HAL_CAN_H
|
||||
#define STM32F1xx_HAL_CAN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal_def.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (CAN1)
|
||||
/** @addtogroup CAN
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/** @defgroup CAN_Exported_Types CAN Exported Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief HAL State structures definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_CAN_STATE_RESET = 0x00U, /*!< CAN not yet initialized or disabled */
|
||||
HAL_CAN_STATE_READY = 0x01U, /*!< CAN initialized and ready for use */
|
||||
HAL_CAN_STATE_LISTENING = 0x02U, /*!< CAN receive process is ongoing */
|
||||
HAL_CAN_STATE_SLEEP_PENDING = 0x03U, /*!< CAN sleep request is pending */
|
||||
HAL_CAN_STATE_SLEEP_ACTIVE = 0x04U, /*!< CAN sleep mode is active */
|
||||
HAL_CAN_STATE_ERROR = 0x05U /*!< CAN error state */
|
||||
|
||||
} HAL_CAN_StateTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN init structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Prescaler; /*!< Specifies the length of a time quantum.
|
||||
This parameter must be a number between Min_Data = 1 and Max_Data = 1024. */
|
||||
|
||||
uint32_t Mode; /*!< Specifies the CAN operating mode.
|
||||
This parameter can be a value of @ref CAN_operating_mode */
|
||||
|
||||
uint32_t SyncJumpWidth; /*!< Specifies the maximum number of time quanta the CAN hardware
|
||||
is allowed to lengthen or shorten a bit to perform resynchronization.
|
||||
This parameter can be a value of @ref CAN_synchronisation_jump_width */
|
||||
|
||||
uint32_t TimeSeg1; /*!< Specifies the number of time quanta in Bit Segment 1.
|
||||
This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */
|
||||
|
||||
uint32_t TimeSeg2; /*!< Specifies the number of time quanta in Bit Segment 2.
|
||||
This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */
|
||||
|
||||
FunctionalState TimeTriggeredMode; /*!< Enable or disable the time triggered communication mode.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
FunctionalState AutoBusOff; /*!< Enable or disable the automatic bus-off management.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
FunctionalState AutoWakeUp; /*!< Enable or disable the automatic wake-up mode.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
FunctionalState AutoRetransmission; /*!< Enable or disable the non-automatic retransmission mode.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
FunctionalState ReceiveFifoLocked; /*!< Enable or disable the Receive FIFO Locked mode.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
FunctionalState TransmitFifoPriority;/*!< Enable or disable the transmit FIFO priority.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
} CAN_InitTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN filter configuration structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit
|
||||
configuration, first one for a 16-bit configuration).
|
||||
This parameter must be a number between
|
||||
Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit
|
||||
configuration, second one for a 16-bit configuration).
|
||||
This parameter must be a number between
|
||||
Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number,
|
||||
according to the mode (MSBs for a 32-bit configuration,
|
||||
first one for a 16-bit configuration).
|
||||
This parameter must be a number between
|
||||
Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterMaskIdLow; /*!< Specifies the filter mask number or identification number,
|
||||
according to the mode (LSBs for a 32-bit configuration,
|
||||
second one for a 16-bit configuration).
|
||||
This parameter must be a number between
|
||||
Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1U) which will be assigned to the filter.
|
||||
This parameter can be a value of @ref CAN_filter_FIFO */
|
||||
|
||||
uint32_t FilterBank; /*!< Specifies the filter bank which will be initialized.
|
||||
For single CAN instance(14 dedicated filter banks),
|
||||
this parameter must be a number between Min_Data = 0 and Max_Data = 13.
|
||||
For dual CAN instances(28 filter banks shared),
|
||||
this parameter must be a number between Min_Data = 0 and Max_Data = 27. */
|
||||
|
||||
uint32_t FilterMode; /*!< Specifies the filter mode to be initialized.
|
||||
This parameter can be a value of @ref CAN_filter_mode */
|
||||
|
||||
uint32_t FilterScale; /*!< Specifies the filter scale.
|
||||
This parameter can be a value of @ref CAN_filter_scale */
|
||||
|
||||
uint32_t FilterActivation; /*!< Enable or disable the filter.
|
||||
This parameter can be a value of @ref CAN_filter_activation */
|
||||
|
||||
uint32_t SlaveStartFilterBank; /*!< Select the start filter bank for the slave CAN instance.
|
||||
For single CAN instances, this parameter is meaningless.
|
||||
For dual CAN instances, all filter banks with lower index are assigned to master
|
||||
CAN instance, whereas all filter banks with greater index are assigned to slave
|
||||
CAN instance.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 27. */
|
||||
|
||||
} CAN_FilterTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN Tx message header structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t StdId; /*!< Specifies the standard identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */
|
||||
|
||||
uint32_t ExtId; /*!< Specifies the extended identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */
|
||||
|
||||
uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
|
||||
This parameter can be a value of @ref CAN_identifier_type */
|
||||
|
||||
uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
|
||||
This parameter can be a value of @ref CAN_remote_transmission_request */
|
||||
|
||||
uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 8. */
|
||||
|
||||
FunctionalState TransmitGlobalTime; /*!< Specifies whether the timestamp counter value captured on start
|
||||
of frame transmission, is sent in DATA6 and DATA7 replacing pData[6] and pData[7].
|
||||
@note: Time Triggered Communication Mode must be enabled.
|
||||
@note: DLC must be programmed as 8 bytes, in order these 2 bytes are sent.
|
||||
This parameter can be set to ENABLE or DISABLE. */
|
||||
|
||||
} CAN_TxHeaderTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN Rx message header structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t StdId; /*!< Specifies the standard identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */
|
||||
|
||||
uint32_t ExtId; /*!< Specifies the extended identifier.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF. */
|
||||
|
||||
uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
|
||||
This parameter can be a value of @ref CAN_identifier_type */
|
||||
|
||||
uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
|
||||
This parameter can be a value of @ref CAN_remote_transmission_request */
|
||||
|
||||
uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 8. */
|
||||
|
||||
uint32_t Timestamp; /*!< Specifies the timestamp counter value captured on start of frame reception.
|
||||
@note: Time Triggered Communication Mode must be enabled.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0xFFFF. */
|
||||
|
||||
uint32_t FilterMatchIndex; /*!< Specifies the index of matching acceptance filter element.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF. */
|
||||
|
||||
} CAN_RxHeaderTypeDef;
|
||||
|
||||
/**
|
||||
* @brief CAN handle Structure definition
|
||||
*/
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
typedef struct __CAN_HandleTypeDef
|
||||
#else
|
||||
typedef struct
|
||||
#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
|
||||
{
|
||||
CAN_TypeDef *Instance; /*!< Register base address */
|
||||
|
||||
CAN_InitTypeDef Init; /*!< CAN required parameters */
|
||||
|
||||
__IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */
|
||||
|
||||
__IO uint32_t ErrorCode; /*!< CAN Error code.
|
||||
This parameter can be a value of @ref CAN_Error_Code */
|
||||
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
void (* TxMailbox0CompleteCallback)(struct __CAN_HandleTypeDef *hcan);/*!< CAN Tx Mailbox 0 complete callback */
|
||||
void (* TxMailbox1CompleteCallback)(struct __CAN_HandleTypeDef *hcan);/*!< CAN Tx Mailbox 1 complete callback */
|
||||
void (* TxMailbox2CompleteCallback)(struct __CAN_HandleTypeDef *hcan);/*!< CAN Tx Mailbox 2 complete callback */
|
||||
void (* TxMailbox0AbortCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Tx Mailbox 0 abort callback */
|
||||
void (* TxMailbox1AbortCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Tx Mailbox 1 abort callback */
|
||||
void (* TxMailbox2AbortCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Tx Mailbox 2 abort callback */
|
||||
void (* RxFifo0MsgPendingCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Rx FIFO 0 msg pending callback */
|
||||
void (* RxFifo0FullCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Rx FIFO 0 full callback */
|
||||
void (* RxFifo1MsgPendingCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Rx FIFO 1 msg pending callback */
|
||||
void (* RxFifo1FullCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Rx FIFO 1 full callback */
|
||||
void (* SleepCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Sleep callback */
|
||||
void (* WakeUpFromRxMsgCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Wake Up from Rx msg callback */
|
||||
void (* ErrorCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Error callback */
|
||||
|
||||
void (* MspInitCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Msp Init callback */
|
||||
void (* MspDeInitCallback)(struct __CAN_HandleTypeDef *hcan); /*!< CAN Msp DeInit callback */
|
||||
|
||||
#endif /* (USE_HAL_CAN_REGISTER_CALLBACKS) */
|
||||
} CAN_HandleTypeDef;
|
||||
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
/**
|
||||
* @brief HAL CAN common Callback ID enumeration definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID = 0x00U, /*!< CAN Tx Mailbox 0 complete callback ID */
|
||||
HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID = 0x01U, /*!< CAN Tx Mailbox 1 complete callback ID */
|
||||
HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID = 0x02U, /*!< CAN Tx Mailbox 2 complete callback ID */
|
||||
HAL_CAN_TX_MAILBOX0_ABORT_CB_ID = 0x03U, /*!< CAN Tx Mailbox 0 abort callback ID */
|
||||
HAL_CAN_TX_MAILBOX1_ABORT_CB_ID = 0x04U, /*!< CAN Tx Mailbox 1 abort callback ID */
|
||||
HAL_CAN_TX_MAILBOX2_ABORT_CB_ID = 0x05U, /*!< CAN Tx Mailbox 2 abort callback ID */
|
||||
HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID = 0x06U, /*!< CAN Rx FIFO 0 message pending callback ID */
|
||||
HAL_CAN_RX_FIFO0_FULL_CB_ID = 0x07U, /*!< CAN Rx FIFO 0 full callback ID */
|
||||
HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID = 0x08U, /*!< CAN Rx FIFO 1 message pending callback ID */
|
||||
HAL_CAN_RX_FIFO1_FULL_CB_ID = 0x09U, /*!< CAN Rx FIFO 1 full callback ID */
|
||||
HAL_CAN_SLEEP_CB_ID = 0x0AU, /*!< CAN Sleep callback ID */
|
||||
HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID = 0x0BU, /*!< CAN Wake Up from Rx msg callback ID */
|
||||
HAL_CAN_ERROR_CB_ID = 0x0CU, /*!< CAN Error callback ID */
|
||||
|
||||
HAL_CAN_MSPINIT_CB_ID = 0x0DU, /*!< CAN MspInit callback ID */
|
||||
HAL_CAN_MSPDEINIT_CB_ID = 0x0EU, /*!< CAN MspDeInit callback ID */
|
||||
|
||||
} HAL_CAN_CallbackIDTypeDef;
|
||||
|
||||
/**
|
||||
* @brief HAL CAN Callback pointer definition
|
||||
*/
|
||||
typedef void (*pCAN_CallbackTypeDef)(CAN_HandleTypeDef *hcan); /*!< pointer to a CAN callback function */
|
||||
|
||||
#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup CAN_Exported_Constants CAN Exported Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Error_Code CAN Error Code
|
||||
* @{
|
||||
*/
|
||||
#define HAL_CAN_ERROR_NONE (0x00000000U) /*!< No error */
|
||||
#define HAL_CAN_ERROR_EWG (0x00000001U) /*!< Protocol Error Warning */
|
||||
#define HAL_CAN_ERROR_EPV (0x00000002U) /*!< Error Passive */
|
||||
#define HAL_CAN_ERROR_BOF (0x00000004U) /*!< Bus-off error */
|
||||
#define HAL_CAN_ERROR_STF (0x00000008U) /*!< Stuff error */
|
||||
#define HAL_CAN_ERROR_FOR (0x00000010U) /*!< Form error */
|
||||
#define HAL_CAN_ERROR_ACK (0x00000020U) /*!< Acknowledgment error */
|
||||
#define HAL_CAN_ERROR_BR (0x00000040U) /*!< Bit recessive error */
|
||||
#define HAL_CAN_ERROR_BD (0x00000080U) /*!< Bit dominant error */
|
||||
#define HAL_CAN_ERROR_CRC (0x00000100U) /*!< CRC error */
|
||||
#define HAL_CAN_ERROR_RX_FOV0 (0x00000200U) /*!< Rx FIFO0 overrun error */
|
||||
#define HAL_CAN_ERROR_RX_FOV1 (0x00000400U) /*!< Rx FIFO1 overrun error */
|
||||
#define HAL_CAN_ERROR_TX_ALST0 (0x00000800U) /*!< TxMailbox 0 transmit failure due to arbitration lost */
|
||||
#define HAL_CAN_ERROR_TX_TERR0 (0x00001000U) /*!< TxMailbox 0 transmit failure due to transmit error */
|
||||
#define HAL_CAN_ERROR_TX_ALST1 (0x00002000U) /*!< TxMailbox 1 transmit failure due to arbitration lost */
|
||||
#define HAL_CAN_ERROR_TX_TERR1 (0x00004000U) /*!< TxMailbox 1 transmit failure due to transmit error */
|
||||
#define HAL_CAN_ERROR_TX_ALST2 (0x00008000U) /*!< TxMailbox 2 transmit failure due to arbitration lost */
|
||||
#define HAL_CAN_ERROR_TX_TERR2 (0x00010000U) /*!< TxMailbox 2 transmit failure due to transmit error */
|
||||
#define HAL_CAN_ERROR_TIMEOUT (0x00020000U) /*!< Timeout error */
|
||||
#define HAL_CAN_ERROR_NOT_INITIALIZED (0x00040000U) /*!< Peripheral not initialized */
|
||||
#define HAL_CAN_ERROR_NOT_READY (0x00080000U) /*!< Peripheral not ready */
|
||||
#define HAL_CAN_ERROR_NOT_STARTED (0x00100000U) /*!< Peripheral not started */
|
||||
#define HAL_CAN_ERROR_PARAM (0x00200000U) /*!< Parameter error */
|
||||
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
#define HAL_CAN_ERROR_INVALID_CALLBACK (0x00400000U) /*!< Invalid Callback error */
|
||||
#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */
|
||||
#define HAL_CAN_ERROR_INTERNAL (0x00800000U) /*!< Internal error */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_InitStatus CAN InitStatus
|
||||
* @{
|
||||
*/
|
||||
#define CAN_INITSTATUS_FAILED (0x00000000U) /*!< CAN initialization failed */
|
||||
#define CAN_INITSTATUS_SUCCESS (0x00000001U) /*!< CAN initialization OK */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_operating_mode CAN Operating Mode
|
||||
* @{
|
||||
*/
|
||||
#define CAN_MODE_NORMAL (0x00000000U) /*!< Normal mode */
|
||||
#define CAN_MODE_LOOPBACK ((uint32_t)CAN_BTR_LBKM) /*!< Loopback mode */
|
||||
#define CAN_MODE_SILENT ((uint32_t)CAN_BTR_SILM) /*!< Silent mode */
|
||||
#define CAN_MODE_SILENT_LOOPBACK ((uint32_t)(CAN_BTR_LBKM | CAN_BTR_SILM)) /*!< Loopback combined with
|
||||
silent mode */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup CAN_synchronisation_jump_width CAN Synchronization Jump Width
|
||||
* @{
|
||||
*/
|
||||
#define CAN_SJW_1TQ (0x00000000U) /*!< 1 time quantum */
|
||||
#define CAN_SJW_2TQ ((uint32_t)CAN_BTR_SJW_0) /*!< 2 time quantum */
|
||||
#define CAN_SJW_3TQ ((uint32_t)CAN_BTR_SJW_1) /*!< 3 time quantum */
|
||||
#define CAN_SJW_4TQ ((uint32_t)CAN_BTR_SJW) /*!< 4 time quantum */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_time_quantum_in_bit_segment_1 CAN Time Quantum in Bit Segment 1
|
||||
* @{
|
||||
*/
|
||||
#define CAN_BS1_1TQ (0x00000000U) /*!< 1 time quantum */
|
||||
#define CAN_BS1_2TQ ((uint32_t)CAN_BTR_TS1_0) /*!< 2 time quantum */
|
||||
#define CAN_BS1_3TQ ((uint32_t)CAN_BTR_TS1_1) /*!< 3 time quantum */
|
||||
#define CAN_BS1_4TQ ((uint32_t)(CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 4 time quantum */
|
||||
#define CAN_BS1_5TQ ((uint32_t)CAN_BTR_TS1_2) /*!< 5 time quantum */
|
||||
#define CAN_BS1_6TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 6 time quantum */
|
||||
#define CAN_BS1_7TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 7 time quantum */
|
||||
#define CAN_BS1_8TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 8 time quantum */
|
||||
#define CAN_BS1_9TQ ((uint32_t)CAN_BTR_TS1_3) /*!< 9 time quantum */
|
||||
#define CAN_BS1_10TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_0)) /*!< 10 time quantum */
|
||||
#define CAN_BS1_11TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1)) /*!< 11 time quantum */
|
||||
#define CAN_BS1_12TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 12 time quantum */
|
||||
#define CAN_BS1_13TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2)) /*!< 13 time quantum */
|
||||
#define CAN_BS1_14TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 14 time quantum */
|
||||
#define CAN_BS1_15TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 15 time quantum */
|
||||
#define CAN_BS1_16TQ ((uint32_t)CAN_BTR_TS1) /*!< 16 time quantum */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_time_quantum_in_bit_segment_2 CAN Time Quantum in Bit Segment 2
|
||||
* @{
|
||||
*/
|
||||
#define CAN_BS2_1TQ (0x00000000U) /*!< 1 time quantum */
|
||||
#define CAN_BS2_2TQ ((uint32_t)CAN_BTR_TS2_0) /*!< 2 time quantum */
|
||||
#define CAN_BS2_3TQ ((uint32_t)CAN_BTR_TS2_1) /*!< 3 time quantum */
|
||||
#define CAN_BS2_4TQ ((uint32_t)(CAN_BTR_TS2_1 | CAN_BTR_TS2_0)) /*!< 4 time quantum */
|
||||
#define CAN_BS2_5TQ ((uint32_t)CAN_BTR_TS2_2) /*!< 5 time quantum */
|
||||
#define CAN_BS2_6TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_0)) /*!< 6 time quantum */
|
||||
#define CAN_BS2_7TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_1)) /*!< 7 time quantum */
|
||||
#define CAN_BS2_8TQ ((uint32_t)CAN_BTR_TS2) /*!< 8 time quantum */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_filter_mode CAN Filter Mode
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FILTERMODE_IDMASK (0x00000000U) /*!< Identifier mask mode */
|
||||
#define CAN_FILTERMODE_IDLIST (0x00000001U) /*!< Identifier list mode */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_filter_scale CAN Filter Scale
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FILTERSCALE_16BIT (0x00000000U) /*!< Two 16-bit filters */
|
||||
#define CAN_FILTERSCALE_32BIT (0x00000001U) /*!< One 32-bit filter */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_filter_activation CAN Filter Activation
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FILTER_DISABLE (0x00000000U) /*!< Disable filter */
|
||||
#define CAN_FILTER_ENABLE (0x00000001U) /*!< Enable filter */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_filter_FIFO CAN Filter FIFO
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FILTER_FIFO0 (0x00000000U) /*!< Filter FIFO 0 assignment for filter x */
|
||||
#define CAN_FILTER_FIFO1 (0x00000001U) /*!< Filter FIFO 1 assignment for filter x */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_identifier_type CAN Identifier Type
|
||||
* @{
|
||||
*/
|
||||
#define CAN_ID_STD (0x00000000U) /*!< Standard Id */
|
||||
#define CAN_ID_EXT (0x00000004U) /*!< Extended Id */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_remote_transmission_request CAN Remote Transmission Request
|
||||
* @{
|
||||
*/
|
||||
#define CAN_RTR_DATA (0x00000000U) /*!< Data frame */
|
||||
#define CAN_RTR_REMOTE (0x00000002U) /*!< Remote frame */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_receive_FIFO_number CAN Receive FIFO Number
|
||||
* @{
|
||||
*/
|
||||
#define CAN_RX_FIFO0 (0x00000000U) /*!< CAN receive FIFO 0 */
|
||||
#define CAN_RX_FIFO1 (0x00000001U) /*!< CAN receive FIFO 1 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Tx_Mailboxes CAN Tx Mailboxes
|
||||
* @{
|
||||
*/
|
||||
#define CAN_TX_MAILBOX0 (0x00000001U) /*!< Tx Mailbox 0 */
|
||||
#define CAN_TX_MAILBOX1 (0x00000002U) /*!< Tx Mailbox 1 */
|
||||
#define CAN_TX_MAILBOX2 (0x00000004U) /*!< Tx Mailbox 2 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_flags CAN Flags
|
||||
* @{
|
||||
*/
|
||||
/* Transmit Flags */
|
||||
#define CAN_FLAG_RQCP0 (0x00000500U) /*!< Request complete MailBox 0 flag */
|
||||
#define CAN_FLAG_TXOK0 (0x00000501U) /*!< Transmission OK MailBox 0 flag */
|
||||
#define CAN_FLAG_ALST0 (0x00000502U) /*!< Arbitration Lost MailBox 0 flag */
|
||||
#define CAN_FLAG_TERR0 (0x00000503U) /*!< Transmission error MailBox 0 flag */
|
||||
#define CAN_FLAG_RQCP1 (0x00000508U) /*!< Request complete MailBox1 flag */
|
||||
#define CAN_FLAG_TXOK1 (0x00000509U) /*!< Transmission OK MailBox 1 flag */
|
||||
#define CAN_FLAG_ALST1 (0x0000050AU) /*!< Arbitration Lost MailBox 1 flag */
|
||||
#define CAN_FLAG_TERR1 (0x0000050BU) /*!< Transmission error MailBox 1 flag */
|
||||
#define CAN_FLAG_RQCP2 (0x00000510U) /*!< Request complete MailBox2 flag */
|
||||
#define CAN_FLAG_TXOK2 (0x00000511U) /*!< Transmission OK MailBox 2 flag */
|
||||
#define CAN_FLAG_ALST2 (0x00000512U) /*!< Arbitration Lost MailBox 2 flag */
|
||||
#define CAN_FLAG_TERR2 (0x00000513U) /*!< Transmission error MailBox 2 flag */
|
||||
#define CAN_FLAG_TME0 (0x0000051AU) /*!< Transmit mailbox 0 empty flag */
|
||||
#define CAN_FLAG_TME1 (0x0000051BU) /*!< Transmit mailbox 1 empty flag */
|
||||
#define CAN_FLAG_TME2 (0x0000051CU) /*!< Transmit mailbox 2 empty flag */
|
||||
#define CAN_FLAG_LOW0 (0x0000051DU) /*!< Lowest priority mailbox 0 flag */
|
||||
#define CAN_FLAG_LOW1 (0x0000051EU) /*!< Lowest priority mailbox 1 flag */
|
||||
#define CAN_FLAG_LOW2 (0x0000051FU) /*!< Lowest priority mailbox 2 flag */
|
||||
|
||||
/* Receive Flags */
|
||||
#define CAN_FLAG_FF0 (0x00000203U) /*!< RX FIFO 0 Full flag */
|
||||
#define CAN_FLAG_FOV0 (0x00000204U) /*!< RX FIFO 0 Overrun flag */
|
||||
#define CAN_FLAG_FF1 (0x00000403U) /*!< RX FIFO 1 Full flag */
|
||||
#define CAN_FLAG_FOV1 (0x00000404U) /*!< RX FIFO 1 Overrun flag */
|
||||
|
||||
/* Operating Mode Flags */
|
||||
#define CAN_FLAG_INAK (0x00000100U) /*!< Initialization acknowledge flag */
|
||||
#define CAN_FLAG_SLAK (0x00000101U) /*!< Sleep acknowledge flag */
|
||||
#define CAN_FLAG_ERRI (0x00000102U) /*!< Error flag */
|
||||
#define CAN_FLAG_WKU (0x00000103U) /*!< Wake up interrupt flag */
|
||||
#define CAN_FLAG_SLAKI (0x00000104U) /*!< Sleep acknowledge interrupt flag */
|
||||
|
||||
/* Error Flags */
|
||||
#define CAN_FLAG_EWG (0x00000300U) /*!< Error warning flag */
|
||||
#define CAN_FLAG_EPV (0x00000301U) /*!< Error passive flag */
|
||||
#define CAN_FLAG_BOF (0x00000302U) /*!< Bus-Off flag */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup CAN_Interrupts CAN Interrupts
|
||||
* @{
|
||||
*/
|
||||
/* Transmit Interrupt */
|
||||
#define CAN_IT_TX_MAILBOX_EMPTY ((uint32_t)CAN_IER_TMEIE) /*!< Transmit mailbox empty interrupt */
|
||||
|
||||
/* Receive Interrupts */
|
||||
#define CAN_IT_RX_FIFO0_MSG_PENDING ((uint32_t)CAN_IER_FMPIE0) /*!< FIFO 0 message pending interrupt */
|
||||
#define CAN_IT_RX_FIFO0_FULL ((uint32_t)CAN_IER_FFIE0) /*!< FIFO 0 full interrupt */
|
||||
#define CAN_IT_RX_FIFO0_OVERRUN ((uint32_t)CAN_IER_FOVIE0) /*!< FIFO 0 overrun interrupt */
|
||||
#define CAN_IT_RX_FIFO1_MSG_PENDING ((uint32_t)CAN_IER_FMPIE1) /*!< FIFO 1 message pending interrupt */
|
||||
#define CAN_IT_RX_FIFO1_FULL ((uint32_t)CAN_IER_FFIE1) /*!< FIFO 1 full interrupt */
|
||||
#define CAN_IT_RX_FIFO1_OVERRUN ((uint32_t)CAN_IER_FOVIE1) /*!< FIFO 1 overrun interrupt */
|
||||
|
||||
/* Operating Mode Interrupts */
|
||||
#define CAN_IT_WAKEUP ((uint32_t)CAN_IER_WKUIE) /*!< Wake-up interrupt */
|
||||
#define CAN_IT_SLEEP_ACK ((uint32_t)CAN_IER_SLKIE) /*!< Sleep acknowledge interrupt */
|
||||
|
||||
/* Error Interrupts */
|
||||
#define CAN_IT_ERROR_WARNING ((uint32_t)CAN_IER_EWGIE) /*!< Error warning interrupt */
|
||||
#define CAN_IT_ERROR_PASSIVE ((uint32_t)CAN_IER_EPVIE) /*!< Error passive interrupt */
|
||||
#define CAN_IT_BUSOFF ((uint32_t)CAN_IER_BOFIE) /*!< Bus-off interrupt */
|
||||
#define CAN_IT_LAST_ERROR_CODE ((uint32_t)CAN_IER_LECIE) /*!< Last error code interrupt */
|
||||
#define CAN_IT_ERROR ((uint32_t)CAN_IER_ERRIE) /*!< Error Interrupt */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/** @defgroup CAN_Exported_Macros CAN Exported Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Reset CAN handle state
|
||||
* @param __HANDLE__ CAN handle.
|
||||
* @retval None
|
||||
*/
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
#define __HAL_CAN_RESET_HANDLE_STATE(__HANDLE__) do{ \
|
||||
(__HANDLE__)->State = HAL_CAN_STATE_RESET; \
|
||||
(__HANDLE__)->MspInitCallback = NULL; \
|
||||
(__HANDLE__)->MspDeInitCallback = NULL; \
|
||||
} while(0)
|
||||
#else
|
||||
#define __HAL_CAN_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CAN_STATE_RESET)
|
||||
#endif /*USE_HAL_CAN_REGISTER_CALLBACKS */
|
||||
|
||||
/**
|
||||
* @brief Enable the specified CAN interrupts.
|
||||
* @param __HANDLE__ CAN handle.
|
||||
* @param __INTERRUPT__ CAN Interrupt sources to enable.
|
||||
* This parameter can be any combination of @arg CAN_Interrupts
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_CAN_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) |= (__INTERRUPT__))
|
||||
|
||||
/**
|
||||
* @brief Disable the specified CAN interrupts.
|
||||
* @param __HANDLE__ CAN handle.
|
||||
* @param __INTERRUPT__ CAN Interrupt sources to disable.
|
||||
* This parameter can be any combination of @arg CAN_Interrupts
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_CAN_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) &= ~(__INTERRUPT__))
|
||||
|
||||
/** @brief Check if the specified CAN interrupt source is enabled or disabled.
|
||||
* @param __HANDLE__ specifies the CAN Handle.
|
||||
* @param __INTERRUPT__ specifies the CAN interrupt source to check.
|
||||
* This parameter can be a value of @arg CAN_Interrupts
|
||||
* @retval The state of __IT__ (TRUE or FALSE).
|
||||
*/
|
||||
#define __HAL_CAN_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) & (__INTERRUPT__))
|
||||
|
||||
/** @brief Check whether the specified CAN flag is set or not.
|
||||
* @param __HANDLE__ specifies the CAN Handle.
|
||||
* @param __FLAG__ specifies the flag to check.
|
||||
* This parameter can be one of @arg CAN_flags
|
||||
* @retval The state of __FLAG__ (TRUE or FALSE).
|
||||
*/
|
||||
#define __HAL_CAN_GET_FLAG(__HANDLE__, __FLAG__) \
|
||||
((((__FLAG__) >> 8U) == 5U)? ((((__HANDLE__)->Instance->TSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 2U)? ((((__HANDLE__)->Instance->RF0R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 4U)? ((((__HANDLE__)->Instance->RF1R) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 1U)? ((((__HANDLE__)->Instance->MSR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 3U)? ((((__HANDLE__)->Instance->ESR) & (1U << ((__FLAG__) & CAN_FLAG_MASK))) == (1U << ((__FLAG__) & CAN_FLAG_MASK))): 0U)
|
||||
|
||||
/** @brief Clear the specified CAN pending flag.
|
||||
* @param __HANDLE__ specifies the CAN Handle.
|
||||
* @param __FLAG__ specifies the flag to check.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg CAN_FLAG_RQCP0: Request complete MailBox 0 Flag
|
||||
* @arg CAN_FLAG_TXOK0: Transmission OK MailBox 0 Flag
|
||||
* @arg CAN_FLAG_ALST0: Arbitration Lost MailBox 0 Flag
|
||||
* @arg CAN_FLAG_TERR0: Transmission error MailBox 0 Flag
|
||||
* @arg CAN_FLAG_RQCP1: Request complete MailBox 1 Flag
|
||||
* @arg CAN_FLAG_TXOK1: Transmission OK MailBox 1 Flag
|
||||
* @arg CAN_FLAG_ALST1: Arbitration Lost MailBox 1 Flag
|
||||
* @arg CAN_FLAG_TERR1: Transmission error MailBox 1 Flag
|
||||
* @arg CAN_FLAG_RQCP2: Request complete MailBox 2 Flag
|
||||
* @arg CAN_FLAG_TXOK2: Transmission OK MailBox 2 Flag
|
||||
* @arg CAN_FLAG_ALST2: Arbitration Lost MailBox 2 Flag
|
||||
* @arg CAN_FLAG_TERR2: Transmission error MailBox 2 Flag
|
||||
* @arg CAN_FLAG_FF0: RX FIFO 0 Full Flag
|
||||
* @arg CAN_FLAG_FOV0: RX FIFO 0 Overrun Flag
|
||||
* @arg CAN_FLAG_FF1: RX FIFO 1 Full Flag
|
||||
* @arg CAN_FLAG_FOV1: RX FIFO 1 Overrun Flag
|
||||
* @arg CAN_FLAG_WKUI: Wake up Interrupt Flag
|
||||
* @arg CAN_FLAG_SLAKI: Sleep acknowledge Interrupt Flag
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_CAN_CLEAR_FLAG(__HANDLE__, __FLAG__) \
|
||||
((((__FLAG__) >> 8U) == 5U)? (((__HANDLE__)->Instance->TSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 2U)? (((__HANDLE__)->Instance->RF0R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 4U)? (((__HANDLE__)->Instance->RF1R) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): \
|
||||
(((__FLAG__) >> 8U) == 1U)? (((__HANDLE__)->Instance->MSR) = (1U << ((__FLAG__) & CAN_FLAG_MASK))): 0U)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup CAN_Exported_Functions CAN Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Initialization and de-initialization functions *****************************/
|
||||
HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan);
|
||||
|
||||
#if USE_HAL_CAN_REGISTER_CALLBACKS == 1
|
||||
/* Callbacks Register/UnRegister functions ***********************************/
|
||||
HAL_StatusTypeDef HAL_CAN_RegisterCallback(CAN_HandleTypeDef *hcan, HAL_CAN_CallbackIDTypeDef CallbackID,
|
||||
void (* pCallback)(CAN_HandleTypeDef *_hcan));
|
||||
HAL_StatusTypeDef HAL_CAN_UnRegisterCallback(CAN_HandleTypeDef *hcan, HAL_CAN_CallbackIDTypeDef CallbackID);
|
||||
|
||||
#endif /* (USE_HAL_CAN_REGISTER_CALLBACKS) */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group2 Configuration functions
|
||||
* @brief Configuration functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Configuration functions ****************************************************/
|
||||
HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, const CAN_FilterTypeDef *sFilterConfig);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group3 Control functions
|
||||
* @brief Control functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Control functions **********************************************************/
|
||||
HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan);
|
||||
uint32_t HAL_CAN_IsSleepActive(const CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, const CAN_TxHeaderTypeDef *pHeader,
|
||||
const uint8_t aData[], uint32_t *pTxMailbox);
|
||||
HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes);
|
||||
uint32_t HAL_CAN_GetTxMailboxesFreeLevel(const CAN_HandleTypeDef *hcan);
|
||||
uint32_t HAL_CAN_IsTxMessagePending(const CAN_HandleTypeDef *hcan, uint32_t TxMailboxes);
|
||||
uint32_t HAL_CAN_GetTxTimestamp(const CAN_HandleTypeDef *hcan, uint32_t TxMailbox);
|
||||
HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo,
|
||||
CAN_RxHeaderTypeDef *pHeader, uint8_t aData[]);
|
||||
uint32_t HAL_CAN_GetRxFifoFillLevel(const CAN_HandleTypeDef *hcan, uint32_t RxFifo);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group4 Interrupts management
|
||||
* @brief Interrupts management
|
||||
* @{
|
||||
*/
|
||||
/* Interrupts management ******************************************************/
|
||||
HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs);
|
||||
HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs);
|
||||
void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group5 Callback functions
|
||||
* @brief Callback functions
|
||||
* @{
|
||||
*/
|
||||
/* Callbacks functions ********************************************************/
|
||||
|
||||
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan);
|
||||
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Exported_Functions_Group6 Peripheral State and Error functions
|
||||
* @brief CAN Peripheral State functions
|
||||
* @{
|
||||
*/
|
||||
/* Peripheral State and Error functions ***************************************/
|
||||
HAL_CAN_StateTypeDef HAL_CAN_GetState(const CAN_HandleTypeDef *hcan);
|
||||
uint32_t HAL_CAN_GetError(const CAN_HandleTypeDef *hcan);
|
||||
HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/** @defgroup CAN_Private_Types CAN Private Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/** @defgroup CAN_Private_Variables CAN Private Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @defgroup CAN_Private_Constants CAN Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define CAN_FLAG_MASK (0x000000FFU)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private Macros -----------------------------------------------------------*/
|
||||
/** @defgroup CAN_Private_Macros CAN Private Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IS_CAN_MODE(MODE) (((MODE) == CAN_MODE_NORMAL) || \
|
||||
((MODE) == CAN_MODE_LOOPBACK)|| \
|
||||
((MODE) == CAN_MODE_SILENT) || \
|
||||
((MODE) == CAN_MODE_SILENT_LOOPBACK))
|
||||
#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1TQ) || ((SJW) == CAN_SJW_2TQ) || \
|
||||
((SJW) == CAN_SJW_3TQ) || ((SJW) == CAN_SJW_4TQ))
|
||||
#define IS_CAN_BS1(BS1) (((BS1) == CAN_BS1_1TQ) || ((BS1) == CAN_BS1_2TQ) || \
|
||||
((BS1) == CAN_BS1_3TQ) || ((BS1) == CAN_BS1_4TQ) || \
|
||||
((BS1) == CAN_BS1_5TQ) || ((BS1) == CAN_BS1_6TQ) || \
|
||||
((BS1) == CAN_BS1_7TQ) || ((BS1) == CAN_BS1_8TQ) || \
|
||||
((BS1) == CAN_BS1_9TQ) || ((BS1) == CAN_BS1_10TQ)|| \
|
||||
((BS1) == CAN_BS1_11TQ)|| ((BS1) == CAN_BS1_12TQ)|| \
|
||||
((BS1) == CAN_BS1_13TQ)|| ((BS1) == CAN_BS1_14TQ)|| \
|
||||
((BS1) == CAN_BS1_15TQ)|| ((BS1) == CAN_BS1_16TQ))
|
||||
#define IS_CAN_BS2(BS2) (((BS2) == CAN_BS2_1TQ) || ((BS2) == CAN_BS2_2TQ) || \
|
||||
((BS2) == CAN_BS2_3TQ) || ((BS2) == CAN_BS2_4TQ) || \
|
||||
((BS2) == CAN_BS2_5TQ) || ((BS2) == CAN_BS2_6TQ) || \
|
||||
((BS2) == CAN_BS2_7TQ) || ((BS2) == CAN_BS2_8TQ))
|
||||
#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1U) && ((PRESCALER) <= 1024U))
|
||||
#define IS_CAN_FILTER_ID_HALFWORD(HALFWORD) ((HALFWORD) <= 0xFFFFU)
|
||||
#if defined(CAN2)
|
||||
#define IS_CAN_FILTER_BANK_DUAL(BANK) ((BANK) <= 27U)
|
||||
#endif
|
||||
#define IS_CAN_FILTER_BANK_SINGLE(BANK) ((BANK) <= 13U)
|
||||
#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FILTERMODE_IDMASK) || \
|
||||
((MODE) == CAN_FILTERMODE_IDLIST))
|
||||
#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FILTERSCALE_16BIT) || \
|
||||
((SCALE) == CAN_FILTERSCALE_32BIT))
|
||||
#define IS_CAN_FILTER_ACTIVATION(ACTIVATION) (((ACTIVATION) == CAN_FILTER_DISABLE) || \
|
||||
((ACTIVATION) == CAN_FILTER_ENABLE))
|
||||
#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FILTER_FIFO0) || \
|
||||
((FIFO) == CAN_FILTER_FIFO1))
|
||||
#define IS_CAN_TX_MAILBOX(TRANSMITMAILBOX) (((TRANSMITMAILBOX) == CAN_TX_MAILBOX0 ) || \
|
||||
((TRANSMITMAILBOX) == CAN_TX_MAILBOX1 ) || \
|
||||
((TRANSMITMAILBOX) == CAN_TX_MAILBOX2 ))
|
||||
#define IS_CAN_TX_MAILBOX_LIST(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= (CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | \
|
||||
CAN_TX_MAILBOX2))
|
||||
#define IS_CAN_STDID(STDID) ((STDID) <= 0x7FFU)
|
||||
#define IS_CAN_EXTID(EXTID) ((EXTID) <= 0x1FFFFFFFU)
|
||||
#define IS_CAN_DLC(DLC) ((DLC) <= 8U)
|
||||
#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_ID_STD) || \
|
||||
((IDTYPE) == CAN_ID_EXT))
|
||||
#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_DATA) || ((RTR) == CAN_RTR_REMOTE))
|
||||
#define IS_CAN_RX_FIFO(FIFO) (((FIFO) == CAN_RX_FIFO0) || ((FIFO) == CAN_RX_FIFO1))
|
||||
#define IS_CAN_IT(IT) ((IT) <= (CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_RX_FIFO0_MSG_PENDING | \
|
||||
CAN_IT_RX_FIFO0_FULL | CAN_IT_RX_FIFO0_OVERRUN | \
|
||||
CAN_IT_RX_FIFO1_MSG_PENDING | CAN_IT_RX_FIFO1_FULL | \
|
||||
CAN_IT_RX_FIFO1_OVERRUN | CAN_IT_WAKEUP | \
|
||||
CAN_IT_SLEEP_ACK | CAN_IT_ERROR_WARNING | \
|
||||
CAN_IT_ERROR_PASSIVE | CAN_IT_BUSOFF | \
|
||||
CAN_IT_LAST_ERROR_CODE | CAN_IT_ERROR))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* End of private macros -----------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#endif /* CAN1 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32F1xx_HAL_CAN_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_CEC_MODULE_ENABLED */
|
||||
/*#define HAL_CORTEX_MODULE_ENABLED */
|
||||
/*#define HAL_CRC_MODULE_ENABLED */
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
SRC_FILES := stm32f1xx_hal.c stm32f1xx_hal_uart.c stm32f1xx_hal_usart.c stm32f1xx_hal_cortex.c stm32f1xx_hal_rcc.c stm32f1xx_hal_rcc_ex.c stm32f1xx_hal_gpio.c stm32f1xx_hal_msp.c stm32f1xx_hal_flash.c stm32f1xx_hal_flash_ex.c stm32f1xx_hal_dma.c
|
||||
SRC_FILES := stm32f1xx_hal.c \
|
||||
stm32f1xx_hal_uart.c \
|
||||
stm32f1xx_hal_usart.c \
|
||||
stm32f1xx_hal_cortex.c \
|
||||
stm32f1xx_hal_rcc.c \
|
||||
stm32f1xx_hal_rcc_ex.c \
|
||||
stm32f1xx_hal_gpio.c \
|
||||
stm32f1xx_hal_msp.c \
|
||||
stm32f1xx_hal_flash.c \
|
||||
stm32f1xx_hal_flash_ex.c \
|
||||
stm32f1xx_hal_dma.c \
|
||||
stm32f1xx_hal_can.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -41,6 +41,7 @@
|
|||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "stm32f1xx_hal_can.h"
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
@ -505,6 +506,80 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief CAN MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hcan: CAN handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(hcan->Instance==CAN1)
|
||||
{
|
||||
/* USER CODE BEGIN CAN1_MspInit 0 */
|
||||
|
||||
/* USER CODE END CAN1_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_CAN1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**CAN GPIO Configuration
|
||||
PA11 ------> CAN_RX
|
||||
PA12 ------> CAN_TX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_12;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* CAN1 interrupt Init */
|
||||
HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||
/* USER CODE BEGIN CAN1_MspInit 1 */
|
||||
|
||||
/* USER CODE END CAN1_MspInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CAN MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hcan: CAN handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
|
||||
{
|
||||
if(hcan->Instance==CAN1)
|
||||
{
|
||||
/* USER CODE BEGIN CAN1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END CAN1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_CAN1_CLK_DISABLE();
|
||||
|
||||
/**CAN GPIO Configuration
|
||||
PA11 ------> CAN_RX
|
||||
PA12 ------> CAN_TX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
|
||||
|
||||
/* CAN1 interrupt DeInit */
|
||||
HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||
/* USER CODE BEGIN CAN1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END CAN1_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 定义目标目录
|
||||
target_dir="/mnt/hgfs/share"
|
||||
|
||||
# 检查目标目录是否存在
|
||||
if [ ! -d "$target_dir" ]; then
|
||||
echo "错误: 目标目录 $target_dir 不存在,脚本将退出。"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 执行 make clean 操作
|
||||
# echo "执行 make BOARD=stm32f103-nano clean..."
|
||||
# make BOARD=stm32f103-nano clean
|
||||
# if [ $? -ne 0 ]; then
|
||||
# echo "错误: make BOARD=stm32f103-nano clean 失败,脚本将退出。"
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# 执行 make 操作
|
||||
echo "执行 make BOARD=stm32f103-nano ..."
|
||||
make BOARD=stm32f103-nano
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "错误: make BOARD=stm32f103-nano 失败,脚本将退出。"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
arm-none-eabi-objdump -d ./build/XiZi-stm32f103-nano.elf > ./build/obj.S
|
||||
|
||||
|
||||
# 定义源文件路径和名称
|
||||
source_files=(
|
||||
"./build/obj.S"
|
||||
"./build/XiZi-stm32f103-nano.bin"
|
||||
"./build/XiZi-stm32f103-nano.elf"
|
||||
"./build/XiZi-stm32f103-nano.hex"
|
||||
"./build/XiZi-stm32f103-nano.map"
|
||||
)
|
||||
|
||||
|
||||
|
||||
# 复制文件,如果有同名文件则覆盖
|
||||
for file in "${source_files[@]}"; do
|
||||
if [ -f "$file" ]; then
|
||||
cp -f "$file" "$target_dir"
|
||||
echo "文件 $file 已复制到 $target_dir(如果已存在则被覆盖)"
|
||||
else
|
||||
echo "警告: 文件 $file 不存在,跳过复制操作。"
|
||||
fi
|
||||
done
|
|
@ -18,7 +18,9 @@ static void GetBusName(const char *path, char *bus_name)
|
|||
|
||||
static void GetDrvName(char *bus_name, char *drv_name)
|
||||
{
|
||||
snprintf(drv_name, strlen(bus_name) + 5, "%s_drv", bus_name);
|
||||
//snprintf(drv_name, strlen(bus_name) + 5, "%s_drv", bus_name);
|
||||
strcpy(drv_name, bus_name);
|
||||
strcat(drv_name, "_drv");
|
||||
}
|
||||
|
||||
static int DevicefileOpen(struct FileDescriptor *fdp, const char *path)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
/* import board special configuration */
|
||||
#include <xsconfig.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -123,9 +124,10 @@ typedef x_base x_OffPos;
|
|||
#endif
|
||||
|
||||
#define WAITING_FOREVER -1
|
||||
|
||||
// #define KPrintf printf
|
||||
void KPrintf(const char *fmt, ...);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -150,6 +150,8 @@ static int _CanTestRecv(const char *bus_name, const char *driver_name, const c
|
|||
for(i = 0; i<len;i++)
|
||||
KPrintf("0x%02x ", rx_buf[i]);
|
||||
KPrintf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -252,7 +252,7 @@ extern int InitUserspace(void);
|
|||
#endif
|
||||
|
||||
StartupOsAssign();
|
||||
ymodem_fun();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,14 +49,6 @@ static void ZombieKTaskEntry(void *parameter)
|
|||
lock = CriticalAreaLock();
|
||||
if (JudgeZombieKTaskIsNotEmpty()) {
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(KTaskZombie.node_next, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
if(0 == strcmp("main", task->task_base_info.name))
|
||||
{
|
||||
// KPrintf("Zombie KTask Is main\n");
|
||||
SuspendKTask(zombie_recycle);
|
||||
CriticalAreaUnLock(lock);
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
else
|
||||
{
|
||||
DoubleLinkListRmNode(&(task->task_dync_sched_member.sched_link));
|
||||
CriticalAreaUnLock(lock);
|
||||
|
|
|
@ -373,6 +373,7 @@ KERNELPATHS += \
|
|||
-I$(KERNEL_ROOT)/arch/arm/cortex-m3 \
|
||||
-I$(BSP_ROOT)/third_party_driver/include \
|
||||
-I$(BSP_ROOT)/third_party_driver/libraries/STM32F1xx_HAL/inc \
|
||||
-I$(BSP_ROOT)/third_party_driver/libraries/STM32F1xx_HAL/inc/Legacy \
|
||||
-I$(BSP_ROOT)/third_party_driver/libraries/CMSIS \
|
||||
-I$(KERNEL_ROOT)/include \
|
||||
-I$(BSP_ROOT)/include #
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
menu "Tool feature"
|
||||
|
||||
source "$KERNEL_DIR/tool/bootloader/Kconfig"
|
||||
source "$KERNEL_DIR/tool/libcanard/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -8,4 +8,9 @@ ifeq ($(CONFIG_TOOL_USING_OTA),y)
|
|||
SRC_DIR += bootloader
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_TOOL_USING_UVCAN),y)
|
||||
SRC_DIR += libcanard
|
||||
endif
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
menu "UVCAN"
|
||||
|
||||
menuconfig TOOL_USING_UVCAN
|
||||
bool "Enable UVCAN function"
|
||||
default y
|
||||
|
||||
endmenu
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES :=
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,337 @@
|
|||
/// Source: https://github.com/pavel-kirienko/cavl
|
||||
///
|
||||
/// Cavl is a single-header C library providing an implementation of AVL tree suitable for deeply embedded systems.
|
||||
/// To integrate it into your project, simply copy this file into your source tree. Read the API docs below.
|
||||
///
|
||||
/// See also O1Heap <https://github.com/pavel-kirienko/o1heap> -- a deterministic memory manager for hard-real-time
|
||||
/// high-integrity embedded systems.
|
||||
///
|
||||
/// Copyright (c) 2021 Pavel Kirienko <pavel@opencyphal.org>
|
||||
///
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
/// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
/// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
/// and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
||||
/// the Software.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
/// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
/// OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "canard.h"
|
||||
|
||||
/// Modified for use with Libcanard: use the same assertion check macro if provided.
|
||||
#ifdef CANARD_ASSERT
|
||||
# define CAVL_ASSERT CANARD_ASSERT
|
||||
#else
|
||||
// Intentional violation of MISRA: inclusion not at the top of the file to eliminate unnecessary dependency on assert.h.
|
||||
# include <assert.h> // NOSONAR
|
||||
# define CAVL_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
// This is, strictly speaking, useless because we do not define any functions with external linkage here,
|
||||
// but it tells static analyzers that what follows should be interpreted as C code rather than C++.
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ---------------------------------------- PUBLIC API SECTION ----------------------------------------
|
||||
|
||||
/// Modified for use with Libcanard: expose the Cavl structure via public API as CanardTreeNode.
|
||||
typedef CanardTreeNode Cavl;
|
||||
|
||||
/// Returns POSITIVE if the search target is GREATER than the provided node, negative if smaller, zero on match (found).
|
||||
/// Values other than {-1, 0, +1} are not recommended to avoid overflow during the narrowing conversion of the result.
|
||||
typedef int8_t (*CavlPredicate)(void* user_reference, const Cavl* node);
|
||||
|
||||
/// If provided, the factory will be invoked when the sought node does not exist in the tree.
|
||||
/// It is expected to return a new node that will be inserted immediately (without the need to traverse the tree again).
|
||||
/// If the factory returns NULL or is not provided, the tree is not modified.
|
||||
typedef Cavl* (*CavlFactory)(void* user_reference);
|
||||
|
||||
/// Look for a node in the tree using the specified search predicate. The worst-case complexity is O(log n).
|
||||
/// - If the node is found, return it.
|
||||
/// - If the node is not found and the factory is NULL, return NULL.
|
||||
/// - Otherwise, construct a new node using the factory; if the result is not NULL, insert it; return the result.
|
||||
/// The user_reference is passed into the predicate & factory unmodified.
|
||||
/// The root node may be replaced in the process.
|
||||
/// If predicate is NULL, returns NULL.
|
||||
static inline Cavl* cavlSearch(Cavl** const root,
|
||||
void* const user_reference,
|
||||
const CavlPredicate predicate,
|
||||
const CavlFactory factory);
|
||||
|
||||
/// Remove the specified node from its tree. The root node may be replaced in the process.
|
||||
/// The worst-case complexity is O(log n).
|
||||
/// The function has no effect if either of the pointers are NULL.
|
||||
/// If the node is not in the tree, the behavior is undefined; it may create cycles in the tree which is deadly.
|
||||
/// It is safe to pass the result of cavlSearch() directly as the second argument:
|
||||
/// cavlRemove(&root, cavlSearch(&root, user_reference, search_predicate, NULL));
|
||||
/// It is recommended to invalidate the pointers stored in the node after its removal.
|
||||
static inline void cavlRemove(Cavl** const root, const Cavl* const node);
|
||||
|
||||
/// Return the min-/max-valued node stored in the tree, depending on the flag. This is an extremely fast query.
|
||||
/// Returns NULL iff the argument is NULL (i.e., the tree is empty). The worst-case complexity is O(log n).
|
||||
static inline Cavl* cavlFindExtremum(Cavl* const root, const bool maximum)
|
||||
{
|
||||
Cavl* result = NULL;
|
||||
Cavl* c = root;
|
||||
while (c != NULL)
|
||||
{
|
||||
result = c;
|
||||
c = c->lr[maximum];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ---------------------------------------- END OF PUBLIC API SECTION ----------------------------------------
|
||||
// ---------------------------------------- POLICE LINE DO NOT CROSS ----------------------------------------
|
||||
|
||||
/// INTERNAL USE ONLY. Makes the '!r' child of node 'x' its parent; i.e., rotates 'x' toward 'r'.
|
||||
static inline void cavlPrivateRotate(Cavl* const x, const bool r)
|
||||
{
|
||||
CAVL_ASSERT((x != NULL) && (x->lr[!r] != NULL) && ((x->bf >= -1) && (x->bf <= +1)));
|
||||
Cavl* const z = x->lr[!r];
|
||||
if (x->up != NULL)
|
||||
{
|
||||
x->up->lr[x->up->lr[1] == x] = z;
|
||||
}
|
||||
z->up = x->up;
|
||||
x->up = z;
|
||||
x->lr[!r] = z->lr[r];
|
||||
if (x->lr[!r] != NULL)
|
||||
{
|
||||
x->lr[!r]->up = x;
|
||||
}
|
||||
z->lr[r] = x;
|
||||
}
|
||||
|
||||
/// INTERNAL USE ONLY.
|
||||
/// Accepts a node and how its balance factor needs to be changed -- either +1 or -1.
|
||||
/// Returns the new node to replace the old one if tree rotation took place, same node otherwise.
|
||||
static inline Cavl* cavlPrivateAdjustBalance(Cavl* const x, const bool increment)
|
||||
{
|
||||
CAVL_ASSERT((x != NULL) && ((x->bf >= -1) && (x->bf <= +1)));
|
||||
Cavl* out = x;
|
||||
const int8_t new_bf = (int8_t) (x->bf + (increment ? +1 : -1));
|
||||
if ((new_bf < -1) || (new_bf > 1))
|
||||
{
|
||||
const bool r = new_bf < 0; // bf<0 if left-heavy --> right rotation is needed.
|
||||
const int8_t sign = r ? +1 : -1; // Positive if we are rotating right.
|
||||
Cavl* const z = x->lr[!r];
|
||||
CAVL_ASSERT(z != NULL); // Heavy side cannot be empty.
|
||||
if ((z->bf * sign) <= 0) // Parent and child are heavy on the same side or the child is balanced.
|
||||
{
|
||||
out = z;
|
||||
cavlPrivateRotate(x, r);
|
||||
if (0 == z->bf)
|
||||
{
|
||||
x->bf = (int8_t) (-sign);
|
||||
z->bf = (int8_t) (+sign);
|
||||
}
|
||||
else
|
||||
{
|
||||
x->bf = 0;
|
||||
z->bf = 0;
|
||||
}
|
||||
}
|
||||
else // Otherwise, the child needs to be rotated in the opposite direction first.
|
||||
{
|
||||
Cavl* const y = z->lr[r];
|
||||
CAVL_ASSERT(y != NULL); // Heavy side cannot be empty.
|
||||
out = y;
|
||||
cavlPrivateRotate(z, !r);
|
||||
cavlPrivateRotate(x, r);
|
||||
if ((y->bf * sign) < 0)
|
||||
{
|
||||
x->bf = (int8_t) (+sign);
|
||||
y->bf = 0;
|
||||
z->bf = 0;
|
||||
}
|
||||
else if ((y->bf * sign) > 0)
|
||||
{
|
||||
x->bf = 0;
|
||||
y->bf = 0;
|
||||
z->bf = (int8_t) (-sign);
|
||||
}
|
||||
else
|
||||
{
|
||||
x->bf = 0;
|
||||
z->bf = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x->bf = new_bf; // Balancing not needed, just update the balance factor and call it a day.
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/// INTERNAL USE ONLY.
|
||||
/// Takes the culprit node (the one that is added); returns NULL or the root of the tree (possibly new one).
|
||||
/// When adding a new node, set its balance factor to zero and call this function to propagate the changes upward.
|
||||
static inline Cavl* cavlPrivateRetraceOnGrowth(Cavl* const added)
|
||||
{
|
||||
CAVL_ASSERT((added != NULL) && (0 == added->bf));
|
||||
Cavl* c = added; // Child
|
||||
Cavl* p = added->up; // Parent
|
||||
while (p != NULL)
|
||||
{
|
||||
const bool r = p->lr[1] == c; // c is the right child of parent
|
||||
CAVL_ASSERT(p->lr[r] == c);
|
||||
c = cavlPrivateAdjustBalance(p, r);
|
||||
p = c->up;
|
||||
if (0 == c->bf)
|
||||
{ // The height change of the subtree made this parent perfectly balanced (as all things should be),
|
||||
break; // hence, the height of the outer subtree is unchanged, so upper balance factors are unchanged.
|
||||
}
|
||||
}
|
||||
CAVL_ASSERT(c != NULL);
|
||||
return (NULL == p) ? c : NULL; // New root or nothing.
|
||||
}
|
||||
|
||||
static inline Cavl* cavlSearch(Cavl** const root,
|
||||
void* const user_reference,
|
||||
const CavlPredicate predicate,
|
||||
const CavlFactory factory)
|
||||
{
|
||||
Cavl* out = NULL;
|
||||
if ((root != NULL) && (predicate != NULL))
|
||||
{
|
||||
Cavl* up = *root;
|
||||
Cavl** n = root;
|
||||
while (*n != NULL)
|
||||
{
|
||||
const int8_t cmp = predicate(user_reference, *n);
|
||||
if (0 == cmp)
|
||||
{
|
||||
out = *n;
|
||||
break;
|
||||
}
|
||||
up = *n;
|
||||
n = &(*n)->lr[cmp > 0];
|
||||
CAVL_ASSERT((NULL == *n) || ((*n)->up == up));
|
||||
}
|
||||
if (NULL == out)
|
||||
{
|
||||
out = (NULL == factory) ? NULL : factory(user_reference);
|
||||
if (out != NULL)
|
||||
{
|
||||
*n = out; // Overwrite the pointer to the new node in the parent node.
|
||||
out->lr[0] = NULL;
|
||||
out->lr[1] = NULL;
|
||||
out->up = up;
|
||||
out->bf = 0;
|
||||
Cavl* const rt = cavlPrivateRetraceOnGrowth(out);
|
||||
if (rt != NULL)
|
||||
{
|
||||
*root = rt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline void cavlRemove(Cavl** const root, const Cavl* const node)
|
||||
{
|
||||
if ((root != NULL) && (node != NULL))
|
||||
{
|
||||
CAVL_ASSERT(*root != NULL); // Otherwise, the node would have to be NULL.
|
||||
CAVL_ASSERT((node->up != NULL) || (node == *root));
|
||||
Cavl* p = NULL; // The lowest parent node that suffered a shortening of its subtree.
|
||||
bool r = false; // Which side of the above was shortened.
|
||||
// The first step is to update the topology and remember the node where to start the retracing from later.
|
||||
// Balancing is not performed yet so we may end up with an unbalanced tree.
|
||||
if ((node->lr[0] != NULL) && (node->lr[1] != NULL))
|
||||
{
|
||||
Cavl* const re = cavlFindExtremum(node->lr[1], false);
|
||||
CAVL_ASSERT((re != NULL) && (NULL == re->lr[0]) && (re->up != NULL));
|
||||
re->bf = node->bf;
|
||||
re->lr[0] = node->lr[0];
|
||||
re->lr[0]->up = re;
|
||||
if (re->up != node)
|
||||
{
|
||||
p = re->up; // Retracing starts with the ex-parent of our replacement node.
|
||||
CAVL_ASSERT(p->lr[0] == re);
|
||||
p->lr[0] = re->lr[1]; // Reducing the height of the left subtree here.
|
||||
if (p->lr[0] != NULL)
|
||||
{
|
||||
p->lr[0]->up = p;
|
||||
}
|
||||
re->lr[1] = node->lr[1];
|
||||
re->lr[1]->up = re;
|
||||
r = false;
|
||||
}
|
||||
else // In this case, we are reducing the height of the right subtree, so r=1.
|
||||
{
|
||||
p = re; // Retracing starts with the replacement node itself as we are deleting its parent.
|
||||
r = true; // The right child of the replacement node remains the same so we don't bother relinking it.
|
||||
}
|
||||
re->up = node->up;
|
||||
if (re->up != NULL)
|
||||
{
|
||||
re->up->lr[re->up->lr[1] == node] = re; // Replace link in the parent of node.
|
||||
}
|
||||
else
|
||||
{
|
||||
*root = re;
|
||||
}
|
||||
}
|
||||
else // Either or both of the children are NULL.
|
||||
{
|
||||
p = node->up;
|
||||
const bool rr = node->lr[1] != NULL;
|
||||
if (node->lr[rr] != NULL)
|
||||
{
|
||||
node->lr[rr]->up = p;
|
||||
}
|
||||
if (p != NULL)
|
||||
{
|
||||
r = p->lr[1] == node;
|
||||
p->lr[r] = node->lr[rr];
|
||||
if (p->lr[r] != NULL)
|
||||
{
|
||||
p->lr[r]->up = p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*root = node->lr[rr];
|
||||
}
|
||||
}
|
||||
// Now that the topology is updated, perform the retracing to restore balance. We climb up adjusting the
|
||||
// balance factors until we reach the root or a parent whose balance factor becomes plus/minus one, which
|
||||
// means that that parent was able to absorb the balance delta; in other words, the height of the outer
|
||||
// subtree is unchanged, so upper balance factors shall be kept unchanged.
|
||||
if (p != NULL)
|
||||
{
|
||||
Cavl* c = NULL;
|
||||
for (;;)
|
||||
{
|
||||
c = cavlPrivateAdjustBalance(p, !r);
|
||||
p = c->up;
|
||||
if ((c->bf != 0) || (NULL == p)) // Reached the root or the height difference is absorbed by c.
|
||||
{
|
||||
break;
|
||||
}
|
||||
r = p->lr[1] == c;
|
||||
}
|
||||
if (NULL == p)
|
||||
{
|
||||
CAVL_ASSERT(c != NULL);
|
||||
*root = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,714 @@
|
|||
/// ____ ______ __ __
|
||||
/// / __ `____ ___ ____ / ____/_ ______ / /_ ____ / /
|
||||
/// / / / / __ `/ _ `/ __ `/ / / / / / __ `/ __ `/ __ `/ /
|
||||
/// / /_/ / /_/ / __/ / / / /___/ /_/ / /_/ / / / / /_/ / /
|
||||
/// `____/ .___/`___/_/ /_/`____/`__, / .___/_/ /_/`__,_/_/
|
||||
/// /_/ /____/_/
|
||||
///
|
||||
/// Libcanard is a compact implementation of the Cyphal/CAN protocol for high-integrity real-time embedded systems.
|
||||
/// It is designed for use in robust deterministic embedded systems equipped with at least 32K ROM and 8K RAM.
|
||||
/// The codebase follows the MISRA C rules, has 100% test coverage, and is validated by at least two static analyzers.
|
||||
/// The library is designed to be compatible with any target platform and instruction set architecture, from 8 to 64
|
||||
/// bit, little- and big-endian, RTOS-based or baremetal, etc., as long as there is a standards-compliant compiler.
|
||||
///
|
||||
/// INTEGRATION
|
||||
///
|
||||
/// The library is intended to be integrated into the end application by simply copying its source files into the
|
||||
/// source tree of the project; it does not require any special compilation options and should work out of the box.
|
||||
/// There are build-time configuration parameters defined near the top of canard.c, but they are safe to ignore.
|
||||
///
|
||||
/// As explained in this documentation, the library requires a deterministic constant-time bounded-fragmentation dynamic
|
||||
/// memory allocator. If your target platform does not provide a deterministic memory manager (most platforms don't),
|
||||
/// it is recommended to use O1Heap (MIT licensed): https://github.com/pavel-kirienko/o1heap.
|
||||
///
|
||||
/// There are no specific requirements to the underlying I/O layer. Some low-level drivers maintained by the
|
||||
/// OpenCyphal team may be found at https://github.com/OpenCyphal-Garage/platform_specific_components.
|
||||
///
|
||||
/// If your application requires a MISRA C compliance report, please get in touch with the maintainers via the forum
|
||||
/// at https://forum.opencyphal.org.
|
||||
///
|
||||
/// ARCHITECTURE
|
||||
///
|
||||
/// Cyphal, as a protocol stack, is composed of two layers: TRANSPORT and PRESENTATION. The transport layer is portable
|
||||
/// across different transport protocols, one of which is CAN (FD), formally referred to as Cyphal/CAN. This library
|
||||
/// is focused on Cyphal/CAN only and it will not support other transports. The presentation layer is implemented
|
||||
/// through the DSDL language and the associated data type regulation policies; these parts are out of the scope of
|
||||
/// this library as it is focused purely on the transport.
|
||||
///
|
||||
/// This library consists of two components: the transmission (TX) pipeline and the reception (RX) pipeline.
|
||||
/// The pipelines are completely independent from each other except that they both rely on the same dynamic memory
|
||||
/// manager. The TX pipeline uses the dynamic memory to store outgoing CAN frames in the prioritized transmission
|
||||
/// queue. The RX pipeline uses the dynamic memory to store contiguous payload buffers for received transfers and
|
||||
/// for keeping the transfer reassembly state machine data. The exact memory consumption model is defined for both
|
||||
/// pipelines, so it is possible to statically determine the minimum size of the dynamic memory pool required to
|
||||
/// guarantee that a given application will never encounter an out-of-memory error at runtime.
|
||||
///
|
||||
/// Much like with dynamic memory, the time complexity of every API function is well-characterized, allowing the
|
||||
/// application to guarantee predictable real-time performance.
|
||||
///
|
||||
/// The TX pipeline is managed with the help of four API functions. The first one -- canardTxInit() -- is used for
|
||||
/// constructing a new TX queue, of which there should be as many as there are redundant CAN interfaces;
|
||||
/// each queue is managed independently. When the application needs to emit a transfer, it invokes canardTxPush()
|
||||
/// on each queue separately. The function splits the transfer into CAN frames and stores them into the queue.
|
||||
/// The application then picks the produced CAN frames from the queue one-by-one by calling canardTxPeek() followed
|
||||
/// by canardTxPop() -- the former allows the application to look at the next frame scheduled for transmission,
|
||||
/// and the latter tells the library that the frame shall be removed from the queue.
|
||||
/// Popped frames need to be manually deallocated by the application upon transmission.
|
||||
///
|
||||
/// The RX pipeline is managed with the help of three API functions; unlike the TX pipeline, there is one shared
|
||||
/// state for all redundant interfaces that manages deduplication transparently. The main function canardRxAccept()
|
||||
/// takes a received CAN frame and updates the appropriate transfer reassembly state machine. The functions
|
||||
/// canardRxSubscribe() and its counterpart canardRxUnsubscribe() instruct the library which transfers should be
|
||||
/// received (by default, all transfers are ignored); also, the subscription function specifies vital transfer
|
||||
/// reassembly parameters such as the maximum payload size (i.e., the maximum size of a serialized representation
|
||||
/// of a DSDL object) and the transfer-ID timeout. Transfers that carry more payload than the configured maximum per
|
||||
/// subscription are truncated following the Implicit Truncation Rule (ITR) defined by the Cyphal Specification --
|
||||
/// the rule is implemented to facilitate backward-compatible DSDL data type extensibility.
|
||||
///
|
||||
/// The library supports a practically unlimited number of redundant interfaces.
|
||||
///
|
||||
/// The library is not thread-safe: if used in a concurrent environment, it is the responsibility of the application
|
||||
/// to provide adequate synchronization.
|
||||
///
|
||||
/// The library is purely reactive: it does not perform any background processing and does not require periodic
|
||||
/// servicing. Its internal state is only updated as a response to well-specified external events.
|
||||
///
|
||||
/// --------------------------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// This software is distributed under the terms of the MIT License.
|
||||
/// Copyright (c) 2016 OpenCyphal.
|
||||
/// Author: Pavel Kirienko <pavel@opencyphal.org>
|
||||
/// Contributors: https://github.com/OpenCyphal/libcanard/contributors.
|
||||
|
||||
#ifndef CANARD_H_INCLUDED
|
||||
#define CANARD_H_INCLUDED
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Semantic version of this library (not the Cyphal specification).
|
||||
/// API will be backward compatible within the same major version.
|
||||
#define CANARD_VERSION_MAJOR 3
|
||||
#define CANARD_VERSION_MINOR 3
|
||||
|
||||
/// The version number of the Cyphal specification implemented by this library.
|
||||
#define CANARD_CYPHAL_SPECIFICATION_VERSION_MAJOR 1
|
||||
#define CANARD_CYPHAL_SPECIFICATION_VERSION_MINOR 0
|
||||
|
||||
/// These error codes may be returned from the library API calls whose return type is a signed integer in the negated
|
||||
/// form (e.g., error code 2 returned as -2). A non-negative return value represents success.
|
||||
/// API calls whose return type is not a signed integer cannot fail by contract.
|
||||
/// No other error states may occur in the library.
|
||||
/// By contract, a well-characterized application with a properly sized memory pool will never encounter errors.
|
||||
/// The error code 1 is not used because -1 is often used as a generic error code in 3rd-party code.
|
||||
#define CANARD_ERROR_INVALID_ARGUMENT 2
|
||||
#define CANARD_ERROR_OUT_OF_MEMORY 3
|
||||
|
||||
/// MTU values for the supported protocols.
|
||||
/// Per the recommendations given in the Cyphal/CAN Specification, other MTU values should not be used.
|
||||
#define CANARD_MTU_CAN_CLASSIC 8U
|
||||
#define CANARD_MTU_CAN_FD 64U
|
||||
#define CANARD_MTU_MAX CANARD_MTU_CAN_FD
|
||||
|
||||
/// Parameter ranges are inclusive; the lower bound is zero for all. See Cyphal/CAN Specification for background.
|
||||
#define CANARD_SUBJECT_ID_MAX 8191U
|
||||
#define CANARD_SERVICE_ID_MAX 511U
|
||||
#define CANARD_NODE_ID_MAX 127U
|
||||
#define CANARD_PRIORITY_MAX 7U
|
||||
#define CANARD_TRANSFER_ID_BIT_LENGTH 5U
|
||||
#define CANARD_TRANSFER_ID_MAX ((1U << CANARD_TRANSFER_ID_BIT_LENGTH) - 1U)
|
||||
|
||||
/// This value represents an undefined node-ID: broadcast destination or anonymous source.
|
||||
/// Library functions treat all values above CANARD_NODE_ID_MAX as anonymous.
|
||||
#define CANARD_NODE_ID_UNSET 255U
|
||||
|
||||
/// This is the recommended transfer-ID timeout value given in the Cyphal Specification. The application may choose
|
||||
/// different values per subscription (i.e., per data specifier) depending on its timing requirements.
|
||||
#define CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC 2000000UL
|
||||
|
||||
// Forward declarations.
|
||||
typedef struct CanardInstance CanardInstance;
|
||||
typedef struct CanardTreeNode CanardTreeNode;
|
||||
typedef struct CanardTxQueueItem CanardTxQueueItem;
|
||||
typedef uint64_t CanardMicrosecond;
|
||||
typedef uint16_t CanardPortID;
|
||||
typedef uint8_t CanardNodeID;
|
||||
typedef uint8_t CanardTransferID;
|
||||
|
||||
/// Transfer priority level mnemonics per the recommendations given in the Cyphal Specification.
|
||||
typedef enum
|
||||
{
|
||||
CanardPriorityExceptional = 0,
|
||||
CanardPriorityImmediate = 1,
|
||||
CanardPriorityFast = 2,
|
||||
CanardPriorityHigh = 3,
|
||||
CanardPriorityNominal = 4, ///< Nominal priority level should be the default.
|
||||
CanardPriorityLow = 5,
|
||||
CanardPrioritySlow = 6,
|
||||
CanardPriorityOptional = 7,
|
||||
} CanardPriority;
|
||||
|
||||
/// Transfer kinds as defined by the Cyphal Specification.
|
||||
typedef enum
|
||||
{
|
||||
CanardTransferKindMessage = 0, ///< Multicast, from publisher to all subscribers.
|
||||
CanardTransferKindResponse = 1, ///< Point-to-point, from server to client.
|
||||
CanardTransferKindRequest = 2, ///< Point-to-point, from client to server.
|
||||
} CanardTransferKind;
|
||||
#define CANARD_NUM_TRANSFER_KINDS 3
|
||||
|
||||
/// The AVL tree node structure is exposed here to avoid pointer casting/arithmetics inside the library.
|
||||
/// The user code is not expected to interact with this type except if advanced introspection is required.
|
||||
struct CanardTreeNode
|
||||
{
|
||||
CanardTreeNode* up; ///< Do not access this field.
|
||||
CanardTreeNode* lr[2]; ///< Left and right children of this node may be accessed for tree traversal.
|
||||
int8_t bf; ///< Do not access this field.
|
||||
};
|
||||
|
||||
/// CAN data frame with an extended 29-bit ID. RTR/Error frames are not used and therefore not modeled here.
|
||||
/// CAN frames with 11-bit ID are not used by Cyphal/CAN and so they are not supported by the library.
|
||||
typedef struct
|
||||
{
|
||||
/// 29-bit extended ID. The bits above 29-th shall be zero.
|
||||
uint32_t extended_can_id;
|
||||
|
||||
/// The useful data in the frame. The length value is not to be confused with DLC!
|
||||
/// If the payload is empty (payload_size = 0), the payload pointer may be NULL.
|
||||
/// For RX frames: the library does not expect the lifetime of the pointee to extend beyond the point of return
|
||||
/// from the API function. That is, the pointee can be invalidated immediately after the frame has been processed.
|
||||
/// For TX frames: the frame and the payload are allocated within the same dynamic memory fragment, so their
|
||||
/// lifetimes are identical; when the frame is freed, the payload is invalidated.
|
||||
/// A more detailed overview of the dataflow and related resource management issues is provided in the API docs.
|
||||
size_t payload_size;
|
||||
const void* payload;
|
||||
} CanardFrame;
|
||||
|
||||
/// Conversion look-up table from CAN DLC to data length.
|
||||
extern const uint8_t CanardCANDLCToLength[16];
|
||||
|
||||
/// Conversion look-up table from data length to CAN DLC; the length is rounded up.
|
||||
extern const uint8_t CanardCANLengthToDLC[65];
|
||||
|
||||
/// A Cyphal transfer metadata (everything except the payload).
|
||||
/// Per Specification, a transfer is represented on the wire as a non-empty set of transport frames (i.e., CAN frames).
|
||||
/// The library is responsible for serializing transfers into transport frames when transmitting, and reassembling
|
||||
/// transfers from an incoming stream of frames (possibly duplicated if redundant interfaces are used) during reception.
|
||||
typedef struct
|
||||
{
|
||||
/// Per the Specification, all frames belonging to a given transfer shall share the same priority level.
|
||||
/// If this is not the case, then this field contains the priority level of the last frame to arrive.
|
||||
CanardPriority priority;
|
||||
|
||||
CanardTransferKind transfer_kind;
|
||||
|
||||
/// Subject-ID for message publications; service-ID for service requests/responses.
|
||||
CanardPortID port_id;
|
||||
|
||||
/// For outgoing message transfers the value shall be CANARD_NODE_ID_UNSET (otherwise the state is invalid).
|
||||
/// For outgoing service transfers this is the destination address (invalid if unset).
|
||||
/// For incoming non-anonymous transfers this is the node-ID of the origin.
|
||||
/// For incoming anonymous transfers the value is reported as CANARD_NODE_ID_UNSET.
|
||||
CanardNodeID remote_node_id;
|
||||
|
||||
/// When responding to a service request, the response transfer SHALL have the same transfer-ID value as the
|
||||
/// request because the client will match the response with the request based on that.
|
||||
///
|
||||
/// When publishing a message transfer, the value SHALL be one greater than the previous transfer under the same
|
||||
/// subject-ID; the initial value should be zero.
|
||||
///
|
||||
/// When publishing a service request transfer, the value SHALL be one greater than the previous transfer under
|
||||
/// the same service-ID addressed to the same server node-ID; the initial value should be zero.
|
||||
///
|
||||
/// Upon overflow, the value SHALL be reset back to zero.
|
||||
/// Values above CANARD_TRANSFER_ID_MAX are permitted -- the library will compute the modulo automatically.
|
||||
/// For received transfers, the values never exceed CANARD_TRANSFER_ID_MAX.
|
||||
///
|
||||
/// A simple and robust way of managing transfer-ID counters is to keep a separate static variable per subject-ID
|
||||
/// and per (service-ID, server-node-ID) pair.
|
||||
CanardTransferID transfer_id;
|
||||
} CanardTransferMetadata;
|
||||
|
||||
/// Prioritized transmission queue that keeps CAN frames destined for transmission via one CAN interface.
|
||||
/// Applications with redundant interfaces are expected to have one instance of this type per interface.
|
||||
/// Applications that are not interested in transmission may have zero queues.
|
||||
/// All operations (push, peek, pop) are O(log n); there is exactly one heap allocation per element.
|
||||
/// API functions that work with this type are named "canardTx*()", find them below.
|
||||
typedef struct CanardTxQueue
|
||||
{
|
||||
/// The maximum number of frames this queue is allowed to contain. An attempt to push more will fail with an
|
||||
/// out-of-memory error even if the memory is not exhausted. This value can be changed by the user at any moment.
|
||||
/// The purpose of this limitation is to ensure that a blocked queue does not exhaust the heap memory.
|
||||
size_t capacity;
|
||||
|
||||
/// The transport-layer maximum transmission unit (MTU). The value can be changed arbitrarily at any time between
|
||||
/// pushes. It defines the maximum number of data bytes per CAN data frame in outgoing transfers via this queue.
|
||||
///
|
||||
/// Only the standard values should be used as recommended by the specification;
|
||||
/// otherwise, networking interoperability issues may arise. See recommended values CANARD_MTU_*.
|
||||
///
|
||||
/// Valid values are any valid CAN frame data length value not smaller than 8.
|
||||
/// Invalid values are treated as the nearest valid value. The default is the maximum valid value.
|
||||
size_t mtu_bytes;
|
||||
|
||||
/// The number of frames that are currently contained in the queue, initially zero.
|
||||
/// Do not modify this field!
|
||||
size_t size;
|
||||
|
||||
/// The root of the priority queue is NULL if the queue is empty. Do not modify this field!
|
||||
CanardTreeNode* root;
|
||||
|
||||
/// This field can be arbitrarily mutated by the user. It is never accessed by the library.
|
||||
/// Its purpose is to simplify integration with OOP interfaces.
|
||||
void* user_reference;
|
||||
} CanardTxQueue;
|
||||
|
||||
/// One frame stored in the transmission queue along with its metadata.
|
||||
struct CanardTxQueueItem
|
||||
{
|
||||
/// Internal use only; do not access this field.
|
||||
CanardTreeNode base;
|
||||
|
||||
/// Points to the next frame in this transfer or NULL. This field is mostly intended for own needs of the library.
|
||||
/// Normally, the application would not use it because transfer frame ordering is orthogonal to global TX ordering.
|
||||
/// It can be useful though for pulling pending frames from the TX queue if at least one frame of their transfer
|
||||
/// failed to transmit; the idea is that if at least one frame is missing, the transfer will not be received by
|
||||
/// remote nodes anyway, so all its remaining frames can be dropped from the queue at once using canardTxPop().
|
||||
CanardTxQueueItem* next_in_transfer;
|
||||
|
||||
/// This is the same value that is passed to canardTxPush().
|
||||
/// Frames whose transmission deadline is in the past shall be dropped.
|
||||
CanardMicrosecond tx_deadline_usec;
|
||||
|
||||
/// The actual CAN frame data.
|
||||
CanardFrame frame;
|
||||
};
|
||||
|
||||
/// Transfer subscription state. The application can register its interest in a particular kind of data exchanged
|
||||
/// over the bus by creating such subscription objects. Frames that carry data for which there is no active
|
||||
/// subscription will be silently dropped by the library. The entire RX pipeline is invariant to the number of
|
||||
/// redundant CAN interfaces used.
|
||||
///
|
||||
/// SUBSCRIPTION INSTANCES SHALL NOT BE MOVED WHILE IN USE.
|
||||
///
|
||||
/// The memory footprint of a subscription is large. On a 32-bit platform it slightly exceeds half a KiB.
|
||||
/// This is an intentional time-memory trade-off: use a large look-up table to ensure predictable temporal properties.
|
||||
typedef struct CanardRxSubscription
|
||||
{
|
||||
CanardTreeNode base; ///< Read-only DO NOT MODIFY THIS
|
||||
|
||||
CanardMicrosecond transfer_id_timeout_usec;
|
||||
size_t extent; ///< Read-only DO NOT MODIFY THIS
|
||||
CanardPortID port_id; ///< Read-only DO NOT MODIFY THIS
|
||||
|
||||
/// This field can be arbitrarily mutated by the user. It is never accessed by the library.
|
||||
/// Its purpose is to simplify integration with OOP interfaces.
|
||||
void* user_reference;
|
||||
|
||||
/// The current architecture is an acceptable middle ground between worst-case execution time and memory
|
||||
/// consumption. Instead of statically pre-allocating a dedicated RX session for each remote node-ID here in
|
||||
/// this table, we only keep pointers, which are NULL by default, populating a new RX session dynamically
|
||||
/// on an ad-hoc basis when we first receive a transfer from that node. This is O(1) because our memory
|
||||
/// allocation routines are assumed to be O(1) and we make at most one allocation per remote node.
|
||||
///
|
||||
/// A more predictable and simpler approach is to pre-allocate states here statically instead of keeping
|
||||
/// just pointers, but it would push the size of this instance from about 0.5 KiB to ~3 KiB for a typical 32-bit
|
||||
/// system. Since this is a general-purpose library, we have to pick a middle ground so we use the more complex
|
||||
/// but more memory-efficient approach.
|
||||
struct CanardInternalRxSession* sessions[CANARD_NODE_ID_MAX + 1U]; ///< Read-only DO NOT MODIFY THIS
|
||||
} CanardRxSubscription;
|
||||
|
||||
/// Reassembled incoming transfer returned by canardRxAccept().
|
||||
typedef struct CanardRxTransfer
|
||||
{
|
||||
CanardTransferMetadata metadata;
|
||||
|
||||
/// The timestamp of the first received CAN frame of this transfer.
|
||||
/// The time system may be arbitrary as long as the clock is monotonic (steady).
|
||||
CanardMicrosecond timestamp_usec;
|
||||
|
||||
/// If the payload is empty (payload_size = 0), the payload pointer may be NULL.
|
||||
/// The application is required to deallocate the payload buffer after the transfer is processed.
|
||||
size_t payload_size;
|
||||
void* payload;
|
||||
} CanardRxTransfer;
|
||||
|
||||
/// A pointer to the memory allocation function. The semantics are similar to malloc():
|
||||
/// - The returned pointer shall point to an uninitialized block of memory that is at least "amount" bytes large.
|
||||
/// - If there is not enough memory, the returned pointer shall be NULL.
|
||||
/// - The memory shall be aligned at least at max_align_t.
|
||||
/// - The execution time should be constant (O(1)).
|
||||
/// - The worst-case memory fragmentation should be bounded and easily predictable.
|
||||
/// If the standard dynamic memory manager of the target platform does not satisfy the above requirements,
|
||||
/// consider using O1Heap: https://github.com/pavel-kirienko/o1heap.
|
||||
typedef void* (*CanardMemoryAllocate)(CanardInstance* ins, size_t amount);
|
||||
|
||||
/// The counterpart of the above -- this function is invoked to return previously allocated memory to the allocator.
|
||||
/// The semantics are similar to free():
|
||||
/// - The pointer was previously returned by the allocation function.
|
||||
/// - The pointer may be NULL, in which case the function shall have no effect.
|
||||
/// - The execution time should be constant (O(1)).
|
||||
typedef void (*CanardMemoryFree)(CanardInstance* ins, void* pointer);
|
||||
|
||||
/// This is the core structure that keeps all of the states and allocated resources of the library instance.
|
||||
struct CanardInstance
|
||||
{
|
||||
/// User pointer that can link this instance with other objects.
|
||||
/// This field can be changed arbitrarily, the library does not access it after initialization.
|
||||
/// The default value is NULL.
|
||||
void* user_reference;
|
||||
|
||||
/// The node-ID of the local node.
|
||||
/// Per the Cyphal Specification, the node-ID should not be assigned more than once.
|
||||
/// Invalid values are treated as CANARD_NODE_ID_UNSET. The default value is CANARD_NODE_ID_UNSET.
|
||||
CanardNodeID node_id;
|
||||
|
||||
/// Dynamic memory management callbacks. See their type documentation for details.
|
||||
/// They SHALL be valid function pointers at all times.
|
||||
/// The time complexity models given in the API documentation are made on the assumption that the memory management
|
||||
/// functions have constant complexity O(1).
|
||||
///
|
||||
/// The following API functions may allocate memory: canardRxAccept(), canardTxPush().
|
||||
/// The following API functions may deallocate memory: canardRxAccept(), canardRxSubscribe(), canardRxUnsubscribe().
|
||||
/// The exact memory requirement and usage model is specified for each function in its documentation.
|
||||
CanardMemoryAllocate memory_allocate;
|
||||
CanardMemoryFree memory_free;
|
||||
|
||||
/// Read-only DO NOT MODIFY THIS
|
||||
CanardTreeNode* rx_subscriptions[CANARD_NUM_TRANSFER_KINDS];
|
||||
};
|
||||
|
||||
/// CAN acceptance filter configuration with an extended 29-bit ID utilizing an ID + mask filter scheme.
|
||||
/// Filter configuration can be programmed into a CAN controller to filter out irrelevant messages in hardware.
|
||||
/// This allows the software application to reduce CPU load spent on processing irrelevant messages.
|
||||
typedef struct CanardFilter
|
||||
{
|
||||
/// 29-bit extended ID. Defines the extended CAN ID to filter incoming frames against.
|
||||
/// The bits above 29-th shall be zero.
|
||||
uint32_t extended_can_id;
|
||||
/// 29-bit extended mask. Defines the bitmask used to enable/disable bits used to filter messages.
|
||||
/// Only bits that are enabled are compared to the extended_can_id for filtering.
|
||||
/// The bits above 29-th shall be zero.
|
||||
uint32_t extended_mask;
|
||||
} CanardFilter;
|
||||
|
||||
/// Construct a new library instance.
|
||||
/// The default values will be assigned as specified in the structure field documentation.
|
||||
/// If any of the pointers are NULL, the behavior is undefined.
|
||||
///
|
||||
/// The instance does not hold any resources itself except for the allocated memory.
|
||||
/// To safely discard it, simply remove all existing subscriptions, and don't forget about the TX queues.
|
||||
///
|
||||
/// The time complexity is constant. This function does not invoke the dynamic memory manager.
|
||||
CanardInstance canardInit(const CanardMemoryAllocate memory_allocate, const CanardMemoryFree memory_free);
|
||||
|
||||
/// Construct a new transmission queue instance with the specified values for capacity and mtu_bytes.
|
||||
/// No memory allocation is going to take place until the queue is actually pushed to.
|
||||
/// Applications are expected to have one instance of this type per redundant interface.
|
||||
///
|
||||
/// The instance does not hold any resources itself except for the allocated memory.
|
||||
/// To safely discard it, simply pop all items from the queue.
|
||||
///
|
||||
/// The time complexity is constant. This function does not invoke the dynamic memory manager.
|
||||
CanardTxQueue canardTxInit(const size_t capacity, const size_t mtu_bytes);
|
||||
|
||||
/// This function serializes a transfer into a sequence of transport frames and inserts them into the prioritized
|
||||
/// transmission queue at the appropriate position. Afterwards, the application is supposed to take the enqueued frames
|
||||
/// from the transmission queue using the function canardTxPeek() and transmit them. Each transmitted (or otherwise
|
||||
/// discarded, e.g., due to timeout) frame should be removed from the queue using canardTxPop(). The queue is
|
||||
/// prioritized following the normal CAN frame arbitration rules to avoid the inner priority inversion. The transfer
|
||||
/// payload will be copied into the transmission queue so that the lifetime of the frames is not related to the
|
||||
/// lifetime of the input payload buffer.
|
||||
///
|
||||
/// The MTU of the generated frames is dependent on the value of the MTU setting at the time when this function
|
||||
/// is invoked. The MTU setting can be changed arbitrarily between invocations.
|
||||
///
|
||||
/// The tx_deadline_usec will be used to populate the timestamp values of the resulting transport
|
||||
/// frames (so all frames will have the same timestamp value). This feature is intended to facilitate transmission
|
||||
/// deadline tracking, i.e., aborting frames that could not be transmitted before the specified deadline.
|
||||
/// Therefore, normally, the timestamp value should be in the future.
|
||||
/// The library itself, however, does not use or check this value in any way, so it can be zero if not needed.
|
||||
///
|
||||
/// The function returns the number of frames enqueued into the prioritized TX queue (which is always a positive
|
||||
/// number) in case of success (so that the application can track the number of items in the TX queue if necessary).
|
||||
/// In case of failure, the function returns a negated error code: either invalid argument or out-of-memory.
|
||||
///
|
||||
/// An invalid argument error may be returned in the following cases:
|
||||
/// - Any of the input arguments are NULL.
|
||||
/// - The remote node-ID is not CANARD_NODE_ID_UNSET and the transfer is a message transfer.
|
||||
/// - The remote node-ID is above CANARD_NODE_ID_MAX and the transfer is a service transfer.
|
||||
/// - The priority, subject-ID, or service-ID exceed their respective maximums.
|
||||
/// - The transfer kind is invalid.
|
||||
/// - The payload pointer is NULL while the payload size is nonzero.
|
||||
/// - The local node is anonymous and a message transfer is requested that requires a multi-frame transfer.
|
||||
/// - The local node is anonymous and a service transfer is requested.
|
||||
/// The following cases are handled without raising an invalid argument error:
|
||||
/// - If the transfer-ID is above the maximum, the excessive bits are silently masked away
|
||||
/// (i.e., the modulo is computed automatically, so the caller doesn't have to bother).
|
||||
///
|
||||
/// An out-of-memory error is returned if a TX frame could not be allocated due to the memory being exhausted,
|
||||
/// or if the capacity of the queue would be exhausted by this operation. In such cases, all frames allocated for
|
||||
/// this transfer (if any) will be deallocated automatically. In other words, either all frames of the transfer are
|
||||
/// enqueued successfully, or none are.
|
||||
///
|
||||
/// The time complexity is O(p + log e), where p is the amount of payload in the transfer, and e is the number of
|
||||
/// frames already enqueued in the transmission queue.
|
||||
///
|
||||
/// The memory allocation requirement is one allocation per transport frame. A single-frame transfer takes one
|
||||
/// allocation; a multi-frame transfer of N frames takes N allocations. The size of each allocation is
|
||||
/// (sizeof(CanardTxQueueItem) + MTU).
|
||||
int32_t canardTxPush(CanardTxQueue* const que,
|
||||
CanardInstance* const ins,
|
||||
const CanardMicrosecond tx_deadline_usec,
|
||||
const CanardTransferMetadata* const metadata,
|
||||
const size_t payload_size,
|
||||
const void* const payload);
|
||||
|
||||
/// This function accesses the top element of the prioritized transmission queue. The queue itself is not modified
|
||||
/// (i.e., the accessed element is not removed). The application should invoke this function to collect the transport
|
||||
/// frames of serialized transfers pushed into the prioritized transmission queue by canardTxPush().
|
||||
///
|
||||
/// The timestamp values of returned frames are initialized with tx_deadline_usec from canardTxPush().
|
||||
/// Timestamps are used to specify the transmission deadline. It is up to the application and/or the media layer
|
||||
/// to implement the discardment of timed-out transport frames. The library does not check it, so a frame that is
|
||||
/// already timed out may be returned here.
|
||||
///
|
||||
/// If the queue is empty or if the argument is NULL, the returned value is NULL.
|
||||
///
|
||||
/// If the queue is non-empty, the returned value is a pointer to its top element (i.e., the next frame to transmit).
|
||||
/// The returned pointer points to an object allocated in the dynamic storage; it should be eventually freed by the
|
||||
/// application by calling CanardInstance::memory_free(). The memory shall not be freed before the entry is removed
|
||||
/// from the queue by calling canardTxPop(); this is because until canardTxPop() is executed, the library retains
|
||||
/// ownership of the object. The pointer retains validity until explicitly freed by the application; in other words,
|
||||
/// calling canardTxPop() does not invalidate the object.
|
||||
///
|
||||
/// The payload buffer is located shortly after the object itself, in the same memory fragment. The application shall
|
||||
/// not attempt to free it.
|
||||
///
|
||||
/// The time complexity is logarithmic of the queue size. This function does not invoke the dynamic memory manager.
|
||||
const CanardTxQueueItem* canardTxPeek(const CanardTxQueue* const que);
|
||||
|
||||
/// This function transfers the ownership of the specified element of the prioritized transmission queue from the queue
|
||||
/// to the application. The element does not necessarily need to be the top one -- it is safe to dequeue any element.
|
||||
/// The element is dequeued but not invalidated; it is the responsibility of the application to deallocate the
|
||||
/// memory used by the object later. The memory SHALL NOT be deallocated UNTIL this function is invoked.
|
||||
/// The function returns the same pointer that it is given except that it becomes mutable.
|
||||
///
|
||||
/// If any of the arguments are NULL, the function has no effect and returns NULL.
|
||||
///
|
||||
/// The time complexity is logarithmic of the queue size. This function does not invoke the dynamic memory manager.
|
||||
CanardTxQueueItem* canardTxPop(CanardTxQueue* const que, const CanardTxQueueItem* const item);
|
||||
|
||||
/// This function implements the transfer reassembly logic. It accepts a transport frame from any of the redundant
|
||||
/// interfaces, locates the appropriate subscription state, and, if found, updates it. If the frame completed a
|
||||
/// transfer, the return value is 1 (one) and the out_transfer pointer is populated with the parameters of the
|
||||
/// newly reassembled transfer. The transfer reassembly logic is defined in the Cyphal specification.
|
||||
///
|
||||
/// The MTU of the accepted frame can be arbitrary; that is, any MTU is accepted. The DLC validity is irrelevant.
|
||||
///
|
||||
/// Any value of redundant_iface_index is accepted; that is, up to 256 redundant interfaces are supported.
|
||||
/// The index of the interface from which the transfer is accepted is always the same as redundant_iface_index
|
||||
/// of the current invocation, so the application can always determine which interface has delivered the transfer.
|
||||
///
|
||||
/// Upon return, the out_subscription pointer will point to the instance of CanardRxSubscription that accepted this
|
||||
/// frame; if no matching subscription exists (i.e., frame discarded), the pointer will be NULL.
|
||||
/// If this information is not relevant, set out_subscription to NULL.
|
||||
/// The purpose of this argument is to allow integration with OOP adapters built on top of libcanard; see also the
|
||||
/// user_reference provided in CanardRxSubscription.
|
||||
///
|
||||
/// The function invokes the dynamic memory manager in the following cases only:
|
||||
///
|
||||
/// 1. New memory for a session state object is allocated when a new session is initiated.
|
||||
/// This event occurs when a transport frame that matches a known subscription is received from a node that
|
||||
/// did not emit matching frames since the subscription was created.
|
||||
/// Once a new session is created, it is not destroyed until the subscription is terminated by invoking
|
||||
/// canardRxUnsubscribe(). The number of sessions is bounded and the bound is low (at most the number of nodes
|
||||
/// in the network minus one), also the size of a session instance is very small, so the removal is unnecessary.
|
||||
/// Real-time networks typically do not change their configuration at runtime, so it is possible to reduce
|
||||
/// the time complexity by never deallocating sessions.
|
||||
/// The size of a session instance is at most 48 bytes on any conventional platform (typically much smaller).
|
||||
///
|
||||
/// 2. New memory for the transfer payload buffer is allocated when a new transfer is initiated, unless the buffer
|
||||
/// was already allocated at the time.
|
||||
/// This event occurs when a transport frame that matches a known subscription is received and it begins a
|
||||
/// new transfer (that is, the start-of-frame flag is set and it is not a duplicate).
|
||||
/// The amount of the allocated memory equals the extent as configured via canardRxSubscribe(); please read
|
||||
/// its documentation for further information about the extent and related edge cases.
|
||||
/// The worst case occurs when every node on the bus initiates a multi-frame transfer for which there is a
|
||||
/// matching subscription: in this case, the library will allocate number_of_nodes allocations, where each
|
||||
/// allocation is the same size as the configured extent.
|
||||
///
|
||||
/// 3. Memory allocated for the transfer payload buffer may be deallocated at the discretion of the library.
|
||||
/// This operation does not increase the worst case execution time and does not improve the worst case memory
|
||||
/// consumption, so a deterministic application need not consider this behavior in the resource analysis.
|
||||
/// This behavior is implemented for the benefit of applications where rigorous characterization is unnecessary.
|
||||
///
|
||||
/// The worst case dynamic memory consumption per subscription is:
|
||||
///
|
||||
/// (sizeof(session instance) + extent) * number_of_nodes
|
||||
///
|
||||
/// Where sizeof(session instance) and extent are defined above, and number_of_nodes is the number of remote
|
||||
/// nodes emitting transfers that match the subscription (which cannot exceed (CANARD_NODE_ID_MAX-1) by design).
|
||||
/// If the dynamic memory pool is sized correctly, the application is guaranteed to never encounter an
|
||||
/// out-of-memory (OOM) error at runtime. The actual size of the dynamic memory pool is typically larger;
|
||||
/// for a detailed treatment of the problem and the related theory please refer to the documentation of O1Heap --
|
||||
/// a deterministic memory allocator for hard real-time embedded systems.
|
||||
///
|
||||
/// The time complexity is O(p + log n) where n is the number of subject-IDs or service-IDs subscribed to by the
|
||||
/// application, depending on the transfer kind of the supplied frame, and p is the amount of payload in the received
|
||||
/// frame (because it will be copied into an internal contiguous buffer). Observe that the time complexity is
|
||||
/// invariant to the network configuration (such as the number of online nodes) -- this is a very important
|
||||
/// design guarantee for real-time applications because the execution time is dependent only on the number of
|
||||
/// active subscriptions for a given transfer kind, and the MTU, both of which are easy to predict and account for.
|
||||
/// Excepting the subscription search and the payload data copying, the entire RX pipeline contains neither loops
|
||||
/// nor recursion.
|
||||
/// Misaddressed and malformed frames are discarded in constant time.
|
||||
///
|
||||
/// The function returns 1 (one) if the new frame completed a transfer. In this case, the details of the transfer
|
||||
/// are stored into out_transfer, and the transfer payload buffer ownership is passed to that object. The lifetime
|
||||
/// of the resulting transfer object is not related to the lifetime of the input transport frame (that is, even if
|
||||
/// it is a single-frame transfer, its payload is copied out into a new dynamically allocated buffer storage).
|
||||
/// If the extent is zero, the payload pointer may be NULL, since there is no data to store and so a
|
||||
/// buffer is not needed. The application is responsible for deallocating the payload buffer when the processing
|
||||
/// is done by invoking memory_free on the transfer payload pointer.
|
||||
///
|
||||
/// The function returns a negated out-of-memory error if it was unable to allocate dynamic memory.
|
||||
///
|
||||
/// The function does nothing and returns a negated invalid argument error immediately if any condition is true:
|
||||
/// - Any of the input arguments that are pointers are NULL.
|
||||
/// - The payload pointer of the input frame is NULL while its size is non-zero.
|
||||
/// - The CAN ID of the input frame is not less than 2**29=0x20000000.
|
||||
///
|
||||
/// The function returns zero if any of the following conditions are true (the general policy is that protocol
|
||||
/// errors are not escalated because they do not construe a node-local error):
|
||||
/// - The received frame is not a valid Cyphal/CAN transport frame.
|
||||
/// - The received frame is a valid Cyphal/CAN transport frame, but there is no matching subscription,
|
||||
/// the frame did not complete a transfer, the frame forms an invalid frame sequence, the frame is a duplicate,
|
||||
/// the frame is unicast to a different node (address mismatch).
|
||||
int8_t canardRxAccept(CanardInstance* const ins,
|
||||
const CanardMicrosecond timestamp_usec,
|
||||
const CanardFrame* const frame,
|
||||
const uint8_t redundant_iface_index,
|
||||
CanardRxTransfer* const out_transfer,
|
||||
CanardRxSubscription** const out_subscription);
|
||||
|
||||
/// This function creates a new subscription, allowing the application to register its interest in a particular
|
||||
/// category of transfers. The library will reject all transport frames for which there is no active subscription.
|
||||
/// The reference out_subscription shall retain validity until the subscription is terminated (the referred object
|
||||
/// cannot be moved or destroyed).
|
||||
///
|
||||
/// If such subscription already exists, it will be removed first as if canardRxUnsubscribe() was
|
||||
/// invoked by the application, and then re-created anew with the new parameters.
|
||||
///
|
||||
/// The extent defines the size of the transfer payload memory buffer; or, in other words, the maximum possible size
|
||||
/// of received objects, considering also possible future versions with new fields. It is safe to pick larger values.
|
||||
/// Note well that the extent is not the same thing as the maximum size of the object, it is usually larger!
|
||||
/// Transfers that carry payloads that exceed the specified extent will be accepted anyway but the excess payload
|
||||
/// will be truncated away, as mandated by the Specification. The transfer CRC is always validated regardless of
|
||||
/// whether its payload is truncated.
|
||||
///
|
||||
/// The default transfer-ID timeout value is defined as CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC; use it if not sure.
|
||||
/// The redundant interface fail-over timeout (if redundant interfaces are used) is the same as the transfer-ID timeout.
|
||||
/// It may be reduced in a future release of the library, but it will not affect the backward compatibility.
|
||||
///
|
||||
/// The return value is 1 if a new subscription has been created as requested.
|
||||
/// The return value is 0 if such subscription existed at the time the function was invoked. In this case,
|
||||
/// the existing subscription is terminated and then a new one is created in its place. Pending transfers may be lost.
|
||||
/// The return value is a negated invalid argument error if any of the input arguments are invalid.
|
||||
///
|
||||
/// The time complexity is logarithmic from the number of current subscriptions under the specified transfer kind.
|
||||
/// This function does not allocate new memory. The function may deallocate memory if such subscription already
|
||||
/// existed; the deallocation behavior is specified in the documentation for canardRxUnsubscribe().
|
||||
///
|
||||
/// Subscription instances have large look-up tables to ensure that the temporal properties of the algorithms are
|
||||
/// invariant to the network configuration (i.e., a node that is validated on a network containing one other node
|
||||
/// will provably perform identically on a network that contains X nodes). This is a conscious time-memory trade-off.
|
||||
int8_t canardRxSubscribe(CanardInstance* const ins,
|
||||
const CanardTransferKind transfer_kind,
|
||||
const CanardPortID port_id,
|
||||
const size_t extent,
|
||||
const CanardMicrosecond transfer_id_timeout_usec,
|
||||
CanardRxSubscription* const out_subscription);
|
||||
|
||||
/// This function reverses the effect of canardRxSubscribe().
|
||||
/// If the subscription is found, all its memory is de-allocated (session states and payload buffers); to determine
|
||||
/// the amount of memory freed, please refer to the memory allocation requirement model of canardRxAccept().
|
||||
///
|
||||
/// The return value is 1 if such subscription existed (and, therefore, it was removed).
|
||||
/// The return value is 0 if such subscription does not exist. In this case, the function has no effect.
|
||||
/// The return value is a negated invalid argument error if any of the input arguments are invalid.
|
||||
///
|
||||
/// The time complexity is logarithmic from the number of current subscriptions under the specified transfer kind.
|
||||
/// This function does not allocate new memory.
|
||||
int8_t canardRxUnsubscribe(CanardInstance* const ins,
|
||||
const CanardTransferKind transfer_kind,
|
||||
const CanardPortID port_id);
|
||||
|
||||
/// This function allows to check the effect of canardRxSubscribe() and canardRxUnsubscribe().
|
||||
///
|
||||
/// The return value is 1 if the specified subscription exists, 0 otherwise.
|
||||
/// The return value is a negated invalid argument error if any of the input arguments are invalid.
|
||||
/// Output out_subscription could be NULL, but if it is not, it will be populated with the pointer to the existing
|
||||
/// subscription. In case the subscription does not exist (or error), out_subscription won't be touched.
|
||||
/// Result pointer to the subscription is valid until the subscription is terminated.
|
||||
///
|
||||
/// The time complexity is logarithmic from the number of current subscriptions under the specified transfer kind.
|
||||
/// This function does not allocate new memory.
|
||||
int8_t canardRxGetSubscription(CanardInstance* const ins,
|
||||
const CanardTransferKind transfer_kind,
|
||||
const CanardPortID port_id,
|
||||
CanardRxSubscription** const out_subscription);
|
||||
|
||||
/// Utilities for generating CAN controller hardware acceptance filter configurations
|
||||
/// to accept specific subjects, services, or nodes.
|
||||
///
|
||||
/// Complex applications will likely subscribe to more subject IDs than there are
|
||||
/// acceptance filters available in the CAN hardware. In this case, the application
|
||||
/// should implement filter consolidation. See canardConsolidateFilters()
|
||||
/// as well as the Cyphal specification for details.
|
||||
|
||||
/// Generate an acceptance filter configuration to accept a specific subject ID.
|
||||
CanardFilter canardMakeFilterForSubject(const CanardPortID subject_id);
|
||||
|
||||
/// Generate an acceptance filter configuration to accept both requests and responses for a specific service.
|
||||
///
|
||||
/// Users may prefer to instead use a catch-all acceptance filter configuration for accepting
|
||||
/// all service requests and responses targeted at the specified local node ID.
|
||||
/// See canardMakeFilterForServices() for this.
|
||||
CanardFilter canardMakeFilterForService(const CanardPortID service_id, const CanardNodeID local_node_id);
|
||||
|
||||
/// Generate an acceptance filter configuration to accept all service
|
||||
/// requests and responses targeted to the specified local node ID.
|
||||
///
|
||||
/// Due to the relatively low frequency of service transfers expected on a network,
|
||||
/// and the fact that a service directed at a specific node is not likely to be rejected by that node,
|
||||
/// a user may prefer to use this over canardMakeFilterForService()
|
||||
/// in order to simplify the API usage and reduce the number of required hardware CAN acceptance filters.
|
||||
CanardFilter canardMakeFilterForServices(const CanardNodeID local_node_id);
|
||||
|
||||
/// Consolidate two acceptance filter configurations into a single configuration.
|
||||
///
|
||||
/// Complex applications will likely subscribe to more subject IDs than there are
|
||||
/// acceptance filters available in the CAN hardware. In this case, the application
|
||||
/// should implement filter consolidation. While this may make it impossible to create
|
||||
/// a 'perfect' filter that only accepts desired subject IDs, the application should apply
|
||||
/// consolidation in a manner that minimizes the number of undesired messages that pass
|
||||
/// through the hardware acceptance filters and require software filtering (implemented by canardRxSubscribe).
|
||||
///
|
||||
/// While optimal choice of filter consolidation is a function of the number of available hardware filters,
|
||||
/// the set of transfers needed by the application, and the expected frequency of occurrence
|
||||
/// of all possible distinct transfers on the bus, it is possible to generate a quasi-optimal configuration
|
||||
/// if information about the frequency of occurrence of different transfers is not known.
|
||||
/// For details, see the "Automatic hardware acceptance filter configuration" note under the Cyphal/CAN section
|
||||
/// in the Transport Layer chapter of the Cyphal specification.
|
||||
CanardFilter canardConsolidateFilters(const CanardFilter* const a, const CanardFilter* const b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,118 @@
|
|||
#include "canard.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
CanardInstance canard;
|
||||
CanardTxQueue txQueue;
|
||||
|
||||
void* canard_memAllocate(CanardInstance* const canard, const size_t amount)
|
||||
{
|
||||
(void) canard;
|
||||
return x_malloc(amount);
|
||||
}
|
||||
|
||||
void canard_memFree(CanardInstance* const canard, void* const pointer)
|
||||
{
|
||||
(void) canard;
|
||||
free(pointer);
|
||||
}
|
||||
|
||||
void slave_comm_init()
|
||||
{
|
||||
canard = canardInit(&canard_memAllocate, &canard_memFree);
|
||||
canard.node_id = savePara.id;
|
||||
txQueue = canardTxInit(1536, CANARD_MTU_CAN_CLASSIC); // Set MTU = 64 bytes. There is also CANARD_MTU_CAN_CLASSIC.
|
||||
}
|
||||
|
||||
void slave_comm_tx_process()
|
||||
{
|
||||
for (const CanardTxQueueItem* ti = NULL; (ti = canardTxPeek(&txQueue)) != NULL;) // Peek at the top of the queue.
|
||||
{
|
||||
if ((0U == ti->tx_deadline_usec) || (ti->tx_deadline_usec > rt_tick_get_millisecond()*1000)) // Check the deadline.
|
||||
{
|
||||
if (!slave_send_ext(ti->frame.extended_can_id,(void *)ti->frame.payload,ti->frame.payload_size)) // Send the frame over this redundant CAN iface.
|
||||
{
|
||||
break; // If the driver is busy, break and retry later.
|
||||
}
|
||||
}
|
||||
|
||||
// After the frame is transmitted or if it has timed out while waiting, pop it from the queue and deallocate:
|
||||
canard.memory_free(&canard, canardTxPop(&txQueue, ti));
|
||||
}
|
||||
}
|
||||
|
||||
rt_inline uint8_t slave_send_ext(uint32_t id,uint8_t *sendBuf,uint8_t len)
|
||||
{
|
||||
struct rt_can_msg txMsg = {0};
|
||||
|
||||
txMsg.id = id;
|
||||
txMsg.ide = RT_CAN_EXTID;
|
||||
txMsg.rtr = RT_CAN_DTR;
|
||||
txMsg.len = len;
|
||||
for(rt_uint8_t i=0;i<len;i++)
|
||||
{
|
||||
txMsg.data[i] = sendBuf[i];
|
||||
}
|
||||
|
||||
|
||||
return rt_device_write(slaveDev,0,&txMsg,sizeof(txMsg));
|
||||
|
||||
}
|
||||
|
||||
void slave_comm_rx_process()
|
||||
{
|
||||
CanardRxTransfer transfer;
|
||||
CanardFrame receivedFrame;
|
||||
struct rt_can_msg canRxMsg = {0};
|
||||
uint32_t rxTimestampUsec;
|
||||
int8_t result;
|
||||
|
||||
while(rt_mq_recv(&slave_rec_msgq,&canRxMsg,sizeof(canRxMsg),RT_WAITING_NO) == RT_EOK)
|
||||
{
|
||||
|
||||
receivedFrame.extended_can_id = canRxMsg.id;
|
||||
receivedFrame.payload_size = canRxMsg.len;
|
||||
receivedFrame.payload = canRxMsg.data;
|
||||
|
||||
rxTimestampUsec = rt_tick_get_millisecond()*1000;
|
||||
|
||||
result = canardRxAccept(&canard,
|
||||
rxTimestampUsec, // When the frame was received, in microseconds.
|
||||
&receivedFrame, // The CAN frame received from the bus.
|
||||
0, // If the transport is not redundant, use 0.
|
||||
&transfer,
|
||||
NULL);
|
||||
if (result < 0)
|
||||
{
|
||||
// An error has occurred: either an argument is invalid or we've ran out of memory.
|
||||
// It is possible to statically prove that an out-of-memory will never occur for a given application if
|
||||
// the heap is sized correctly; for background, refer to the Robson's Proof and the documentation for O1Heap.
|
||||
// Reception of an invalid frame is NOT an error.
|
||||
}
|
||||
else if (result == 1)
|
||||
{
|
||||
void process_received_transfer(const uint8_t index,CanardRxTransfer* const transfer);
|
||||
process_received_transfer(0, &transfer); // A transfer has been received, process it.
|
||||
canard.memory_free(&canard, transfer.payload); // Deallocate the dynamic memory afterwards.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nothing to do.
|
||||
// The received frame is either invalid or it's a non-last frame of a multi-frame transfer.
|
||||
// Reception of an invalid frame is NOT reported as an error because it is not an error.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void process_received_transfer(const uint8_t index,CanardRxTransfer* const transfer)
|
||||
{
|
||||
LOG_D("slave rec id:%d size:%d",transfer->metadata.remote_node_id,transfer->payload_size);
|
||||
if(transfer->metadata.remote_node_id == canard.node_id)
|
||||
{
|
||||
slavePackDef *p = (slavePackDef *)transfer->payload;
|
||||
recCmd = p->packCmd;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue