first commit for chrg
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user