first commit for chrg

This commit is contained in:
wmano
2025-08-16 22:58:22 +08:00
commit 52a3ed5862
2306 changed files with 1021208 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
/**
* Change Logs:
* 1. 增加长按按键恢复出厂固件的选项
* 2. 修改中断开启与关闭接口
*/
#ifndef __BSP_COMMON_H__
#define __BSP_COMMON_H__
#include "common.h"
#if (ENABLE_FACTORY_FIRMWARE_BUTTON)
#include "bsp_key.h"
#endif
#include "bsp_uart.h"
#include "drv_timer.h"
#include "bsp_flash.h"
#define BSP_VERSION_MAIN (0x01U) /*!< [15:8] main version */
#define BSP_VERSION_SUB (0x00U) /*!< [ 7:0] sub version */
#define BSP_VERSION ((BSP_VERSION_MAIN << 8) \
|(BSP_VERSION_SUB))
#define BSP_Delay(ms) HAL_Delay(ms)
#define BSP_INT_ENTER()
#define BSP_INT_EXIT()
#define BSP_INT_EN() __enable_irq()
#define BSP_INT_DIS() __disable_irq()
#define BSP_UART_ENABLE_RX(UARTx) UARTx.Instance->CR1 |= (uint32_t)0x0004
#define BSP_UART_DISABLE_RX(UARTx) UARTx.Instance->CR1 &= (~(uint32_t)0x0004)
typedef enum {
ERR_OK = 0x00,
ERR_UNKNOWN = 0x01, // 未知错误
/* 协议错误 */
ERR_DUPLICATE_FRAME = 0x02, // 重复帧
ERR_OMISSION_FRAME = 0x03, // 跳帧或遗漏帧
ERR_PKT_NUM_ERR = 0x04, // 正反序列号错误
ERR_FRAME_LENGTH = 0x05, // 帧长度错误
ERR_FRAME_VERIFY_ERR = 0x06, // 帧校验错误
ERR_HEADER_ERR = 0x07, // header 错误
ERR_EXE_FLOW = 0x08, // 执行流程错误,未按协议流程收到数据包
/* 业务错误 */
ERR_NO_FACTORY_FIRMWARE = 0x10, // 没有可供恢复出厂的固件
ERR_NO_THIS_PART, /* 找不到固件包指定的分区 */
ERR_READ_IS_EMPTY_ERR, /* 判断分区是否为空时读取错误 */
ERR_FIRMWARE_OVERSIZE, /* 固件大小超过分区容量 */
ERR_FIRMWARE_HEAD_VERIFY_ERR, /* 固件包头校验错误 */
ERR_VERIFY_READ_ERR, /* 校验固件时读取错误 */
ERR_RAW_BODY_VERIFY_ERR, /* 源固件包体校验错误 */
ERR_PKG_BODY_VERIFY_ERR, /* 打包后的固件包体校验错误 */
ERR_ERASE_PART_ERR, /* 擦除分区错误 */
ERR_WRITE_FIRST_ADDR_ERR, /* 数据写入分区首地址错误 */
ERR_JUMP_TO_APP_ERR, /* 跳转至 APP 时检测到错误 */
ERR_READ_FIRMWARE_HEAD_ERR, /* 读取固件包头错误 */
ERR_UPDATE_READ_ERR, /* 固件更新至 APP 分区时读取分区错误 */
ERR_UPDATE_VER_READ_ERR, /* 更新固件版本信息时读取分区错误 */
ERR_UPDATE_VER_ERASE_ERR, /* 更新固件版本信息时擦除分区错误 */
ERR_UPDATE_VER_WRITE_ERR, /* 更新固件版本信息时写入分区错误 */
ERR_WRITE_PART_ERR, /* 数据写入分区错误 */
ERR_FAULT_FIRMWARE, /* 错误的固件包 */
ERR_DECRYPT_ERR = 0x30, // 固件解密失败
ERR_NO_DECRYPT_COMPONENT, // 从机没有解密组件,无法解密
ERR_FLASH_NO_EMPTY, // flash 非空
ERR_READ_VER_ERR, // 读取固件的版本失败
ERR_WRITE_VER_ERR, // 固件的版本写入 APP 分区失败
ERR_VER_AREA_NO_ERASE, // APP 分区的固件版本区域没有擦除
ERR_CAN_NOT_PLACE_IN_APP, // 从机限制了多分区方案时不能指定固件包放置于 APP 分区
ERR_DOES_NOT_EXIST_DOWNLOAD, // 不存在 download 分区
ERR_DOES_NOT_EXIST_FACTORY, // 不存在 factory 分区
} eErrCode;
#endif
+341
View File
@@ -0,0 +1,341 @@
#include "bsp_flash.h"
static uint32_t _Get_STM32SectorIndex(uint32_t addr)
{
uint32_t sector = 0;
if ((addr < ADDR_FLASH_SECTOR_1) && (addr >= ADDR_FLASH_SECTOR_0))
{
sector = FLASH_SECTOR_0;
}
else if ((addr < ADDR_FLASH_SECTOR_2) && (addr >= ADDR_FLASH_SECTOR_1))
{
sector = FLASH_SECTOR_1;
}
else if ((addr < ADDR_FLASH_SECTOR_3) && (addr >= ADDR_FLASH_SECTOR_2))
{
sector = FLASH_SECTOR_2;
}
else if ((addr < ADDR_FLASH_SECTOR_4) && (addr >= ADDR_FLASH_SECTOR_3))
{
sector = FLASH_SECTOR_3;
}
else if ((addr < ADDR_FLASH_SECTOR_5) && (addr >= ADDR_FLASH_SECTOR_4))
{
sector = FLASH_SECTOR_4;
}
#if defined(FLASH_SECTOR_5)
else if ((addr < ADDR_FLASH_SECTOR_6) && (addr >= ADDR_FLASH_SECTOR_5))
{
sector = FLASH_SECTOR_5;
}
#endif
#if defined(FLASH_SECTOR_6)
else if ((addr < ADDR_FLASH_SECTOR_7) && (addr >= ADDR_FLASH_SECTOR_6))
{
sector = FLASH_SECTOR_6;
}
#endif
#if defined(FLASH_SECTOR_7)
else if ((addr < ADDR_FLASH_SECTOR_8) && (addr >= ADDR_FLASH_SECTOR_7))
{
sector = FLASH_SECTOR_7;
}
#endif
#if defined(FLASH_SECTOR_8)
else if ((addr < ADDR_FLASH_SECTOR_9) && (addr >= ADDR_FLASH_SECTOR_8))
{
sector = FLASH_SECTOR_8;
}
#endif
#if defined(FLASH_SECTOR_9)
else if ((addr < ADDR_FLASH_SECTOR_10) && (addr >= ADDR_FLASH_SECTOR_9))
{
sector = FLASH_SECTOR_9;
}
#endif
#if defined(FLASH_SECTOR_10)
else if ((addr < ADDR_FLASH_SECTOR_11) && (addr >= ADDR_FLASH_SECTOR_10))
{
sector = FLASH_SECTOR_10;
}
#endif
#if defined(FLASH_SECTOR_11)
else if ((addr < ADDR_FLASH_SECTOR_12) && (addr >= ADDR_FLASH_SECTOR_11))
{
sector = FLASH_SECTOR_11;
}
#endif
#if defined(FLASH_SECTOR_12)
else if ((addr < ADDR_FLASH_SECTOR_13) && (addr >= ADDR_FLASH_SECTOR_12))
{
sector = FLASH_SECTOR_12;
}
#endif
#if defined(FLASH_SECTOR_13)
else if ((addr < ADDR_FLASH_SECTOR_14) && (addr >= ADDR_FLASH_SECTOR_13))
{
sector = FLASH_SECTOR_13;
}
#endif
#if defined(FLASH_SECTOR_14)
else if ((addr < ADDR_FLASH_SECTOR_15) && (addr >= ADDR_FLASH_SECTOR_14))
{
sector = FLASH_SECTOR_14;
}
#endif
#if defined(FLASH_SECTOR_15)
else if ((addr < ADDR_FLASH_SECTOR_16) && (addr >= ADDR_FLASH_SECTOR_15))
{
sector = FLASH_SECTOR_15;
}
#endif
#if defined(FLASH_SECTOR_16)
else if ((addr < ADDR_FLASH_SECTOR_17) && (addr >= ADDR_FLASH_SECTOR_16))
{
sector = FLASH_SECTOR_16;
}
#endif
#if defined(FLASH_SECTOR_17)
else if ((addr < ADDR_FLASH_SECTOR_18) && (addr >= ADDR_FLASH_SECTOR_17))
{
sector = FLASH_SECTOR_17;
}
#endif
#if defined(FLASH_SECTOR_18)
else if ((addr < ADDR_FLASH_SECTOR_19) && (addr >= ADDR_FLASH_SECTOR_18))
{
sector = FLASH_SECTOR_18;
}
#endif
#if defined(FLASH_SECTOR_19)
else if ((addr < ADDR_FLASH_SECTOR_20) && (addr >= ADDR_FLASH_SECTOR_19))
{
sector = FLASH_SECTOR_19;
}
#endif
#if defined(FLASH_SECTOR_20)
else if ((addr < ADDR_FLASH_SECTOR_21) && (addr >= ADDR_FLASH_SECTOR_20))
{
sector = FLASH_SECTOR_20;
}
#endif
#if defined(FLASH_SECTOR_21)
else if ((addr < ADDR_FLASH_SECTOR_22) && (addr >= ADDR_FLASH_SECTOR_21))
{
sector = FLASH_SECTOR_21;
}
#endif
#if defined(FLASH_SECTOR_22)
else if ((addr < ADDR_FLASH_SECTOR_23) && (addr >= ADDR_FLASH_SECTOR_22))
{
sector = FLASH_SECTOR_22;
}
#endif
#if defined(FLASH_SECTOR_23)
else /* (addr < FLASH_END_ADDR) && (addr >= ADDR_FLASH_SECTOR_23) */
{
sector = FLASH_SECTOR_23;
}
#endif
return sector;
}
int read(long offset, uint8_t *buf, size_t size)
{
size_t i = 0;
uint32_t addr = offset;
if ((addr + size) > OFFSET_ONCHIP_FLASH_END) {
return -1;
}
for (i = 0; i < size; i++, buf++, addr++) {
*buf = *(uint8_t *) addr;
}
return size;
}
int write(long offset, const uint8_t *buf, size_t size)
{
int status = 0;
uint32_t addr = offset;
uint32_t end_addr = addr + size;
if (end_addr > OFFSET_ONCHIP_FLASH_END) {
printf("%s:%d\r\n", __func__, __LINE__);
return -1;
}
if (size < 1) {
printf("%s:%d\r\n", __func__, __LINE__);
return -1;
}
size_t data_len = size * sizeof(uint32_t);
uint32_t *data = (uint32_t *)buf;
HAL_FLASH_Unlock();
/* Clear pending flags (if any) */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | \
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
for (uint32_t i = 0;
(i < data_len) && (addr <= (end_addr - sizeof(uint32_t)));
i++)
{
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (HAL_FLASH_Program(TYPEPROGRAM_WORD, addr, *(uint32_t *)(data + i)) == HAL_OK)
{
/* Check the written value */
if (*(uint32_t *)addr != *(uint32_t *)(data + i))
{
/* Flash content doesn't match SRAM content */
status = -1;
break;
}
/* Increment FLASH destination address */
addr += sizeof(uint32_t);
}
else
{
/* Error occurred while writing data in Flash memory */
status = -2;
break;
}
}
HAL_FLASH_Lock();
if (status < 0) {
printf("%s:%d %d\r\n", __func__, __LINE__, status);
return status;
}
return size;
}
int erase(long offset, size_t size)
{
uint32_t page_err = 0;
HAL_StatusTypeDef status = HAL_OK;
FLASH_EraseInitTypeDef erase_init = {0};
uint32_t addr = offset;
uint32_t end_addr = addr + size;
if (end_addr > OFFSET_ONCHIP_FLASH_END) {
return -1;
}
HAL_FLASH_Unlock();
/* Clear pending flags (if any) */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | \
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
uint8_t sector_count;
uint32_t sector_head_num;
uint32_t sector_end_num;
sector_head_num = _Get_STM32SectorIndex( addr );
sector_end_num = _Get_STM32SectorIndex( end_addr-1 );
sector_count = sector_end_num - sector_head_num;
sector_count ++;
#if (ENABLE_DB1M_BIT)
if (sector_head_num > FLASH_SECTOR_7)
sector_head_num += 4;
#endif
erase_init.TypeErase = TYPEERASE_SECTORS;
erase_init.Sector = sector_head_num;
erase_init.NbSectors = sector_count;
erase_init.VoltageRange = VOLTAGE_RANGE_3;
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
you have to make sure that these data are rewritten before they are accessed during code
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
DCRST and ICRST bits in the FLASH_CR register. */
status = HAL_FLASHEx_Erase(&erase_init, &page_err);
HAL_FLASH_Lock();
if (status != HAL_OK)
return -2;
return size;
}
static struct BSP_FLASH *_part_head;
static void _Flash_Add(struct BSP_FLASH *part)
{
struct BSP_FLASH *target;
for (target = _part_head; target != NULL; target = target->next)
{
if (target == part)
return;
}
part->next = _part_head;
_part_head = part;
}
void BSP_Flash_Init(struct BSP_FLASH *part, const char *name, uint32_t addr, uint32_t size)
{
ASSERT(part != NULL);
memcpy(part->name, name, MAX_NAME_LEN);
part->addr = addr;
part->len = size;
_Flash_Add(part);
}
int BSP_Flash_Read(const struct BSP_FLASH *part, uint32_t relative_addr, uint8_t *buff, uint32_t size)
{
ASSERT(part != NULL);
return read(part->addr + relative_addr, buff, size);
}
inline int BSP_Flash_Write(const struct BSP_FLASH *part, uint32_t relative_addr, const uint8_t *buff, uint32_t size)
{
ASSERT(part != NULL);
return write(part->addr + relative_addr, buff, size);
}
inline int BSP_Flash_Erase(const struct BSP_FLASH *part, uint32_t relative_addr, uint32_t size)
{
ASSERT(part != NULL);
return erase(part->addr + relative_addr, size);
}
struct BSP_FLASH *BSP_Flash_GetHandle(const char *part_name)
{
struct BSP_FLASH *part;
for (part = _part_head; part != NULL; part = part->next)
{
if (strncmp(part->name, part_name, MAX_NAME_LEN) == 0)
return part;
}
return NULL;
}
+54
View File
@@ -0,0 +1,54 @@
#ifndef __BSP_FLASH_H__
#define __BSP_FLASH_H__
#include "bsp_common.h"
/* Base address of the Flash sectors Bank 1 */
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
/* Base address of the Flash sectors Bank 2 */
#define ADDR_FLASH_SECTOR_12 ((uint32_t)0x08100000) /* Base @ of Sector 0, 16 Kbytes */
#define ADDR_FLASH_SECTOR_13 ((uint32_t)0x08104000) /* Base @ of Sector 1, 16 Kbytes */
#define ADDR_FLASH_SECTOR_14 ((uint32_t)0x08108000) /* Base @ of Sector 2, 16 Kbytes */
#define ADDR_FLASH_SECTOR_15 ((uint32_t)0x0810C000) /* Base @ of Sector 3, 16 Kbytes */
#define ADDR_FLASH_SECTOR_16 ((uint32_t)0x08110000) /* Base @ of Sector 4, 64 Kbytes */
#define ADDR_FLASH_SECTOR_17 ((uint32_t)0x08120000) /* Base @ of Sector 5, 128 Kbytes */
#define ADDR_FLASH_SECTOR_18 ((uint32_t)0x08140000) /* Base @ of Sector 6, 128 Kbytes */
#define ADDR_FLASH_SECTOR_19 ((uint32_t)0x08160000) /* Base @ of Sector 7, 128 Kbytes */
#define ADDR_FLASH_SECTOR_20 ((uint32_t)0x08180000) /* Base @ of Sector 8, 128 Kbytes */
#define ADDR_FLASH_SECTOR_21 ((uint32_t)0x081A0000) /* Base @ of Sector 9, 128 Kbytes */
#define ADDR_FLASH_SECTOR_22 ((uint32_t)0x081C0000) /* Base @ of Sector 10, 128 Kbytes */
#define ADDR_FLASH_SECTOR_23 ((uint32_t)0x081E0000) /* Base @ of Sector 11, 128 Kbytes */
struct BSP_FLASH
{
char name[MAX_NAME_LEN];
uint32_t addr;
uint32_t len;
struct BSP_FLASH *next;
};
void BSP_Flash_Init (struct BSP_FLASH *part, const char *name, uint32_t addr, uint32_t size);
int BSP_Flash_Read (const struct BSP_FLASH *part, uint32_t relative_addr, uint8_t *buff, uint32_t size);
int BSP_Flash_Write (const struct BSP_FLASH *part, uint32_t relative_addr, const uint8_t *buff, uint32_t size);
int BSP_Flash_Erase (const struct BSP_FLASH *part, uint32_t relative_addr, uint32_t size);
struct BSP_FLASH * BSP_Flash_GetHandle (const char *part_name);
#endif
+314
View File
@@ -0,0 +1,314 @@
#include "bsp_gpio.h"
static const struct GPIO_INDEX _gpios[] = {
#if defined(GPIOA)
STM32_PIN(0 , A, 0 ),
STM32_PIN(1 , A, 1 ),
STM32_PIN(2 , A, 2 ),
STM32_PIN(3 , A, 3 ),
STM32_PIN(4 , A, 4 ),
STM32_PIN(5 , A, 5 ),
STM32_PIN(6 , A, 6 ),
STM32_PIN(7 , A, 7 ),
STM32_PIN(8 , A, 8 ),
STM32_PIN(9 , A, 9 ),
STM32_PIN(10, A, 10),
STM32_PIN(11, A, 11),
STM32_PIN(12, A, 12),
STM32_PIN(13, A, 13),
STM32_PIN(14, A, 14),
STM32_PIN(15, A, 15),
#endif
#if defined(GPIOB)
STM32_PIN(16, B, 0),
STM32_PIN(17, B, 1),
STM32_PIN(18, B, 2),
STM32_PIN(19, B, 3),
STM32_PIN(20, B, 4),
STM32_PIN(21, B, 5),
STM32_PIN(22, B, 6),
STM32_PIN(23, B, 7),
STM32_PIN(24, B, 8),
STM32_PIN(25, B, 9),
STM32_PIN(26, B, 10),
STM32_PIN(27, B, 11),
STM32_PIN(28, B, 12),
STM32_PIN(29, B, 13),
STM32_PIN(30, B, 14),
STM32_PIN(31, B, 15),
#endif
#if defined(GPIOC)
STM32_PIN(32, C, 0),
STM32_PIN(33, C, 1),
STM32_PIN(34, C, 2),
STM32_PIN(35, C, 3),
STM32_PIN(36, C, 4),
STM32_PIN(37, C, 5),
STM32_PIN(38, C, 6),
STM32_PIN(39, C, 7),
STM32_PIN(40, C, 8),
STM32_PIN(41, C, 9),
STM32_PIN(42, C, 10),
STM32_PIN(43, C, 11),
STM32_PIN(44, C, 12),
STM32_PIN(45, C, 13),
STM32_PIN(46, C, 14),
STM32_PIN(47, C, 15),
#endif
#if defined(GPIOD)
STM32_PIN(48, D, 0),
STM32_PIN(49, D, 1),
STM32_PIN(50, D, 2),
STM32_PIN(51, D, 3),
STM32_PIN(52, D, 4),
STM32_PIN(53, D, 5),
STM32_PIN(54, D, 6),
STM32_PIN(55, D, 7),
STM32_PIN(56, D, 8),
STM32_PIN(57, D, 9),
STM32_PIN(58, D, 10),
STM32_PIN(59, D, 11),
STM32_PIN(60, D, 12),
STM32_PIN(61, D, 13),
STM32_PIN(62, D, 14),
STM32_PIN(63, D, 15),
#endif
#if defined(GPIOE)
STM32_PIN(64, E, 0),
STM32_PIN(65, E, 1),
STM32_PIN(66, E, 2),
STM32_PIN(67, E, 3),
STM32_PIN(68, E, 4),
STM32_PIN(69, E, 5),
STM32_PIN(70, E, 6),
STM32_PIN(71, E, 7),
STM32_PIN(72, E, 8),
STM32_PIN(73, E, 9),
STM32_PIN(74, E, 10),
STM32_PIN(75, E, 11),
STM32_PIN(76, E, 12),
STM32_PIN(77, E, 13),
STM32_PIN(78, E, 14),
STM32_PIN(79, E, 15),
#endif
#if defined(GPIOF)
STM32_PIN(80, F, 0),
STM32_PIN(81, F, 1),
STM32_PIN(82, F, 2),
STM32_PIN(83, F, 3),
STM32_PIN(84, F, 4),
STM32_PIN(85, F, 5),
STM32_PIN(86, F, 6),
STM32_PIN(87, F, 7),
STM32_PIN(88, F, 8),
STM32_PIN(89, F, 9),
STM32_PIN(90, F, 10),
STM32_PIN(91, F, 11),
STM32_PIN(92, F, 12),
STM32_PIN(93, F, 13),
STM32_PIN(94, F, 14),
STM32_PIN(95, F, 15),
#endif
#if defined(GPIOG)
STM32_PIN(96, G, 0),
STM32_PIN(97, G, 1),
STM32_PIN(98, G, 2),
STM32_PIN(99, G, 3),
STM32_PIN(100, G, 4),
STM32_PIN(101, G, 5),
STM32_PIN(102, G, 6),
STM32_PIN(103, G, 7),
STM32_PIN(104, G, 8),
STM32_PIN(105, G, 9),
STM32_PIN(106, G, 10),
STM32_PIN(107, G, 11),
STM32_PIN(108, G, 12),
STM32_PIN(109, G, 13),
STM32_PIN(110, G, 14),
STM32_PIN(111, G, 15),
#endif
#if defined(GPIOH)
STM32_PIN(112, H, 0),
STM32_PIN(113, H, 1),
STM32_PIN(114, H, 2),
STM32_PIN(115, H, 3),
STM32_PIN(116, H, 4),
STM32_PIN(117, H, 5),
STM32_PIN(118, H, 6),
STM32_PIN(119, H, 7),
STM32_PIN(120, H, 8),
STM32_PIN(121, H, 9),
STM32_PIN(122, H, 10),
STM32_PIN(123, H, 11),
STM32_PIN(124, H, 12),
STM32_PIN(125, H, 13),
STM32_PIN(126, H, 14),
STM32_PIN(127, H, 15),
#endif
#if defined(GPIOI)
STM32_PIN(128, I, 0),
STM32_PIN(129, I, 1),
STM32_PIN(130, I, 2),
STM32_PIN(131, I, 3),
STM32_PIN(132, I, 4),
STM32_PIN(133, I, 5),
STM32_PIN(134, I, 6),
STM32_PIN(135, I, 7),
STM32_PIN(136, I, 8),
STM32_PIN(137, I, 9),
STM32_PIN(138, I, 10),
STM32_PIN(139, I, 11),
STM32_PIN(140, I, 12),
STM32_PIN(141, I, 13),
STM32_PIN(142, I, 14),
STM32_PIN(143, I, 15),
#endif
#if defined(GPIOJ)
STM32_PIN(144, J, 0),
STM32_PIN(145, J, 1),
STM32_PIN(146, J, 2),
STM32_PIN(147, J, 3),
STM32_PIN(148, J, 4),
STM32_PIN(149, J, 5),
STM32_PIN(150, J, 6),
STM32_PIN(151, J, 7),
STM32_PIN(152, J, 8),
STM32_PIN(153, J, 9),
STM32_PIN(154, J, 10),
STM32_PIN(155, J, 11),
STM32_PIN(156, J, 12),
STM32_PIN(157, J, 13),
STM32_PIN(158, J, 14),
STM32_PIN(159, J, 15),
#endif
#if defined(GPIOK)
STM32_PIN(160, K, 0),
STM32_PIN(161, K, 1),
STM32_PIN(162, K, 2),
STM32_PIN(163, K, 3),
STM32_PIN(164, K, 4),
STM32_PIN(165, K, 5),
STM32_PIN(166, K, 6),
STM32_PIN(167, K, 7),
STM32_PIN(168, K, 8),
STM32_PIN(169, K, 9),
STM32_PIN(170, K, 10),
STM32_PIN(171, K, 11),
STM32_PIN(172, K, 12),
STM32_PIN(173, K, 13),
STM32_PIN(174, K, 14),
STM32_PIN(175, K, 15),
#endif
};
static const uint8_t _gpio_qty = sizeof(_gpios) / sizeof(_gpios[0]);
static const struct GPIO_INDEX *_GPIO_GetPin (uint8_t io)
{
const struct GPIO_INDEX *index;
if (io < _gpio_qty) {
index = &_gpios[io];
if (index->index == -1)
index = NULL;
}
else
index = NULL;
return index;
};
void BSP_GPIO_Write (uint8_t io, uint8_t level)
{
const struct GPIO_INDEX *index;
index = _GPIO_GetPin(io);
if (index == NULL)
return;
HAL_GPIO_WritePin(index->gpio, index->pin, (GPIO_PinState)level);
}
uint8_t BSP_GPIO_Read(uint8_t io)
{
const struct GPIO_INDEX *index;
index = _GPIO_GetPin(io);
if (index == NULL)
return GPIO_HIGH;
return HAL_GPIO_ReadPin(index->gpio, index->pin);
}
void BSP_GPIO_Toggle(uint8_t io)
{
const struct GPIO_INDEX *index;
index = _GPIO_GetPin(io);
if (index == NULL)
return;
HAL_GPIO_TogglePin(index->gpio, index->pin);
}
/*
* mode: IO模式(This parameter can be a value of @ref GPIO_mode_define stm32f1xx_hal_gpio.h
* pull: 上下拉(GPIO_NOPULL、GPIO_PULLUP、GPIO_PULLDOWN
*/
void BSP_GPIO_SetMode (uint8_t io, uint32_t mode, uint32_t pull)
{
const struct GPIO_INDEX *index;
GPIO_InitTypeDef GPIO_InitStruct;
index = _GPIO_GetPin(io);
if (index == NULL)
return;
/* Configure GPIO_InitStructure */
GPIO_InitStruct.Pin = index->pin;
GPIO_InitStruct.Mode = mode;
GPIO_InitStruct.Pull = pull;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(index->gpio, &GPIO_InitStruct);
}
GPIO_TypeDef *BSP_GPIO_GetPort(uint8_t io)
{
const struct GPIO_INDEX *index;
index = _GPIO_GetPin(io);
if (index == NULL)
return NULL;
return index->gpio;
}
uint16_t BSP_GPIO_GetPin (uint8_t io)
{
const struct GPIO_INDEX *index;
index = _GPIO_GetPin(io);
if (index == NULL)
return NULL;
return index->pin;
}
+36
View File
@@ -0,0 +1,36 @@
#ifndef __BSP_GPIO_H__
#define __BSP_GPIO_H__
#include "bsp_common.h"
#define GPIO_LOW 0x00
#define GPIO_HIGH 0x01
#define STM32_PORT(port) GPIO##port##_BASE
#define GET_PIN(port, pin) (uint32_t)((16 * ( ((uint32_t)STM32_PORT(port) - (uint32_t)GPIOA_BASE)/(0x0400UL) )) + pin)
#define STM32_PIN(index, gpio, gpio_index) \
{ \
index, GPIO##gpio, GPIO_PIN_##gpio_index \
}
/* STM32 GPIO driver */
struct GPIO_INDEX
{
int index;
GPIO_TypeDef *gpio;
uint16_t pin;
};
void BSP_GPIO_Write (uint8_t io, uint8_t level);
uint8_t BSP_GPIO_Read (uint8_t io);
void BSP_GPIO_Toggle (uint8_t io);
void BSP_GPIO_SetMode (uint8_t io, uint32_t mode, uint32_t pull);
GPIO_TypeDef * BSP_GPIO_GetPort (uint8_t io);
uint16_t BSP_GPIO_GetPin (uint8_t io);
#endif
+274
View File
@@ -0,0 +1,274 @@
/* Includes ------------------------------------------------------------------*/
#include "bsp_key.h"
/* Private variables ---------------------------------------------------------*/
#define EVENT_CALLBACK(event) do{ \
if (key_index->Callback[ event ]) \
{ \
key_index->Callback[ event ]( key_index->id, event ); \
} \
} while(0)
/* Private function prototypes -----------------------------------------------*/
static struct BSP_KEY *_key_head;
/* Exported functions ---------------------------------------------------------*/
/**
* @brief 按键对象初始化
* @note
* @param[in] key: 按键句柄
* @param[in] id: 按键 ID,用于识别不同的按键
* @param[in] KEY_GetState: 按键状态获取回调函数
* @param[in] press_level: 按键按下时的电平状态
* @param[in] press_time: 设置按键长按的间隔时间
* @retval 执行结果
*/
#if (KEY_USER_DEFINE_PRESS_TIME)
int8_t BSP_Key_Init(struct BSP_KEY *key, uint8_t id, uint8_t (*KEY_GetState)(void), KEY_LEVEL press_level, uint16_t press_time)
#else
int8_t BSP_Key_Init(struct BSP_KEY *key, uint8_t id, uint8_t (*KEY_GetState)(void), KEY_LEVEL press_level)
#endif
{
memset(key, 0, sizeof(struct BSP_KEY));
key->id = id;
key->press_level = press_level;
key->continuous_value = 0xFF;
key->GetState = KEY_GetState;
#if (KEY_USER_DEFINE_PRESS_TIME)
key->press_time = press_time;
#endif
return 0;
}
/**
* @brief 按键启用
* @note 每个按键初始化并注册好相应的按键事件回调函数后,必须调用本函数才能使用
* @param[in] key: 按键句柄
* @retval 执行结果
*/
int8_t BSP_Key_Start(struct BSP_KEY *key)
{
struct BSP_KEY *key_index = _key_head;
while (key_index)
{
if (key_index == key)
return 1;
key_index = key_index->next;
}
key->next = _key_head;
_key_head = key;
return 0;
}
/**
* @brief 按键停用
* @note 当按键不再需要使用时,便可调用本函数
* @param[in] key:按键句柄
* @retval None
*/
void BSP_Key_Stop(struct BSP_KEY *key)
{
struct BSP_KEY *key_now = _key_head;
struct BSP_KEY *key_last;
for (; key_now; key_now = key_now->next)
{
if (key_now == key)
{
if (key == _key_head)
{
_key_head = key->next;
return;
}
if (key->next)
key_last->next = key->next;
else
key_last->next = NULL;
}
key_last = key_now;
}
}
/**
* @brief 注册按键事件触发时的回调函数
* @note 若需要使用按键,则至少应该注册一个按键事件的回调函数
* @param[in] key: 按键句柄
* @param[in] event: 按键事件
* @param[in] callback: 按键事件回调函数
* @retval None
*/
void BSP_Key_Register(struct BSP_KEY *key, KEY_EVENT event, Key_EventCallback callback)
{
key->Callback[ event ] = callback;
}
/**
* @brief 按键业务处理函数
* @note 若需要使用按键的任何功能,都需要调用本函数,并周期性的循环执行
* @param[in] ms: 告知本函数每隔多少毫秒被执行1次
* @retval None
*/
void BSP_Key_Handler(uint8_t ms)
{
uint8_t i = 0;
uint8_t times = 0xFF;
struct BSP_KEY *key_index = _key_head;
for (; i < (8 - KEY_CONSECUTIVE_READ_TIME); i++)
times >>= 1;
for (; key_index; key_index = key_index->next)
{
/* 获取按键电平值 */
key_index->continuous_value = (key_index->continuous_value << 1) | key_index->GetState();
/* 获取按键按下或弹起状态 */
if ((key_index->continuous_value & times) == 0x00)
{
if (key_index->press_level == KEY_PRESS_LOW)
key_index->key_state = KEY_DOWN;
else
key_index->key_state = KEY_UP;
}
else if((key_index->continuous_value & times) == times)
{
if (key_index->press_level == KEY_PRESS_HIGH)
key_index->key_state = KEY_DOWN;
else
key_index->key_state = KEY_UP;
}
/* 按键状态机 */
switch (key_index->state)
{
case 0:
{
if (key_index->key_state == KEY_DOWN) /* 首次按下 */
{
key_index->event = KEY_PRESS;
EVENT_CALLBACK( KEY_PRESS );
key_index->state = 1;
}
break;
}
case 1:
{
if (key_index->key_state == KEY_UP) /* 按下后放开 */
{
key_index->tick = 0;
#if (KEY_CLICK_EVENT_WHEN_DBLCLICK)
key_index->event = KEY_CLICK;
EVENT_CALLBACK( KEY_CLICK );
#endif
key_index->state = 2;
}
else if (key_index->key_state == KEY_DOWN) /* 还处于第一次按下的状态 */
{
key_index->tick += ms;
#if (KEY_USER_DEFINE_PRESS_TIME)
if (key_index->tick >= key_index->press_time) /* 第一次按下时间已超过长按触发时间 */
#else
if (key_index->tick >= KEY_LONG_PRESS_TIME) /* 超时未按下 */
#endif
{
key_index->tick = 0;
key_index->event = KEY_LONG_PRESS;
EVENT_CALLBACK( KEY_LONG_PRESS );
key_index->state = 4;
}
}
break;
}
case 2: /* 检测是否双击 */
{
if (key_index->key_state == KEY_DOWN) /* 单击后再次按下 */
{
if (KEY_DBLCLICK_PRESS_VALID) /* 第二次按下立即触发标志 */
{
key_index->event = KEY_DBLCLICK;
EVENT_CALLBACK( KEY_DBLCLICK );
}
key_index->tick = 0;
key_index->state = 3;
}
else if (key_index->key_state == KEY_UP) /* 未按下 */
{
key_index->tick += ms;
if (key_index->tick >= KEY_DBLCLICK_TIME) /* 单击后超时未再按下,事件结束 */
{
#if (KEY_CLICK_EVENT_WHEN_DBLCLICK == 0)
key_index->event = KEY_CLICK;
EVENT_CALLBACK( KEY_CLICK );
#endif
key_index->tick = 0;
key_index->state = 0;
key_index->event = KEY_NONE_EVENT;
}
}
break;
}
case 3: /* 双击事件,第二次已按下 */
{
if (key_index->key_state == KEY_UP) /* 第二次已放开按键 */
{
if (KEY_DBLCLICK_PRESS_VALID == 0) /* 第二次按下放开后才触发标志 */
{
key_index->event = KEY_DBLCLICK;
EVENT_CALLBACK( KEY_DBLCLICK );
}
key_index->tick = 0;
key_index->state = 0;
key_index->event = KEY_NONE_EVENT;
}
break;
}
case 4: /* 长时间按着(进入此处时长按回调事件已经被执行完毕) */
{
if (key_index->key_state == KEY_DOWN) /* 此时依旧被按着 */
{
key_index->tick += ms;
#if (KEY_LONG_PRESS_CONTINU_TRIG_TIME)
/* 需要长按保持触发 */
if (key_index->tick >= KEY_LONG_PRESS_CONTINU_TRIG_TIME)
{
key_index->tick = 0;
key_index->event = KEY_LONG_PRESS_HOLD;
EVENT_CALLBACK( KEY_LONG_PRESS_HOLD );
}
#endif
}
else if (key_index->key_state == KEY_UP) /* 用户已放开按键,流程结束 */
{
key_index->tick = 0;
key_index->state = 0;
key_index->event = KEY_NONE_EVENT;
}
break;
}
default :break;
}
}
}
+91
View File
@@ -0,0 +1,91 @@
#ifndef __BSP_KEY_H__
#define __BSP_KEY_H__
#include "bsp_common.h"
#define KEY_TEST 0
/* 常用配置项 */
#define KEY_CLICK_EVENT_WHEN_DBLCLICK 0 /* 设定当双击按键时是否还触发单击事件。1:双击时依旧触发单击事件;0:双击时不触发单击事件,但会触发双击事件 */
#define KEY_DBLCLICK_PRESS_VALID 0 /* 按键双击时,选择第二次按下时立即触发事件,或是第二次按下时放开按键后才触发事件 */
/* 1:第二次按下时立即触发事件;0:第二次按下并放开按键后才触发事件 */
#define KEY_LONG_PRESS_TIME FACTORY_FIRMWARE_BUTTON_TIME /* 长按间隔时间,单位:ms */
#define KEY_DBLCLICK_TIME 200 /* 双击间隔时间。单位:ms */
/* 非常用配置项 */
#define KEY_USER_DEFINE_PRESS_TIME 0 /* 用户想针对每个按键设定不同的长按触发时间,为 0 时表示全部按键的长按触发时间使用 KEY_LONG_PRESS_TIME 参数 */
/* 为 1 时表示用户想单独为每个按键设置长按事件的触发时间 */
#define KEY_LONG_PRESS_CONTINU_TRIG_TIME 0 /* 一直长按按键, KEY_LONG_PRESS_TIME 个单位时间后,此参数表示的是用户持续按下按键每隔一段时间触发一次 KEY_LONG_PRESS_HOLD 事件 */
/* 为 0 时表示不管用户一直按下按键持续多长时间,都只触发一次 KEY_LONG_PRESS 事件,直到用户放开按键为止,才能继续下个事件的操作 */
#define KEY_CONSECUTIVE_READ_TIME 4 /* 连续读取键值次数,此参数用于实现非阻塞式的按键消抖,最大值:8 */
/* 该值会影响读取最终键值和触发事件的时间 */
/* 按键的单击事件触发时间 = KEY_CONSECUTIVE_READ_TIME * 传入BSP_Key_Handler函数的参数值,单位:ms */
/* 其他按键事件基于以上时间叠加 */
typedef enum
{
KEY_PRESS_LOW = 0x00,
KEY_PRESS_HIGH = 0xFF
} KEY_LEVEL;
typedef enum
{
KEY_UP = 0,
KEY_DOWN
} KEY_STATE;
typedef enum
{
KEY_PRESS = 0, /* 刚按下(每个按键事件都会触发该事件,是否要处理该事件由用户选择是否注册该事件的回调函数) */
KEY_CLICK = 1, /* 单击 */
KEY_DBLCLICK = 2, /* 双击 */
KEY_LONG_PRESS = 3, /* 长按 */
KEY_LONG_PRESS_HOLD = 4, /* 长按保持 */
KEY_EVENT_NUM, /* 事件总数 */
KEY_NONE_EVENT /* 默认无事件 */
} KEY_EVENT;
typedef void (*Key_EventCallback)(uint8_t id, KEY_EVENT event);
struct BSP_KEY
{
KEY_EVENT event; /* 按键事件记录 */
KEY_LEVEL press_level; /* 记录按下按键是什么电平(高或低) */
KEY_STATE key_state; /* 记录当前按键状态(按下或弹起) */
uint8_t id; /* 提供给用户的按键 id,由于有些用户可能想将所有的按键回调都写成一个函数接口,此举方便用户程序识别为是哪个按键触发了事件 */
/* 由数据类型可见,一个按键接口函数中最大支持256个按键 id */
uint8_t state; /* 状态机 */
uint8_t continuous_value; /* 按键连续采样缓存,一共8位深度,用于存取一个按键不同时刻的按键状态,最大是8次 */
uint16_t tick; /* 用于计时的临时变量 */
#if (KEY_USER_DEFINE_PRESS_TIME)
uint16_t press_time; /* 长按间隔时间 */
#endif
uint8_t (*GetState)(void); /* 按键电平状态获取函数,需要用户实现 */
Key_EventCallback Callback[ KEY_EVENT_NUM ]; /* 按键回调函数,由按键事件触发,需要用户实现 */
struct BSP_KEY *next; /* 简单的单向链表 */
};
#if (KEY_USER_DEFINE_PRESS_TIME)
int8_t BSP_Key_Init(struct BSP_KEY *key, uint8_t id, uint8_t (*KEY_GetState)(void), KEY_LEVEL press_level, uint16_t press_time);
#else
int8_t BSP_Key_Init(struct BSP_KEY *key, uint8_t id, uint8_t (*KEY_GetState)(void), KEY_LEVEL press_level);
#endif
int8_t BSP_Key_Start(struct BSP_KEY *key);
void BSP_Key_Register(struct BSP_KEY *key, KEY_EVENT event, Key_EventCallback callback);
void BSP_Key_Handler(uint8_t ms);
#endif
+359
View File
@@ -0,0 +1,359 @@
/**
* Change Logs:
* 优化中断开关
*/
/* Includes ------------------------------------------------------------------*/
#include "bsp_uart.h"
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void UART_CopyDataToUserBuff (struct UART_STRUCT *uart);
static void UART_RxIntHandler (struct UART_STRUCT *uart);
static void UART_RxIdleHandler (struct UART_STRUCT *uart);
static void UART_TxHandler (struct UART_STRUCT *uart);
/* Exported functions ---------------------------------------------------------*/
/**
* @brief UART 组件初始化
* @note 仅支持已实现的串口
* @param[in] id: 串口 ID
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_Init(BSP_UART_ID id)
{
/* GPIO/UART/DMA 等的初始化代码已由 cubeMX 生成 */
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
if (uart->init)
return BSP_UART_ERR_NO_INIT;
BSP_UART_Port_Init( uart,
UART_RxIntHandler,
UART_RxIdleHandler,
UART_CopyDataToUserBuff,
UART_TxHandler);
BSP_INT_DIS();
uart->init = 1;
BSP_INT_EN();
return BSP_UART_ERR_OK;
}
/**
* @brief 使能UART接收数据
* @note
* @param[in] id: 串口 ID
* @param[in] data: 接收的数据池
* @param[in] len: 指示接收数据长度的变量
* @param[in] max_len: 数据池的最大容量,单位 byte
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_EnableReceive(BSP_UART_ID id, uint8_t *data, uint16_t *len, uint16_t max_len)
{
ASSERT(data != NULL && len != NULL && max_len != 0);
BSP_UART_ERR ret;
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
uart->rx_data = data;
uart->rx_data_len = len;
uart->rx_data_max_len = max_len;
ret = BSP_UART_Port_EnableReceive(uart);
BSP_INT_DIS();
uart->rx_init = 1;
BSP_INT_EN();
return ret;
}
/**
* @brief 禁止 UART 接收数据
* @note
* @param[in] id: 串口 ID
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_DisableReceive(BSP_UART_ID id)
{
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
BSP_INT_DIS();
uart->rx_init = 0;
BSP_INT_EN();
return BSP_UART_Port_DisableReceive(uart);
}
/**
* @brief 判断 UART 是否收到了一帧数据
* @note 该接口为轮询的方式
* @param[in] id: 串口 ID
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_IsFrameEnd(BSP_UART_ID id)
{
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
// BSP_INT_DIS();
if (uart->idle_flag == 0)
{
// BSP_INT_EN();
return BSP_UART_ERR_NO_RECV_FRAME;
}
else
{
uart->idle_flag = 0;
// BSP_INT_EN();
return BSP_UART_ERR_OK;
}
}
/**
* @brief 挂载一个用户自定义的数据到 UART 对象上
* @note
* @param[in] id: 串口 ID
* @param[in] user_data: 用户自定义数据
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_LinkUserData(BSP_UART_ID id, void *user_data)
{
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
uart->user_data = user_data;
return BSP_UART_ERR_OK;
}
/**
* @brief 设置 UART 的发送完成指示回调函数
* @note
* @param[in] id: 串口 ID
* @param[in] TX_Complete: 函数指针
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_SetTxIndicate(BSP_UART_ID id, uint8_t (*TX_Complete)(struct UART_STRUCT *uart))
{
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
uart->TX_Complete = TX_Complete;
return BSP_UART_ERR_OK;
}
/**
* @brief 从 UART 发出一些数据
* @note 若使用 RTOS ,则 BSP_UART_Send、 BSP_UART_SendBlocking 均不能在中断中使用
* @param[in] id: 串口ID
* @param[in] data: 要发送的数据池
* @param[in] len: 要发送的数据长度,单位 byte
* @param[in] timeout: 发送最大超时等待时间,单位 ms
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_Send(BSP_UART_ID id, const uint8_t *data, uint16_t len, uint16_t timeout)
{
ASSERT(data != NULL && len != 0);
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
if (uart->init == 0)
return BSP_UART_ERR_NO_INIT;
return BSP_UART_Port_Send(uart, data, len, timeout);
}
/**
* @brief 清除用户传入的 UART 数据缓存池
* @note
* @param[in] id: 串口 ID
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_ClearUserBuff(BSP_UART_ID id)
{
struct UART_STRUCT *uart = BSP_UART_Port_GetHandle(id);
if (uart == NULL)
return BSP_UART_ERR_NOT_FOUND;
BSP_INT_DIS();
if (uart->rx_data_len)
*(uart->rx_data_len) = 0;
BSP_INT_EN();
return BSP_UART_ERR_OK;
}
/* Private functions ---------------------------------------------------------*/
/**
* @brief 将 DMA 缓存池的 UART 数据搬运到用户数据池中
* @note
* @param[in] uart: UART 对象
* @retval None
*/
static void UART_CopyDataToUserBuff(struct UART_STRUCT *uart)
{
if (*(uart->rx_data_len) >= uart->rx_data_max_len)
return;
// BSP_INT_DIS();
uint8_t *user_buff = &uart->rx_data[0];
uint16_t *user_buff_len = (uint16_t *)(uart->rx_data_len);
uint16_t new_pos = uart->rx_buff_max_len - BSP_UART_Port_GetDmaCounter(uart); /* 计算缓冲区的接收字节数 */
uint16_t recv_len = 0;
if (new_pos != uart->old_pos) /* 收到新的数据 */
{
if (new_pos > uart->old_pos) /* 线性模式 */
{
recv_len = new_pos - uart->old_pos; /* 计算本次接收到的字节数 */
/* 数据超出用户 buff ,只能接收用户 buff 剩余空间的长度数据 */
if ((*user_buff_len) + recv_len > uart->rx_data_max_len)
{
recv_len = uart->rx_data_max_len - *user_buff_len;
}
memcpy(&user_buff[*user_buff_len], &uart->rx_buff[ uart->old_pos ], recv_len);
(*user_buff_len) += recv_len; /* 设置偏移量 */
}
else /* 溢出模式 */
{
/* 先处理未溢出的部分 */
recv_len = uart->rx_buff_max_len - uart->old_pos;
/* 数据超出用户 buff ,只能接收用户 buff 剩余空间的长度数据 */
if (*user_buff_len + recv_len > uart->rx_data_max_len)
{
recv_len = uart->rx_data_max_len - *user_buff_len;
}
memcpy(&user_buff[*user_buff_len], &uart->rx_buff[ uart->old_pos ], recv_len);
*user_buff_len += recv_len; /* 设置偏移量 */
/* 再处理溢出的部分 */
recv_len = new_pos;
if (recv_len != 0)
{
/* 数据超出用户 buff ,只能接收用户 buff 剩余空间的长度数据 */
if (*user_buff_len + recv_len > uart->rx_data_max_len)
{
recv_len = uart->rx_data_max_len - *user_buff_len;
}
memcpy(&user_buff[*user_buff_len], &uart->rx_buff[0], recv_len);
(*user_buff_len) += recv_len; /* 设置偏移量 */
}
}
}
uart->old_pos = new_pos;
if (uart->old_pos >= uart->rx_buff_max_len)
{
uart->old_pos = 0;
}
// BSP_INT_EN();
}
/**
* @brief 串口接收到单字节数据的中断处理函数
* @note
* @param[in] uart: UART 对象
* @retval None
*/
static void UART_RxIntHandler(struct UART_STRUCT *uart)
{
if (uart->rx_init == 0)
return;
uart->rx_data[ *(uart->rx_data_len) ] = (uint8_t)BSP_UART_Port_GetOneByte(uart);
*(uart->rx_data_len) += 1;
if (*(uart->rx_data_len) == uart->rx_data_max_len)
{
*(uart->rx_data_len) = 0;
}
}
/**
* @brief 串口发生空闲中断的处理函数
* @note
* @param[in] uart: UART 对象
* @retval None
*/
static void UART_RxIdleHandler(struct UART_STRUCT *uart)
{
if (uart->rx_init == 0)
return;
// BSP_INT_DIS();
uart->idle_flag = 1;
// BSP_INT_EN();
if (uart->handle.hdmarx)
UART_CopyDataToUserBuff(uart);
BSP_UART_Port_RxUnlock(uart);
}
/**
* @brief 串口发送完成的中断处理函数
* @note
* @param[in] uart: UART 对象
* @retval None
*/
static void UART_TxHandler(struct UART_STRUCT *uart)
{
BSP_UART_Port_TxUnlock(uart);
if (uart->TX_Complete)
uart->TX_Complete(uart);
}
+145
View File
@@ -0,0 +1,145 @@
#ifndef __BSP_UART_H__
#define __BSP_UART_H__
#include "bsp_common.h"
#include "bsp_uart_config.h"
#define UART_INIT_PARA(x) \
{ \
.id = BSP_UART##x, \
.rx_buff = _uart##x##_buff, \
.rx_buff_max_len = BSP_UART_BUFF_SIZE, \
}
#define UART(x) _uart##x
#define UART_CREATE(x) static uint8_t _uart##x##_buff[BSP_UART_BUFF_SIZE]; \
static struct UART_STRUCT _uart##x = UART_INIT_PARA(x);
/* 定义项 */
typedef enum
{
#if (BSP_USING_UART1)
BSP_UART1 = 0x01,
#endif
#if (BSP_USING_UART2)
BSP_UART2 = 0x02,
#endif
#if (BSP_USING_UART2_RE)
BSP_UART2_RE = 0x82,
#endif
#if (BSP_USING_UART3)
BSP_UART3 = 0x03,
#endif
#if (BSP_USING_UART3_RE)
BSP_UART3_RE = 0x83,
#endif
#if (BSP_USING_UART4)
BSP_UART4 = 0x04,
#endif
#if (BSP_USING_UART5)
BSP_UART5 = 0x05,
#endif
#if (BSP_USING_UART6)
BSP_UART6 = 0x06,
#endif
} BSP_UART_ID;
typedef enum
{
BSP_UART_ERR_OK = 0x00U,
BSP_UART_ERR_COMM_ERR = 0x01U, /* 通讯错误(源自 HAL 库) */
BSP_UART_ERR_BUSY = 0x02U, /* UART 外设忙碌(源自 HAL 库) */
BSP_UART_ERR_TIMEOUT = 0x03U, /* 处理时间超时(源自 HAL 库) */
BSP_UART_ERR_NOT_FOUND = 0x04U, /* 未找到对应的 UART 对象 */
BSP_UART_ERR_LOCK_INIT_ERR = 0x05U, /* 通讯信号锁初始化失败 */
BSP_UART_ERR_LOCK_ERR = 0x06U, /* 通讯信号上锁失败 */
BSP_UART_ERR_UNLOCK_ERR = 0x07U, /* 通讯信号解锁失败 */
BSP_UART_ERR_NO_RECV_FRAME = 0x08U, /* 还未收到一帧完整的数据 */
BSP_UART_ERR_NO_INIT = 0x09U, /* 使用的 UART 对象还未初始化 */
BSP_UART_ERR_NAME_DUPLICATE = 0x0AU, /* UART 对象命名重复 */
} BSP_UART_ERR;
struct UART_STRUCT
{
UART_HandleTypeDef handle;
/* 串口唯一标识信息 */
const uint8_t id;
/* 用户串口数据,需要用户传入(二级缓存),当一级缓存半满和全满时,将会写入二级缓存 */
uint8_t *rx_data;
uint16_t * volatile rx_data_len;
uint16_t rx_data_max_len;
/* 一些标志位 */
volatile uint8_t init :1; /* 串口组件初始化标志位 */
volatile uint8_t rx_init :1; /* 串口组件的接收功能初始化标志位 */
// volatile uint8_t user_buff_full :1; /* 暂无使用 */
volatile uint8_t idle_flag :1; /* 是否发生空闲中断的标志位 */
volatile uint8_t :0;
/* 串口数据一级缓存(由 DMA 无条件写入) */
const uint8_t *rx_buff;
const uint16_t rx_buff_max_len;
/* 环形缓存的“写”位置 */
uint16_t old_pos;
/* 回调函数 */
uint8_t (*RX_Indicate)(struct UART_STRUCT *uart);
uint8_t (*TX_Complete)(struct UART_STRUCT *uart);
void *user_data;
};
typedef void (*UART_Callback_t)(struct UART_STRUCT *uart);
/**
* BSP UART 用户接口
*/
BSP_UART_ERR BSP_UART_Init (BSP_UART_ID id);
BSP_UART_ERR BSP_UART_EnableReceive (BSP_UART_ID id, uint8_t *data, uint16_t *len, uint16_t max_len);
BSP_UART_ERR BSP_UART_DisableReceive (BSP_UART_ID id);
BSP_UART_ERR BSP_UART_LinkUserData (BSP_UART_ID id, void *user_data);
BSP_UART_ERR BSP_UART_Send (BSP_UART_ID id, const uint8_t *data, uint16_t len, uint16_t timeout);
#if (ENABLE_DEBUG_PRINT)
void BSP_Printf (const char *fmt, ...);
#endif
BSP_UART_ERR BSP_UART_SetTxIndicate (BSP_UART_ID id, uint8_t (*TX_Complete)(struct UART_STRUCT *uart));
BSP_UART_ERR BSP_UART_ClearUserBuff (BSP_UART_ID id);
BSP_UART_ERR BSP_UART_IsFrameEnd (BSP_UART_ID id);
/**
* BSP UART 移植接口,不对外使用
*/
void BSP_UART_Port_Init ( struct UART_STRUCT *uart,
UART_Callback_t rx_callback,
UART_Callback_t rx_idle_callback,
UART_Callback_t dma_rx_callback,
UART_Callback_t dma_tx_callback);
BSP_UART_ERR BSP_UART_Port_EnableReceive (struct UART_STRUCT *uart);
BSP_UART_ERR BSP_UART_Port_DisableReceive (struct UART_STRUCT *uart);
BSP_UART_ERR BSP_UART_Port_Send (struct UART_STRUCT *uart, const uint8_t *data, uint16_t len, uint16_t timeout);
uint32_t BSP_UART_Port_GetDmaCounter (struct UART_STRUCT *uart);
uint32_t BSP_UART_Port_GetOneByte (struct UART_STRUCT *uart);
struct UART_STRUCT *BSP_UART_Port_GetHandle (BSP_UART_ID id);
/* 通讯锁 */
BSP_UART_ERR BSP_UART_Port_LockInit (struct UART_STRUCT *uart);
BSP_UART_ERR BSP_UART_Port_RxLock (struct UART_STRUCT *uart);
BSP_UART_ERR BSP_UART_Port_RxUnlock (struct UART_STRUCT *uart);
BSP_UART_ERR BSP_UART_Port_TxLock (struct UART_STRUCT *uart);
BSP_UART_ERR BSP_UART_Port_TxUnlock (struct UART_STRUCT *uart);
#endif
+61
View File
@@ -0,0 +1,61 @@
#ifndef __BSP_UART_CONFIG_H__
#define __BSP_UART_CONFIG_H__
#include "app_config.h"
#define BSP_PRINTF_BUFF_SIZE 256
#define BSP_PRINTF_HANDLE UART(1)
#define BSP_UART_BUFF_SIZE 64
#define BSP_USING_UART1 1
#define BSP_USING_UART2 1
#define BSP_USING_UART2_RE 0
#define BSP_USING_UART3 0
#define BSP_USING_UART3_RE 0
#define BSP_USING_UART4 0
#define BSP_USING_UART5 0
#define BSP_USING_UART6 0
/* 配置项 */
#define UART1_HANDLE huart1
#define UART2_HANDLE huart2
#define UART3_HANDLE huart3
#define UART4_HANDLE huart4
#define UART5_HANDLE huart5
#define UART6_HANDLE huart6
/* 移植时到不同型号的单片机时需要修改 */
#if defined(STM32F411xE)||defined(STM32F401xC)
#define UART1_DMA_RX_IRQHandler DMA2_Stream2_IRQHandler
#define UART1_DMA_TX_IRQHandler DMA2_Stream7_IRQHandler
#define UART2_DMA_RX_IRQHandler DMA1_Stream5_IRQHandler
#define UART2_DMA_TX_IRQHandler DMA1_Stream6_IRQHandler
#define UART6_DMA_RX_IRQHandler DMA2_Stream1_IRQHandler
#define UART6_DMA_TX_IRQHandler DMA2_Stream6_IRQHandler
#elif defined(STM32F407xx) || defined(STM32F405xx)
#define UART1_DMA_RX_IRQHandler DMA2_Stream2_IRQHandler
#define UART1_DMA_TX_IRQHandler DMA2_Stream7_IRQHandler
#define UART2_DMA_RX_IRQHandler DMA1_Stream5_IRQHandler
#define UART2_DMA_TX_IRQHandler DMA1_Stream6_IRQHandler
#define UART3_DMA_RX_IRQHandler DMA1_Stream1_IRQHandler
#define UART3_DMA_TX_IRQHandler DMA1_Stream3_IRQHandler
#define UART4_DMA_RX_IRQHandler DMA1_Stream2_IRQHandler
#define UART4_DMA_TX_IRQHandler DMA1_Stream4_IRQHandler
#define UART5_DMA_RX_IRQHandler DMA1_Stream0_IRQHandler
#define UART5_DMA_TX_IRQHandler DMA1_Stream7_IRQHandler
#define UART6_DMA_RX_IRQHandler DMA2_Stream1_IRQHandler
#define UART6_DMA_TX_IRQHandler DMA2_Stream6_IRQHandler
#elif defined(STM32F103xE) || defined(STM32F103xB)
#define UART1_DMA_RX_IRQHandler DMA1_Channel5_IRQHandler
#define UART1_DMA_TX_IRQHandler DMA1_Channel4_IRQHandler
#define UART2_DMA_RX_IRQHandler DMA1_Channel6_IRQHandler
#define UART3_DMA_RX_IRQHandler DMA1_Channel3_IRQHandler
#define UART4_DMA_RX_IRQHandler DMA2_Channel3_IRQHandler
#elif defined(STM32L475xx)
#define UART1_DMA_RX_IRQHandler DMA1_Channel5_IRQHandler
#define UART1_DMA_TX_IRQHandler DMA1_Channel4_IRQHandler
#endif
#endif
+693
View File
@@ -0,0 +1,693 @@
/**
* Change Logs:
* 憓𧼮 __HAL_UART_FLUSH_DRREGISTER
*/
/* Includes ------------------------------------------------------------------*/
#include "bsp_uart.h"
/* Private variables ---------------------------------------------------------*/
#if (BSP_USING_UART2_RE || BSP_USING_UART3_RE)
static volatile uint8_t _uart2_alter;
static volatile uint8_t _uart3_alter;
#endif
static UART_Callback_t _UART_RxCallback;
static UART_Callback_t _UART_RxIdleCallback;
static UART_Callback_t _UART_DMA_RxCallback;
static UART_Callback_t _UART_DMA_TxCallback;
#if (BSP_USING_UART1)
UART_CREATE(1);
#endif
#if (BSP_USING_UART2)
UART_CREATE(2);
#endif
#if (BSP_USING_UART2_RE)
UART_CREATE(2_RE);
#endif
#if (BSP_USING_UART3)
UART_CREATE(3);
#endif
#if (BSP_USING_UART3_RE)
UART_CREATE(3_RE);
#endif
#if (BSP_USING_UART4)
UART_CREATE(4);
#endif
#if (BSP_USING_UART5)
UART_CREATE(5);
#endif
#if (BSP_USING_UART6)
UART_CREATE(6);
#endif
struct UART_STRUCT *_uart_group[] =
{
#if (BSP_USING_UART1)
&UART(1),
#endif
#if (BSP_USING_UART2)
&UART(2),
#endif
#if (BSP_USING_UART2_RE)
&UART(2_RE),
#endif
#if (BSP_USING_UART3)
&UART(3),
#endif
#if (BSP_USING_UART3_RE)
&UART(3_RE),
#endif
#if (BSP_USING_UART4)
&UART(4),
#endif
#if (BSP_USING_UART5)
&UART(5),
#endif
#if (BSP_USING_UART6)
&UART(6),
#endif
};
static const uint8_t _uart_qty = sizeof(_uart_group) / sizeof(struct UART_STRUCT *);
/* Private function prototypes -----------------------------------------------*/
static inline void _UART_IntHandler (struct UART_STRUCT *uart);
static inline void _UART_Alternate (struct UART_STRUCT *uart);
/* Exported functions ---------------------------------------------------------*/
/**
* @brief UART 亙藁? * @note ?UART 憭𤥁挽𡝗𧋦賣㺭憭銵?UART 憭𤥁挽滚虾靚
* @param[in] uart: UART 撖寡情
* @param[in] rx_callback: 交𤣰桐葉賣㺭
* @param[in] rx_idle_callback: 蝛粹𤦭銝剜鱏? * @param[in] dma_rx_callback: DMA 交𤣰銝剜鱏? * @param[in] dma_tx_callback: DMA 賣㺭
* @retval None
*/
void BSP_UART_Port_Init( struct UART_STRUCT *uart,
UART_Callback_t rx_callback,
UART_Callback_t rx_idle_callback,
UART_Callback_t dma_rx_callback,
UART_Callback_t dma_tx_callback)
{
BSP_UART_Port_LockInit(uart);
_UART_RxCallback = rx_callback;
_UART_RxIdleCallback = rx_idle_callback;
_UART_DMA_RxCallback = dma_rx_callback;
_UART_DMA_TxCallback = dma_tx_callback;
/**
* 敶?uart->handle 霈曄眏蝟餌𡝗𧒄嚗䔶憒?CubeMX 憪见嚗䔶誑銝贝雿𨀣糓敹? * 嚗屸䌊撌勗 uart->handle ? * 望迨嚗?BSP_UART_Port_Init ?UART 憭𤥁挽𡝗𧋦賣㺭憭銵?UART 憭𤥁挽滚虾靚? */
switch (uart->id)
{
#if (BSP_USING_UART1)
case BSP_UART1: uart->handle = UART1_HANDLE; break;
#endif
#if (BSP_USING_UART2)
case BSP_UART2: uart->handle = UART2_HANDLE; break;
#endif
#if (BSP_USING_UART2_RE)
case BSP_UART2_RE: uart->handle = UART2_HANDLE; break;
#endif
#if (BSP_USING_UART3)
case BSP_UART3: uart->handle = UART3_HANDLE; break;
#endif
#if (BSP_USING_UART3_RE)
case BSP_UART3_RE: uart->handle = UART3_HANDLE; break;
#endif
#if (BSP_USING_UART4)
case BSP_UART4: uart->handle = UART4_HANDLE; break;
#endif
#if (BSP_USING_UART5)
case BSP_UART5: uart->handle = UART5_HANDLE; break;
#endif
#if (BSP_USING_UART6)
case BSP_UART6: uart->handle = UART6_HANDLE; break;
#endif
default: break;
}
if (uart->handle.hdmatx)
uart->handle.hdmatx->Parent = &uart->handle;
/* Clean the input path */
__HAL_UART_FLUSH_DRREGISTER(&uart->handle);
}
/**
* @brief UART 亙藁帋縑? * @note
* @param[in] uart: UART 撖寡情
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_Port_LockInit(struct UART_STRUCT *uart)
{
return BSP_UART_ERR_OK;
}
/**
* @brief UART 蝑匧交𤣰唳旿
* @note
* @param[in] uart: UART 撖寡情
* @retval BSP_UART_ERR
*/
inline BSP_UART_ERR BSP_UART_Port_RxLock(struct UART_STRUCT *uart)
{
return BSP_UART_ERR_OK;
}
/**
* @brief UART 交𤣰唳㺭靽∪噡? * @note
* @param[in] uart: UART 撖寡情
* @retval BSP_UART_ERR
*/
inline BSP_UART_ERR BSP_UART_Port_RxUnlock(struct UART_STRUCT *uart)
{
return BSP_UART_ERR_OK;
}
/**
* @brief UART
* @note
* @param[in] uart: UART 撖寡情
* @retval BSP_UART_ERR
*/
inline BSP_UART_ERR BSP_UART_Port_TxLock(struct UART_STRUCT *uart)
{
return BSP_UART_ERR_OK;
}
/**
* @brief UART 瘥閗圾? * @note
* @param[in] uart: UART 撖寡情
* @retval BSP_UART_ERR
*/
inline BSP_UART_ERR BSP_UART_Port_TxUnlock(struct UART_STRUCT *uart)
{
return BSP_UART_ERR_OK;
}
/**
* @brief 雿輯 UART 交𤣰唳旿
* @note
* @param[in] uart: UART 撖寡情
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_Port_EnableReceive(struct UART_STRUCT *uart)
{
BSP_UART_ERR ret = BSP_UART_ERR_OK;
if (uart->handle.hdmarx)
uart->handle.hdmarx->Parent = &uart->handle;
_UART_Alternate(uart);
if (uart->handle.hdmarx)
ret = (BSP_UART_ERR)HAL_UART_Receive_DMA(&uart->handle, (uint8_t *)uart->rx_buff, uart->rx_buff_max_len);
else
__HAL_UART_ENABLE_IT(&uart->handle, UART_IT_RXNE);
/* 撘舐征脖葉?*/
__HAL_UART_ENABLE_IT(&uart->handle, UART_IT_IDLE);
return ret;
}
/**
* @brief 蝳迫 UART 交𤣰唳旿
* @note
* @param[in] uart: UART 撖寡情
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_Port_DisableReceive(struct UART_STRUCT *uart)
{
BSP_UART_ERR ret = BSP_UART_ERR_OK;
if (uart->handle.hdmarx)
ret = (BSP_UART_ERR)HAL_UART_DMAPause(&uart->handle);
else
__HAL_UART_DISABLE_IT(&uart->handle, UART_IT_RXNE);
__HAL_UART_DISABLE_IT(&uart->handle, UART_IT_IDLE);
return ret;
}
/**
* @brief UART 撣扳㺭? * @note
* @param[in] uart: UART 撖寡情
* @param[in] data: 閬唳旿
* @param[in] len: 閬唳旿踹漲嚗雿?byte憭折鵭摨? 65535 byte
* @param[in] timeout: 憭批嗆𧒄 ms憭扳摰𡁏𧒄? 65535 ms
* @retval BSP_UART_ERR
*/
BSP_UART_ERR BSP_UART_Port_Send(struct UART_STRUCT *uart, const uint8_t *data, uint16_t len, uint16_t timeout)
{
_UART_Alternate(uart);
if (timeout == 0)
{
if (uart->handle.hdmatx)
return (BSP_UART_ERR)HAL_UART_Transmit_DMA(&uart->handle, (uint8_t *)data, len);
else
return (BSP_UART_ERR)HAL_UART_Transmit_IT(&uart->handle, (uint8_t *)data, len);
}
else
return (BSP_UART_ERR)HAL_UART_Transmit(&uart->handle, (uint8_t *)data, len, timeout);
}
/**
* @brief 隞?UART 銝芸唳旿
* @note
* @param[in] uart: UART 撖寡情
* @retval UART 唳旿
*/
inline uint32_t BSP_UART_Port_GetOneByte(struct UART_STRUCT *uart)
{
return uart->handle.Instance->DR;
}
/**
* @brief DMA 敶枏? * @note
* @param[in] uart: UART 撖寡情
* @retval 霈⊥㺭? */
inline uint32_t BSP_UART_Port_GetDmaCounter(struct UART_STRUCT *uart)
{
return __HAL_DMA_GET_COUNTER(uart->handle.hdmarx);
}
/**
* @brief UART ID UART 撖寡情
* @note
* @param[in] id: 銝脣藁 ID
* @retval NULL: ?ID NULL: UART 撖寡情
*/
struct UART_STRUCT *BSP_UART_Port_GetHandle(BSP_UART_ID id)
{
for (uint8_t i = 0; i < _uart_qty; i++)
{
if (_uart_group[i]->id == id)
{
return _uart_group[i];
}
}
return NULL;
}
/* Private functions ---------------------------------------------------------*/
/**
* @brief UART 銝剜鱏銝剖? * @note
* @param[in] uart: UART 撖寡情
* @retval None
*/
static inline void _UART_IntHandler(struct UART_STRUCT *uart)
{
if (uart->handle.Instance == NULL)
return;
if (__HAL_UART_GET_FLAG(&uart->handle, UART_FLAG_RXNE) != RESET)
{
/* RXNE 銝剜鱏雿滢刻粉?DR 撖瘜閧&摰?_UART_RxCallback 臬炏隡朞粉靝R撖
隞亙銁甇文餈𥡝甈⊥?*/
__HAL_UART_CLEAR_FLAG(&uart->handle, UART_FLAG_RXNE);
if (_UART_RxCallback)
_UART_RxCallback(uart);
}
else if ((__HAL_UART_GET_FLAG(&uart->handle, UART_FLAG_IDLE) != RESET)
&& (__HAL_UART_GET_IT_SOURCE(&uart->handle, UART_IT_IDLE) != RESET))
{
/* IDLE 銝剜鱏雿滚蘨質蔓隞嗆?*/
__HAL_UART_CLEAR_IDLEFLAG(&uart->handle);
if (_UART_RxIdleCallback)
_UART_RxIdleCallback(uart);
}
else
{
HAL_UART_IRQHandler(&(uart->handle));
}
}
/**
* @brief 銝脣藁憭滨鍂賣㺭
* @note
* @param[in] uart: UART 撖寡情
* @retval None
*/
static inline void _UART_Alternate(struct UART_STRUCT *uart)
{
#if (BSP_USING_UART2_RE || BSP_USING_UART3_RE)
switch (uart->id)
{
case BSP_UART2:
case BSP_UART2_RE:
{
if (_uart2_alter != uart->id) /* 憭滨鍂揢 */
{
if (uart->id == BSP_UART2)
{
BSP_GPIO_SetMode(GET_PIN(A, 2), GPIO_MODE_AF_PP, GPIO_PULLUP); /* TX */
BSP_GPIO_SetMode(GET_PIN(A, 3), GPIO_MODE_INPUT, GPIO_PULLUP); /* RX */
__HAL_AFIO_REMAP_USART2_DISABLE();
}
else
{
BSP_GPIO_SetMode(GET_PIN(D, 5), GPIO_MODE_AF_PP, GPIO_PULLUP); /* TX */
BSP_GPIO_SetMode(GET_PIN(D, 6), GPIO_MODE_INPUT, GPIO_PULLUP); /* RX */
__HAL_AFIO_REMAP_USART2_ENABLE();
}
_uart2_alter = uart->id;
}
break;
}
case BSP_UART3:
case BSP_UART3_RE:
{
if (_uart3_alter != uart->id) /* 憭滨鍂揢 */
{
if (uart->id == BSP_UART3)
{
BSP_GPIO_SetMode(GET_PIN(B, 10), GPIO_MODE_AF_PP, GPIO_PULLUP); /* TX */
BSP_GPIO_SetMode(GET_PIN(B, 11), GPIO_MODE_INPUT, GPIO_PULLUP); /* RX */
__HAL_AFIO_REMAP_USART3_DISABLE();
}
else
{
BSP_GPIO_SetMode(GET_PIN(D, 8), GPIO_MODE_AF_PP, GPIO_PULLUP); /* TX */
BSP_GPIO_SetMode(GET_PIN(D, 9), GPIO_MODE_INPUT, GPIO_PULLUP); /* RX */
__HAL_AFIO_REMAP_USART3_ENABLE();
}
_uart3_alter = uart->id;
}
break;
}
default: break;
}
#endif
}
/* Callback functions ---------------------------------------------------------*/
/* 隞乩 4 銝芸遆?HAL 摨?UART 剖遆賣㺭 */
/* UART DMA 交𤣰𦠜說銝剜鱏 */
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
{
struct UART_STRUCT *uart = (struct UART_STRUCT *)huart;
if (_UART_DMA_RxCallback)
_UART_DMA_RxCallback(uart);
}
/* UART DMA 交𤣰冽說銝剜鱏 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
struct UART_STRUCT *uart = (struct UART_STRUCT *)huart;
if (_UART_DMA_RxCallback)
_UART_DMA_RxCallback(uart);
}
/* UART DMA 𣂷葉?*/
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
struct UART_STRUCT *uart = (struct UART_STRUCT *)huart;
if (_UART_DMA_TxCallback)
_UART_DMA_TxCallback(uart);
}
/* UART 銝剜鱏璉瘚见躰秤?*/
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
struct UART_STRUCT *uart = (struct UART_STRUCT *)huart;
//printf("%s: %d %d\r\n", __FUNCTION__, uart->id, huart->ErrorCode);
}
/* Interrupt request functions ---------------------------------------------------------*/
#if (BSP_USING_UART1)
void USART1_IRQHandler(void)
{
BSP_INT_ENTER();
_UART_IntHandler(&UART(1));
BSP_INT_EXIT();
}
void UART1_DMA_RX_IRQHandler(void)
{
BSP_INT_ENTER();
if (UART(1).rx_init)
{
HAL_DMA_IRQHandler(UART(1).handle.hdmarx);
}
BSP_INT_EXIT();
}
void UART1_DMA_TX_IRQHandler(void)
{
BSP_INT_ENTER();
HAL_DMA_IRQHandler(UART(1).handle.hdmatx);
BSP_INT_EXIT();
}
#endif
#if (BSP_USING_UART2)
void USART2_IRQHandler(void)
{
BSP_INT_ENTER();
#if (BSP_USING_UART2_RE)
if (_uart2_alter == BSP_UART2)
_UART_IntHandler(&UART(2));
else
_UART_IntHandler(&UART(2_RE));
#else
_UART_IntHandler(&UART(2));
#endif
BSP_INT_EXIT();
}
void UART2_DMA_RX_IRQHandler(void)
{
BSP_INT_ENTER();
if (UART(2).rx_init)
{
#if (BSP_USING_UART2_RE)
if (_uart2_alter == BSP_UART2)
HAL_DMA_IRQHandler(UART(2).handle.hdmarx);
else
HAL_DMA_IRQHandler(UART(2_RE).handle.hdmarx);
#else
HAL_DMA_IRQHandler(UART(2).handle.hdmarx);
#endif
}
BSP_INT_EXIT();
}
void UART2_DMA_TX_IRQHandler(void)
{
BSP_INT_ENTER();
#if (BSP_USING_UART2_RE)
if (_uart2_alter == BSP_UART2)
HAL_DMA_IRQHandler(UART(2).handle.hdmatx);
else
HAL_DMA_IRQHandler(UART(2_RE).handle.hdmarx);
#else
HAL_DMA_IRQHandler(UART(2).handle.hdmarx);
#endif
BSP_INT_EXIT();
}
#endif
#if (BSP_USING_UART3)
void USART3_IRQHandler(void)
{
BSP_INT_ENTER();
#if (BSP_USING_UART3_RE)
if (_uart3_alter == BSP_UART3)
_UART_IntHandler(&UART(3));
else
_UART_IntHandler(&UART(3_RE));
#else
_UART_IntHandler(&UART(3));
#endif
BSP_INT_EXIT();
}
void UART3_DMA_RX_IRQHandler(void)
{
BSP_INT_ENTER();
if (UART(3).rx_init)
{
#if (BSP_USING_UART3_RE)
if (_uart3_alter == BSP_UART3)
HAL_DMA_IRQHandler(UART(3).handle.hdmarx);
else
HAL_DMA_IRQHandler(UART(3_RE).handle.hdmarx);
#else
HAL_DMA_IRQHandler(UART(3).handle.hdmarx);
#endif
}
BSP_INT_EXIT();
}
void UART3_DMA_TX_IRQHandler(void)
{
BSP_INT_ENTER();
#if (BSP_USING_UART3_RE)
if (_uart3_alter == BSP_UART3)
HAL_DMA_IRQHandler(UART(3).handle.hdmarx);
else
HAL_DMA_IRQHandler(UART(3_RE).handle.hdmarx);
#else
HAL_DMA_IRQHandler(UART(3).handle.hdmarx);
#endif
BSP_INT_EXIT();
}
#endif
#if (BSP_USING_UART4)
void UART4_IRQHandler(void)
{
BSP_INT_ENTER();
_UART_IntHandler(&UART(4));
BSP_INT_EXIT();
}
void UART4_DMA_RX_IRQHandler(void)
{
BSP_INT_ENTER();
if (UART(4).rx_init)
{
HAL_DMA_IRQHandler(UART(4).handle.hdmarx);
}
BSP_INT_EXIT();
}
void UART4_DMA_TX_IRQHandler(void)
{
BSP_INT_ENTER();
HAL_DMA_IRQHandler(UART(4).handle.hdmatx);
BSP_INT_EXIT();
}
#endif
#if (BSP_USING_UART5)
void UART5_IRQHandler(void)
{
BSP_INT_ENTER();
_UART_IntHandler(&UART(5));
BSP_INT_EXIT();
}
void UART5_DMA_RX_IRQHandler(void)
{
BSP_INT_ENTER();
if (UART(5).rx_init)
{
HAL_DMA_IRQHandler(UART(5).handle.hdmarx);
}
BSP_INT_EXIT();
}
void UART5_DMA_TX_IRQHandler(void)
{
BSP_INT_ENTER();
HAL_DMA_IRQHandler(UART(5).handle.hdmatx);
BSP_INT_EXIT();
}
#endif
#if (BSP_USING_UART6)
void USART6_IRQHandler(void)
{
BSP_INT_ENTER();
_UART_IntHandler(&UART(6));
BSP_INT_EXIT();
}
void UART6_DMA_RX_IRQHandler(void)
{
BSP_INT_ENTER();
if (UART(6).rx_init)
{
HAL_DMA_IRQHandler(UART(6).handle.hdmarx);
}
BSP_INT_EXIT();
}
void UART6_DMA_TX_IRQHandler(void)
{
BSP_INT_ENTER();
HAL_DMA_IRQHandler(UART(6).handle.hdmatx);
BSP_INT_EXIT();
}
#endif
+82
View File
@@ -0,0 +1,82 @@
#ifndef __INCLUDES_H__
#define __INCLUDES_H__
/* 配置文件 */
#include "app_config.h"
/* 用户库 */
#include "main.h"
/* 工具库 */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
/* Component */
#if (CONFIG_DECRYPT)
#include "aes.h"
#endif
//! \note for IAR
#ifdef __IS_COMPILER_IAR__
# undef __IS_COMPILER_IAR__
#endif
#if defined(__IAR_SYSTEMS_ICC__)
# define __IS_COMPILER_IAR__ 1
#endif
//! \note for arm compiler 5
#ifdef __IS_COMPILER_ARM_COMPILER_5__
# undef __IS_COMPILER_ARM_COMPILER_5__
#endif
#if ((__ARMCC_VERSION >= 5000000) && (__ARMCC_VERSION < 6000000))
# define __IS_COMPILER_ARM_COMPILER_5__ 1
#endif
//! @}
//! \note for arm compiler 6
#ifdef __IS_COMPILER_ARM_COMPILER_6__
# undef __IS_COMPILER_ARM_COMPILER_6__
#endif
#if ((__ARMCC_VERSION >= 6000000) && (__ARMCC_VERSION < 7000000))
# define __IS_COMPILER_ARM_COMPILER_6__ 1
#endif
#ifdef __IS_COMPILER_ARM_COMPILER__
# undef __IS_COMPILER_ARM_COMPILER__
#endif
#if defined(__IS_COMPILER_ARM_COMPILER_5__) && __IS_COMPILER_ARM_COMPILER_5__ \
|| defined(__IS_COMPILER_ARM_COMPILER_6__) && __IS_COMPILER_ARM_COMPILER_6__
# define __IS_COMPILER_ARM_COMPILER__ 1
#endif
#ifdef __IS_COMPILER_LLVM__
# undef __IS_COMPILER_LLVM__
#endif
#if defined(__clang__) && !__IS_COMPILER_ARM_COMPILER_6__
# define __IS_COMPILER_LLVM__ 1
#else
//! \note for gcc
#ifdef __IS_COMPILER_GCC__
# undef __IS_COMPILER_GCC__
#endif
#if defined(__GNUC__) && !(__IS_COMPILER_ARM_COMPILER_6__ || __IS_COMPILER_LLVM__)
# define __IS_COMPILER_GCC__ 1
#endif
//! @}
#endif
//! @}
#if (ENABLE_ASSERT)
extern void Assert_Failed(uint8_t *func, uint32_t line);
#define ASSERT(expr) ((expr) ? (void)0U : Assert_Failed((uint8_t *)__func__, __LINE__))
#else
#define ASSERT(expr) ((void)0U)
#endif
#endif
+130
View File
@@ -0,0 +1,130 @@
#include "drv_timer.h"
static struct drv_timer_t *timerHead;
void drv_timer_start (struct drv_timer_t *timer)
{
ASSERT(timer != NULL);
timer->start = 1;
}
void drv_timer_restart (struct drv_timer_t *timer)
{
ASSERT(timer != NULL);
timer->start = 0;
timer->time_temp = 0;
timer->period = timer->period_temp;
timer->start = 1;
}
void drv_timer_pause (struct drv_timer_t *timer)
{
ASSERT(timer != NULL);
timer->start = 0;
timer->time_temp = 0;
return;
}
void drv_timer_detach (struct drv_timer_t *timer)
{
struct drv_timer_t **now_target;
struct drv_timer_t *entry;
ASSERT(timer != NULL);
for (now_target = &timerHead; *now_target; ) {
entry = *now_target;
if (entry == timer) {
*now_target = entry->next;
return;
} else {
now_target = &entry->next;
}
}
return;
}
static void drv_timer_attach (struct drv_timer_t *timer)
{
struct drv_timer_t *target;
for (target = timerHead; target != NULL; target = target->next) {
if (target == timer) {
return;
}
}
timer->next = timerHead;
timerHead = timer;
}
// call in tick interrupt
void drv_timer_handler (uint8_t ms)
{
struct drv_timer_t *timer;
for (timer = timerHead; timer != NULL; timer = timer->next) {
if (timer->start) {
timer->time_temp += ms;
if (timer->time_temp >= timer->timeout) {
timer->time_temp = 0;
if ((timer->type & TIMER_TYPE_HARDWARE) != 0) {
if (timer->timerCallback) {
timer->timerCallback(timer->user_data);
}
if ((timer->type & TIMER_ONE_SHOT) != 0) {
--timer->period;
if (timer->period == 0) {
drv_timer_pause(timer);
}
}
} else {
timer->timeout_flag = 1;
}
}
}
}
}
void drv_timer_linkUserData (struct drv_timer_t *timer, void *user_data)
{
ASSERT(timer != NULL);
timer->user_data = user_data;
}
void drv_timer_init (struct drv_timer_t *timer,
void (*timerCallback)(void *user_data),
uint32_t timeout,
uint16_t period)
{
ASSERT(timer != NULL);
timer->period = period;
timer->timeout = timeout;
timer->type = TIMER_TYPE_HARDWARE;
timer->timerCallback = timerCallback;
timer->time_temp = 0;
timer->period_temp = period;
if (period == 0) {
timer->type |= TIMER_PERIODIC;
} else {
timer->type |= TIMER_ONE_SHOT;
}
drv_timer_attach(timer);
}
+58
View File
@@ -0,0 +1,58 @@
#ifndef __DRV_TIMER_H__
#define __DRV_TIMER_H__
#include "bsp_common.h"
#define TIMER_RUN_FOREVER 0
#define TIMER_RUN_ONE_SHOT 1
#define TIMER_ONE_SHOT (0x04)
#define TIMER_PERIODIC (0x08)
typedef enum {
TIMER_TYPE_HARDWARE = (0x01), // 硬件 timer ,实时性较强,定时精度较高,占用中断时间
TIMER_TYPE_SOFTWARE = (0x02) // 软件 timer ,实时性较差,定时精度较差,不占用中断时间
} eTIMERTYPE;
struct drv_timer_t {
void (*timerCallback)(void *user_data);
void *user_data;
eTIMERTYPE type; // 类型 bit3:持续 bit2:单次 bit1:软件 bit0:硬件
uint8_t start :1;
uint8_t timeout_flag :1;
uint8_t :0;
uint16_t period; // 执行次数
uint16_t period_temp; // 暂存执行次数, 用于重置
uint32_t timeout; // 计时,单位为 ms
uint32_t time_temp; // 计时计数
struct drv_timer_t *next;
};
extern void drv_timer_start (struct drv_timer_t *timer);
extern void drv_timer_restart (struct drv_timer_t *timer);
extern void drv_timer_pause (struct drv_timer_t *timer);
extern void drv_timer_detach (struct drv_timer_t *timer);
extern void drv_timer_handler (uint8_t ms);
extern void drv_timer_linkUserData (struct drv_timer_t *timer, void *user_data);
extern void drv_timer_init (struct drv_timer_t *timer,
void (*timerCallback)(void *user_data),
uint32_t timeout,
uint16_t period);
#endif /* __DRV_TIMER_H__ */