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__ */
+569
View File
@@ -0,0 +1,569 @@
/*
This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode.
Block size can be chosen in aes.h - available choices are AES128, AES192, AES256.
The implementation is verified against the test vectors in:
National Institute of Standards and Technology Special Publication 800-38A 2001 ED
ECB-AES128
----------
plain-text:
6bc1bee22e409f96e93d7e117393172a
ae2d8a571e03ac9c9eb76fac45af8e51
30c81c46a35ce411e5fbc1191a0a52ef
f69f2445df4f9b17ad2b417be66c3710
key:
2b7e151628aed2a6abf7158809cf4f3c
resulting cipher
3ad77bb40d7a3660a89ecaf32466ef97
f5d3d58503b9699de785895a96fdbaaf
43b1cd7f598ece23881b00e3ed030688
7b0c785e27e8ad3f8223207104725dd4
NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
You should pad the end of the string with zeros if this is not the case.
For AES192/256 the key size is proportionally larger.
*/
/*****************************************************************************/
/* Includes: */
/*****************************************************************************/
#include <string.h> // CBC mode, for memset
#include "aes.h"
/*****************************************************************************/
/* Defines: */
/*****************************************************************************/
// The number of columns comprising a state in AES. This is a constant in AES. Value=4
#define Nb 4
#if defined(AES256) && (AES256 == 1)
#define Nk 8
#define Nr 14
#elif defined(AES192) && (AES192 == 1)
#define Nk 6
#define Nr 12
#else
#define Nk 4 // The number of 32 bit words in a key.
#define Nr 10 // The number of rounds in AES Cipher.
#endif
// jcallan@github points out that declaring Multiply as a function
// reduces code size considerably with the Keil ARM compiler.
// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3
#ifndef MULTIPLY_AS_A_FUNCTION
#define MULTIPLY_AS_A_FUNCTION 0
#endif
/*****************************************************************************/
/* Private variables: */
/*****************************************************************************/
// state - array holding the intermediate results during decryption.
typedef uint8_t state_t[4][4];
// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
// The numbers below can be computed dynamically trading ROM for RAM -
// This can be useful in (embedded) bootloader applications, where ROM is often limited.
static const uint8_t sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
static const uint8_t rsbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
// The round constant word array, Rcon[i], contains the values given by
// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
static const uint8_t Rcon[11] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
/*
* Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12),
* that you can remove most of the elements in the Rcon array, because they are unused.
*
* From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
*
* "Only the first some of these constants are actually used up to rcon[10] for AES-128 (as 11 round keys are needed),
* up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
*/
/*****************************************************************************/
/* Private functions: */
/*****************************************************************************/
/*
static uint8_t getSBoxValue(uint8_t num)
{
return sbox[num];
}
*/
#define getSBoxValue(num) (sbox[(num)])
/*
static uint8_t getSBoxInvert(uint8_t num)
{
return rsbox[num];
}
*/
#define getSBoxInvert(num) (rsbox[(num)])
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
{
unsigned i, j, k;
uint8_t tempa[4]; // Used for the column/row operations
// The first round key is the key itself.
for (i = 0; i < Nk; ++i)
{
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
}
// All other round keys are found from the previous round keys.
for (i = Nk; i < Nb * (Nr + 1); ++i)
{
{
k = (i - 1) * 4;
tempa[0]=RoundKey[k + 0];
tempa[1]=RoundKey[k + 1];
tempa[2]=RoundKey[k + 2];
tempa[3]=RoundKey[k + 3];
}
if (i % Nk == 0)
{
// This function shifts the 4 bytes in a word to the left once.
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
// Function RotWord()
{
const uint8_t u8tmp = tempa[0];
tempa[0] = tempa[1];
tempa[1] = tempa[2];
tempa[2] = tempa[3];
tempa[3] = u8tmp;
}
// SubWord() is a function that takes a four-byte input word and
// applies the S-box to each of the four bytes to produce an output word.
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
tempa[0] = tempa[0] ^ Rcon[i/Nk];
}
#if defined(AES256) && (AES256 == 1)
if (i % Nk == 4)
{
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
}
#endif
j = i * 4; k=(i - Nk) * 4;
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
}
}
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
{
KeyExpansion(ctx->RoundKey, key);
}
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
{
KeyExpansion(ctx->RoundKey, key);
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
{
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
#endif
// This function adds the round key to state.
// The round key is added to the state by an XOR function.
static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey)
{
uint8_t i,j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
}
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void SubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxValue((*state)[j][i]);
}
}
}
// The ShiftRows() function shifts the rows in the state to the left.
// Each row is shifted with different offset.
// Offset = Row number. So the first row is not shifted.
static void ShiftRows(state_t* state)
{
uint8_t temp;
// Rotate first row 1 columns to left
temp = (*state)[0][1];
(*state)[0][1] = (*state)[1][1];
(*state)[1][1] = (*state)[2][1];
(*state)[2][1] = (*state)[3][1];
(*state)[3][1] = temp;
// Rotate second row 2 columns to left
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to left
temp = (*state)[0][3];
(*state)[0][3] = (*state)[3][3];
(*state)[3][3] = (*state)[2][3];
(*state)[2][3] = (*state)[1][3];
(*state)[1][3] = temp;
}
static uint8_t xtime(uint8_t x)
{
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
}
// MixColumns function mixes the columns of the state matrix
static void MixColumns(state_t* state)
{
uint8_t i;
uint8_t Tmp, Tm, t;
for (i = 0; i < 4; ++i)
{
t = (*state)[i][0];
Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
}
}
// Multiply is used to multiply numbers in the field GF(2^8)
// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary
// The compiler seems to be able to vectorize the operation better this way.
// See https://github.com/kokke/tiny-AES-c/pull/34
#if MULTIPLY_AS_A_FUNCTION
static uint8_t Multiply(uint8_t x, uint8_t y)
{
return (((y & 1) * x) ^
((y>>1 & 1) * xtime(x)) ^
((y>>2 & 1) * xtime(xtime(x))) ^
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
}
#else
#define Multiply(x, y) \
( ((y & 1) * x) ^ \
((y>>1 & 1) * xtime(x)) ^ \
((y>>2 & 1) * xtime(xtime(x))) ^ \
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
#endif
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced.
// Please use the references to gain more information.
static void InvMixColumns(state_t* state)
{
int i;
uint8_t a, b, c, d;
for (i = 0; i < 4; ++i)
{
a = (*state)[i][0];
b = (*state)[i][1];
c = (*state)[i][2];
d = (*state)[i][3];
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void InvSubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
}
}
}
static void InvShiftRows(state_t* state)
{
uint8_t temp;
// Rotate first row 1 columns to right
temp = (*state)[3][1];
(*state)[3][1] = (*state)[2][1];
(*state)[2][1] = (*state)[1][1];
(*state)[1][1] = (*state)[0][1];
(*state)[0][1] = temp;
// Rotate second row 2 columns to right
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to right
temp = (*state)[0][3];
(*state)[0][3] = (*state)[1][3];
(*state)[1][3] = (*state)[2][3];
(*state)[2][3] = (*state)[3][3];
(*state)[3][3] = temp;
}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
// Cipher is the main function that encrypts the PlainText.
static void Cipher(state_t* state, const uint8_t* RoundKey)
{
uint8_t round = 0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(0, state, RoundKey);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr rounds are executed in the loop below.
// Last one without MixColumns()
for (round = 1; ; ++round)
{
SubBytes(state);
ShiftRows(state);
if (round == Nr) {
break;
}
MixColumns(state);
AddRoundKey(round, state, RoundKey);
}
// Add round key to last round
AddRoundKey(Nr, state, RoundKey);
}
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
static void InvCipher(state_t* state, const uint8_t* RoundKey)
{
uint8_t round = 0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(Nr, state, RoundKey);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr rounds are executed in the loop below.
// Last one without InvMixColumn()
for (round = (Nr - 1); ; --round)
{
InvShiftRows(state);
InvSubBytes(state);
AddRoundKey(round, state, RoundKey);
if (round == 0) {
break;
}
InvMixColumns(state);
}
}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
/*****************************************************************************/
/* Public functions: */
/*****************************************************************************/
#if defined(ECB) && (ECB == 1)
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call encrypts the PlainText with the Key using AES algorithm.
Cipher((state_t*)buf, ctx->RoundKey);
}
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call decrypts the PlainText with the Key using AES algorithm.
InvCipher((state_t*)buf, ctx->RoundKey);
}
#endif // #if defined(ECB) && (ECB == 1)
#if defined(CBC) && (CBC == 1)
static void XorWithIv(uint8_t* buf, const uint8_t* Iv)
{
uint8_t i;
for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
{
buf[i] ^= Iv[i];
}
}
void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, uint32_t length)
{
uintptr_t i;
uint8_t *Iv = ctx->Iv;
for (i = 0; i < length; i += AES_BLOCKLEN)
{
XorWithIv(buf, Iv);
Cipher((state_t*)buf, ctx->RoundKey);
Iv = buf;
buf += AES_BLOCKLEN;
}
/* store Iv in ctx for next call */
memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
}
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
{
uintptr_t i;
uint8_t storeNextIv[AES_BLOCKLEN];
for (i = 0; i < length; i += AES_BLOCKLEN)
{
memcpy(storeNextIv, buf, AES_BLOCKLEN);
InvCipher((state_t*)buf, ctx->RoundKey);
XorWithIv(buf, ctx->Iv);
memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
buf += AES_BLOCKLEN;
}
}
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
{
uint8_t buffer[AES_BLOCKLEN];
unsigned i;
int bi;
for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
{
if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
{
memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
Cipher((state_t*)buffer,ctx->RoundKey);
/* Increment Iv and handle overflow */
for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
{
/* inc will overflow */
if (ctx->Iv[bi] == 255)
{
ctx->Iv[bi] = 0;
continue;
}
ctx->Iv[bi] += 1;
break;
}
bi = 0;
}
buf[i] = (buf[i] ^ buffer[bi]);
}
}
#endif // #if defined(CTR) && (CTR == 1)
+1180
View File
File diff suppressed because it is too large Load Diff
+862
View File
@@ -0,0 +1,862 @@
#include "firmware.h"
static uint8_t _fw_start_write_flag; /* 固件开始写入的标志位 */
static uint16_t _update_progress; /* 固件更新的进度, 10000 制 */
static uint16_t _update_progress_step_num; /* 固件更新进度的步进单位 */
static uint16_t _storage_data_size; /* 固件包写入时记录暂存的固件分包大小,单位 byte */
static uint32_t _write_part_addr; /* 固件包写入时记录写入 flash 的相对地址 */
static uint16_t _write_last_pkg_size; /* 固件包写入时最后一个分包的大小,单位 byte */
static uint8_t _fw_first_bytes[CONFIG_WRITE_BYTES_LEASET]; /* 固件包的前几个字节 */
static uint8_t _upk_min_handle_buff[UPK_LEAST_HANDLE_BYTE]; /* upk 固件最小处理单位的缓存区,多次使用以降低系统资源开销 */
static struct upk_head_t upkHdr; /* 用于存放 upk 固件包头 */
#if (CONFIG_DECRYPT)
static struct AES_ctx aesCtx; /* AES 对象 */
#endif
static struct BSP_FLASH _flash_app_part; /* APP 分区 */
#if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION)
static struct BSP_FLASH _flash_download_part; /* download 分区 */
#if (CONFIG_CHIP_PARTS == USE_TRIPLE_PARTITION)
static struct BSP_FLASH _flash_factory_part; /* factory 分区 */
#endif
#endif
/* Extern function prototypes ------------------------------------------------*/
extern void Firmware_OperateCallback(uint16_t progress);
/* Private function prototypes -----------------------------------------------*/
static eErrCode _Write_FirmwareSubPackage( const struct BSP_FLASH *part,
uint8_t *data,
uint16_t pkg_size,
uint8_t decrypt,
FM_FIRMWARE_WRITE_DIR write_dir);
static void _Reset_Write(void);
/* Exported functions ---------------------------------------------------------*/
/**
* @brief 初始化接口
* @note
* @retval None
*/
void FM_Init (void)
{
BSP_Flash_Init(&_flash_app_part, NAME_PART_APPLICATION, BASE_APPLICATION, SIZE_PART_APPLICATION);
#if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION)
BSP_Flash_Init(&_flash_download_part, NAME_PART_DOWNLOAD, BASE_DOWNLOAD, SIZE_PART_DOWNLOAD);
#if (CONFIG_CHIP_PARTS > USE_DOUBLE_PARTITION)
BSP_Flash_Init(&_flash_factory_part, NAME_PART_FACTORY, BASE_FACTORY, SIZE_PART_FACTORY);
#endif
#endif
printf("onchip size : 0x%lX\r\n", SIZE_ONCHIP_FLASH);
printf("0x%08lX+0x%lX 'parameters'.\r\n", BASE_PARAMETERS, SIZE_PART_PARAMETERS);
printf("0x%08X+0x%X 'app'.\r\n", _flash_app_part.addr, _flash_app_part.len);
#if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION)
printf("0x%08X+0x%X 'download'.\r\n", _flash_download_part.addr, _flash_app_part.len);
#if (CONFIG_CHIP_PARTS > USE_DOUBLE_PARTITION)
printf("0x%08X+0x%X 'factory'.\r\n", _flash_factory_part.addr, _flash_app_part.len);
#endif
#endif
#if (CONFIG_DECRYPT)
AES_init_ctx_iv(&aesCtx, (uint8_t *)AES256_KEY, (uint8_t *)AES256_IV);
#endif
}
/**
* @brief 固件包是否有加密
* @note 调用前需确保 upkHdr 已经读入了数据
* @retval 0: 未加密。1: 有加密
*/
inline uint8_t FM_IsEncrypt(void)
{
/* 读取加密选项 */
if (upkHdr.config[1] == 0x01)
return 1;
return 0;
}
/**
* @brief 检测某个分区是否为空
* @note ERR_OK: 分区数据空
* @param[in] part_name: 分区名
* @retval eErrCode
*/
eErrCode FM_IsEmpty(const char *part_name)
{
int read_len = 0;
uint16_t i = 0;
uint16_t need_read_size = UPK_LEAST_HANDLE_BYTE;
uint32_t *p_data = (uint32_t *)_upk_min_handle_buff;
uint32_t read_posit = 0;
ASSERT(part_name != NULL);
const struct BSP_FLASH *part = NULL;
part = BSP_Flash_GetHandle(part_name);
if (part == NULL) {
printf("%s: '%s' not found.\r\n", __func__, part_name);
return ERR_NO_THIS_PART;
}
for (read_posit = 0; read_posit < part->len; ) {
if ((part->len - read_posit) < UPK_LEAST_HANDLE_BYTE) {
need_read_size = part->len - read_posit;
}
read_len = BSP_Flash_Read(part, read_posit, _upk_min_handle_buff, need_read_size);
if (read_len < 0) {
printf("%s: read error (%d).\r\n", __func__, __LINE__);
return ERR_READ_IS_EMPTY_ERR;
}
for (i = 0; i < (UPK_LEAST_HANDLE_BYTE / sizeof(p_data)); i++) {
if (p_data[i] != 0xFFFFFFFF) {
printf("part '%s' not empty.\r\n", part_name);
return ERR_FLASH_NO_EMPTY;
}
}
read_posit += read_len;
}
//printf("%s: '%s' part empty.\r\n", __func__, part_name);
return ERR_OK;
}
/**
* @brief 获取固件包的固件版本
* @note 调用前需确保 upkHdr 已经读入了数据
* @retval 固件新版本
*/
inline char * FM_GetNewFirmwareVersion(void)
{
return upkHdr.fw_new_ver;
}
/**
* @brief 获取源固件的 CRC32 值
* @note 调用前需确保 upkHdr 已经读入了数据
* @retval 源固件的 CRC32 值
*/
inline uint32_t FM_GetRawCRC32(void)
{
return upkHdr.raw_crc;
}
/**
* @brief 暂存固件包头
* @note 会同时校验固件包头
* @param[in] part_name: 分区名
* @param[in] data: 数据
* @retval eErrCode
*/
eErrCode FM_StorageFirmwareHead(const char *part_name, uint8_t *data)
{
uint32_t head_crc = 0xFFFFFFFF;
uint8_t *pHdr = (uint8_t *)&upkHdr;
ASSERT(part_name != NULL);
ASSERT(data != NULL);
_Reset_Write();
memcpy(pHdr, data, UPK_HEAD_SIZE);
#if (!CONFIG_DECRYPT)
/* 若固件包加密,检查是否有解密组件 */
if (FM_IsEncrypt()) {
printf("%s: no decrypt component\r\n", __func__);
return ERR_NO_DECRYPT_COMPONENT;
}
#endif
const struct BSP_FLASH *part = NULL;
part = BSP_Flash_GetHandle(part_name);
if (part == NULL) {
printf("%s: not found.\r\n", __func__);
return ERR_NO_THIS_PART;
}
//printf("%s: '%s' part.\r\n", __func__, part_name);
if (strncmp(upkHdr.name, "upk", sizeof("upk")) != 0) {
return ERR_FAULT_FIRMWARE;
}
if ((upkHdr.pkg_size > part->len)
|| (upkHdr.raw_size > part->len)) {
return ERR_FIRMWARE_OVERSIZE;
}
head_crc = crc32_step(head_crc, pHdr, UPK_HEAD_SIZE - 4);
if (head_crc != upkHdr.head_crc) {
printf("%s: head crc verify failed. (%.8X - %.8X)\r\n", __func__, upkHdr.head_crc, head_crc);
return ERR_FIRMWARE_HEAD_VERIFY_ERR;
}
printf("\n\r--------------------\n\r");
printf("head: \t\t%s\n\r", upkHdr.name);
printf("config: \t%d %d %d %d\n\r", upkHdr.config[0], upkHdr.config[1], upkHdr.config[2], upkHdr.config[3]);
printf("old_ver: \t%d.%d.%d.%d\n\r", upkHdr.fw_old_ver[0], upkHdr.fw_old_ver[1], upkHdr.fw_old_ver[2], upkHdr.fw_old_ver[3]);
printf("new_ver: \t%d.%d.%d.%d\n\r", upkHdr.fw_new_ver[0], upkHdr.fw_new_ver[1], upkHdr.fw_new_ver[2], upkHdr.fw_new_ver[3]);
printf("string: \t%s\n\r",upkHdr.user_string);
printf("partition: \t%s\n\r", upkHdr.part_name);
printf("raw_size: \t%d\n\r", upkHdr.raw_size);
printf("pkg_size: \t%d\n\r", upkHdr.pkg_size);
printf("timestamp: \t%d\n\r", upkHdr.timestamp);
printf("raw_crc: \t%.8X\n\r", upkHdr.raw_crc);
printf("pkg_crc: \t%.8X\n\r", upkHdr.pkg_crc);
printf("head_crc: \t%.8X\n\r", upkHdr.head_crc);
printf("--------------------\n\r");
/* 计算固件更新进度的最小单位,降低过程计算量,无更新进度需求可删除 */
_update_progress_step_num = upkHdr.pkg_size / UPK_LEAST_HANDLE_BYTE;
_update_progress_step_num += upkHdr.pkg_size % UPK_LEAST_HANDLE_BYTE;
_update_progress_step_num = 10000 / _update_progress_step_num;
//printf("%s: progress unit: %d\r\n", __func__, _update_progress_step_num);
return ERR_OK;
}
/**
* @brief 校验已放置在分区的固件包的包体数据的正确性
* @note 一般要先校验包头,注意各分区包体的偏移地址有区别
* @param[in] part_name: 分区名称
* @param[in] crc32: 需进行比对的 CRC32 校验值
* @param[in] is_auto_fill: 是否自动填充固件的首地址数据
* @retval eErrCode
*/
eErrCode FM_VerifyFirmware (const char *part_name, uint32_t crc32, uint8_t is_auto_fill)
{
int read_len = 0;
uint8_t app_part_flag = 0;
uint32_t pkg_size = 0;
uint32_t body_crc = 0xFFFFFFFF;
uint32_t read_posit = 0;
uint32_t read_posit_temp = 0;
uint16_t need_read_size = UPK_LEAST_HANDLE_BYTE;
#if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION)
uint8_t first_flag = 0;
#endif
ASSERT(part_name != NULL);
#if (!CONFIG_DECRYPT)
/* 若固件包加密,检查是否有解密组件 */
if (FM_IsEncrypt()) {
printf("%s: no decrypt component\r\n", __func__);
return ERR_NO_DECRYPT_COMPONENT;
}
#endif
if (strncmp(part_name, NAME_PART_APPLICATION, MAX_NAME_LEN) == 0) {
app_part_flag = 1;
}
const struct BSP_FLASH *part = NULL;
part = BSP_Flash_GetHandle(part_name);
if (part == NULL) {
printf("%s: not found.\r\n", part_name);
return ERR_NO_THIS_PART;
}
hex_printf((uint8_t *)&upkHdr, UPK_HEAD_SIZE);
printf("--------------------\n\r");
printf("head: \t\t%s\n\r", upkHdr.name);
printf("config: \t%d %d %d %d\n\r", upkHdr.config[0], upkHdr.config[1], upkHdr.config[2], upkHdr.config[3]);
printf("old_ver: \t%d.%d.%d.%d\n\r", upkHdr.fw_old_ver[0], upkHdr.fw_old_ver[1], upkHdr.fw_old_ver[2], upkHdr.fw_old_ver[3]);
printf("new_ver: \t%d.%d.%d.%d\n\r", upkHdr.fw_new_ver[0], upkHdr.fw_new_ver[1], upkHdr.fw_new_ver[2], upkHdr.fw_new_ver[3]);
printf("string: \t%s\n\r",upkHdr.user_string);
printf("partition: \t%s\n\r", upkHdr.part_name);
printf("raw_size: \t%d\n\r", upkHdr.raw_size);
printf("pkg_size: \t%d\n\r", upkHdr.pkg_size);
printf("timestamp: \t%d\n\r", upkHdr.timestamp);
printf("raw_crc: \t%.8X\n\r", upkHdr.raw_crc);
printf("pkg_crc: \t%.8X\n\r", upkHdr.pkg_crc);
printf("head_crc: \t%.8X\n\r", upkHdr.head_crc);
printf("--------------------\n\r");
if (app_part_flag) {
pkg_size = upkHdr.raw_size;
} else {
pkg_size = upkHdr.pkg_size;
}
/* 校验固件包体的数据正确性 */
for (; read_posit < pkg_size; ) {
/* 剩余的数据数小于最小处理单位时,按剩余字节数处理 */
if ((pkg_size - read_posit) < UPK_LEAST_HANDLE_BYTE) {
need_read_size = pkg_size - read_posit;
}
/* 非 APP 分区,需要偏移包头的地址才是包体 */
if (app_part_flag) {
read_posit_temp = read_posit;
} else {
read_posit_temp = read_posit + UPK_HEAD_SIZE;
}
read_len = BSP_Flash_Read(part, read_posit_temp, _upk_min_handle_buff, need_read_size);
if (read_len < 0) {
printf("%s: read error (%d).\r\n", __func__, __LINE__);
return ERR_VERIFY_READ_ERR;
}
#if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION)
if (is_auto_fill) {
if (first_flag == 0) {
first_flag = 1;
for (uint8_t i = 0; i < CONFIG_WRITE_BYTES_LEASET; i++) {
_upk_min_handle_buff[i] = _fw_first_bytes[i];
}
}
}
#endif
body_crc = crc32_step(body_crc, _upk_min_handle_buff, read_len);
read_posit += read_len;
}
if (body_crc != crc32) {
printf("%s: '%s' body crc verify failed. (%08X vs %08X)\r\n", __func__, part_name, crc32, body_crc);
if (app_part_flag) {
return ERR_RAW_BODY_VERIFY_ERR;
} else {
return ERR_PKG_BODY_VERIFY_ERR;
}
}
return ERR_OK;
}
/**
* @brief 擦除某个分区的固件
* @note
* @param[in] part_name: 分区名称
* @retval eErrCode
*/
eErrCode FM_EraseFirmware(const char *part_name)
{
ASSERT(part_name != NULL);
const struct BSP_FLASH *part = NULL;
part = BSP_Flash_GetHandle(part_name);
if (part == NULL)
{
printf("%s: not found %s part.\r\n", __func__, part_name);
return ERR_NO_THIS_PART;
}
if (BSP_Flash_Erase(part, 0, part->len) < 0)
{
printf("%s: %s part erase failed.\r\n", __func__, part_name);
return ERR_ERASE_PART_ERR;
}
return ERR_OK;
}
/**
* @brief 固件写入分区的最终阶段,将分区首地址的几个字节数据写入 flash
* @note 程序调用 _Write_FirmwareSubPackage 函数时已暂存进 _fw_first_bytes
* @param[in] part_name: 分区名称
* @retval eErrCode
*/
eErrCode FM_WriteFirmwareDone (const char *part_name)
{
ASSERT(part_name != NULL);
const struct BSP_FLASH *part = NULL;
part = BSP_Flash_GetHandle(part_name);
if (part == NULL) {
printf("%s: not found part.\r\n", __func__);
return ERR_NO_THIS_PART;
}
if (BSP_Flash_Write(part, 0, _fw_first_bytes, CONFIG_WRITE_BYTES_LEASET) < 0) {
printf("%s: write error (%d).\r\n", __func__, __LINE__);
return ERR_WRITE_FIRST_ADDR_ERR;
}
_Reset_Write();
Firmware_OperateCallback(10000);
return ERR_OK;
}
/**
* @brief 将固件分包按顺序写入分区
* @note 由于固件包头已经写入,这里写入的是固件包体,需要注意在 flash 的偏移位置
* @param[in] part_name: 分区名称
* @param[in] data: 数据包
* @param[in] pkg_size: 数据包大小,单位 byte
* @retval eErrCode
*/
eErrCode FM_WriteFirmwareSubPackage(const char *part_name, uint8_t *data, uint16_t pkg_size)
{
ASSERT(part_name != NULL);
ASSERT(data != NULL);
ASSERT(pkg_size != 0);
const struct BSP_FLASH *part = NULL;
part = BSP_Flash_GetHandle(part_name);
if (part == NULL)
{
printf("%s: not found %s part.\r\n", __func__, part_name);
return ERR_NO_THIS_PART;
}
printf(",");
#if (CONFIG_CHIP_PARTS == USE_SINGLE_PARTITION)
uint8_t decrypt = 0;
/* 读取加密选项 */
decrypt = FM_IsEncrypt();
return _Write_FirmwareSubPackage(part, data, pkg_size, decrypt, FM_DIR_HOST_TO_APP); /* 写入前解密 */
#else
return _Write_FirmwareSubPackage(part, data, pkg_size, 0, FM_DIR_HOST_TO_DOWNLOAD); /* 写入前不解密 */
#endif
}
/**
* @brief 检查固件的完整性
* @note 通过首地址数据最后写入的机制,判断首地址 4 个字节是否有正确的数据
* @param[in] addr: 分区首地址
* @retval eErrCode
*/
eErrCode FM_CheckFirmwareIntegrity(uint32_t addr)
{
uint32_t value = *(volatile uint32_t *)addr;
eErrCode fw_integrity = ERR_JUMP_TO_APP_ERR;
printf("\r\nvalue = 0x%08X @ offset 0x%.8X", value, addr);
if (BASE_APPLICATION == addr) {
fw_integrity = ((value & 0x2FF00000) == 0x20000000) ? ERR_OK : ERR_JUMP_TO_APP_ERR;
}
#if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION)
else if ((BASE_DOWNLOAD == addr)||(BASE_FACTORY == addr)) {
if (UPK_IDENTIFIER == value) {
fw_integrity = ERR_OK;
}
}
#endif
return fw_integrity;
}
#if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION)
/**
* @brief 判断是否要进行固件自动更新
* @note 调用前需确保 upkHdr 已经读入了数据
* @retval 0: 无须更新。1: 需自动更新
*/
uint8_t FM_IsNeedAutoUpdate(void)
{
#if (CONFIG_AUTO_UPDATE_MODE == MODE_APPEND_TO_APP)
const struct BSP_FLASH *part = NULL;
part = BSP_Flash_GetHandle(NAME_PART_APPLICATION);
if (part == NULL) {
printf("%s: not found app part.\r\n", __func__);
return ERR_NO_THIS_PART;
}
if (BSP_Flash_Read(part, (SIZE_PART_APPLICATION - UPK_VERSION_SIZE), (uint8_t *)&upkHdr.fw_old_ver[0], UPK_VERSION_SIZE) < 0)
{
printf("%s: read error.\r\n", __func__);
return ERR_READ_VER_ERR;
}
#endif
printf("fw old ver: V%d.%d.%d.%d\r\n", upkHdr.fw_old_ver[0], upkHdr.fw_old_ver[1], upkHdr.fw_old_ver[2], upkHdr.fw_old_ver[3]);
printf("fw new ver: V%d.%d.%d.%d\r\n", upkHdr.fw_new_ver[0], upkHdr.fw_new_ver[1], upkHdr.fw_new_ver[2], upkHdr.fw_new_ver[3]);
if (upkHdr.fw_old_ver[0] != upkHdr.fw_new_ver[0]
|| upkHdr.fw_old_ver[1] != upkHdr.fw_new_ver[1]
|| upkHdr.fw_old_ver[2] != upkHdr.fw_new_ver[2]
|| upkHdr.fw_old_ver[3] != upkHdr.fw_new_ver[3]) {
printf("Need to update.\r\n");
return 1;
}
return 0;
}
/**
* @brief 获取当前操作的固件包的分区名称
* @note 调用前需确保 upkHdr 已经读入了数据
* @retval 分区名称
*/
inline char * FM_GetPartName(void)
{
return upkHdr.part_name;
}
/**
* @brief 获取旧的固件版本,即 APP 分区正在运行的固件版本
* @note 调用前需确保 upkHdr 已经读入了数据
* @retval 固件旧版本
*/
inline char * FM_GetOldFirmwareVersion(void)
{
return upkHdr.fw_old_ver;
}
/**
* @brief 获取打包后固件的 CRC32 值
* @note 调用前需确保 upkHdr 已经读入了数据
* @retval 打包后固件的CRC32值
*/
inline uint32_t FM_GetPackageCRC32(void)
{
return upkHdr.pkg_crc;
}
/**
* @brief 将分区内的固件包头读出
* @note 读出后的数据将放在 upkHdr 中
* @param[in] part_name: 分区名称
* @retval eErrCode
*/
eErrCode FM_ReadFirmwareHead(const char *part_name)
{
ASSERT(part_name != NULL);
_Reset_Write();
const struct BSP_FLASH *part = NULL;
part = BSP_Flash_GetHandle(part_name);
if (part == NULL)
{
printf("%s: not found.\r\n", __func__);
return ERR_NO_THIS_PART;
}
if (BSP_Flash_Read(part, 0, (uint8_t *)&upkHdr, UPK_HEAD_SIZE) < 0)
{
printf("%s: read error.\r\n", __func__);
return ERR_READ_FIRMWARE_HEAD_ERR;
}
return ERR_OK;
}
/**
* @brief 从某个分区将固件包更新至 APP 分区
* @note 读取 -> 解密 -> 写入
* @param[in] from_part_name: 放置需要更新至 APP 分区的固件包的分区
* @retval eErrCode
*/
eErrCode FM_UpdateToAPP(const char *from_part_name)
{
int read_len = 0;
uint8_t decrypt = 0;
uint32_t read_posit = 0;
uint32_t write_posit = 0;
uint32_t need_read_size = UPK_LEAST_HANDLE_BYTE;
eErrCode result = ERR_OK;
ASSERT(from_part_name != NULL);
const struct BSP_FLASH *app_part = NULL;
const struct BSP_FLASH *firmware_part = NULL;
app_part = BSP_Flash_GetHandle(NAME_PART_APPLICATION);
if (app_part == NULL) {
printf("%s: not found.\r\n", __func__);
return ERR_NO_THIS_PART;
}
firmware_part = BSP_Flash_GetHandle(from_part_name);
if (firmware_part == NULL) {
printf("%s: not found %s part.\r\n", __func__, from_part_name);
return ERR_NO_THIS_PART;
}
_Reset_Write();
printf("part '%s' write to 'app'.\r\n", from_part_name);
/* 读取加密选项 */
decrypt = FM_IsEncrypt();
for (write_posit = 0; write_posit < upkHdr.pkg_size; ) {
if ((upkHdr.pkg_size - read_posit) < UPK_LEAST_HANDLE_BYTE) {
need_read_size = upkHdr.pkg_size - read_posit;
}
read_len = BSP_Flash_Read(firmware_part, (read_posit + UPK_HEAD_SIZE), _upk_min_handle_buff, need_read_size);
if (read_len < 0) {
printf("%s: read error (%d).\r\n", __func__, __LINE__);
return ERR_UPDATE_READ_ERR;
}
result = _Write_FirmwareSubPackage(app_part, _upk_min_handle_buff, read_len, decrypt, FM_DIR_DOWNLOAD_TO_APP);
if (result) {
printf("%s: write error (%d).\r\n", __func__, __LINE__);
return result;
}
read_posit += read_len;
write_posit += read_len;
}
return ERR_OK;
}
#if (CONFIG_AUTO_UPDATE_MODE == MODE_UPDATE_DOWNLOAD_HEAD)
/**
* @brief 更新固件包中的版本信息
* @note
* @param[in] part_name: 分区名称
* @retval eErrCode
*/
eErrCode FM_UpdateFirmwareVersion(const char *part_name)
{
ASSERT(part_name != NULL);
#if (ONCHIP_FLASH_ERASE_GRANULARITY > UPK_LEAST_HANDLE_BYTE)
#error "erase granularity oversize than _upk_min_handle_buff array"
#endif
/* 将 download 分区首地址的数据读出,长度为片内 flash 最小擦除粒度 */
const struct BSP_FLASH *part = NULL;
part = BSP_Flash_GetHandle(part_name);
if (part == NULL)
{
printf("%s: not found.\r\n", __func__);
return ERR_NO_THIS_PART;
}
printf("%s: part name: %s\r\n", __func__, part_name);
if (BSP_Flash_Read(part, 0, &_upk_min_handle_buff[0], ONCHIP_FLASH_ERASE_GRANULARITY) < 0)
{
printf("%s: read error.\r\n", __func__);
return ERR_UPDATE_VER_READ_ERR;
}
/* 修改固件包头中旧版本字段的版本信息为新的固件版本 */
struct upk_head_t *p_pkg_head = (struct upk_head_t *)&_upk_min_handle_buff[0];
p_pkg_head->fw_old_ver[0] = p_pkg_head->fw_new_ver[0];
p_pkg_head->fw_old_ver[1] = p_pkg_head->fw_new_ver[1];
p_pkg_head->fw_old_ver[2] = p_pkg_head->fw_new_ver[2];
p_pkg_head->fw_old_ver[3] = p_pkg_head->fw_new_ver[3];
/* 将读出数据的区域擦除 */
if (BSP_Flash_Erase(part, 0, ONCHIP_FLASH_ERASE_GRANULARITY) < 0)
{
printf("%s: %s part erase failed.\r\n", __func__, part_name);
return ERR_UPDATE_VER_ERASE_ERR;
}
/* 将新的数据写入擦除的区域 */
if (BSP_Flash_Write(part, 0, &_upk_min_handle_buff[0], ONCHIP_FLASH_ERASE_GRANULARITY) < 0)
{
printf("%s: write error (%d).\r\n", __func__, __LINE__);
return ERR_UPDATE_VER_WRITE_ERR;
}
memcpy((uint8_t *)&upkHdr, &_upk_min_handle_buff[0], UPK_HEAD_SIZE);
printf("fw old ver: V%d.%d.%d.%d\r\n", p_pkg_head->fw_old_ver[0], p_pkg_head->fw_old_ver[1], p_pkg_head->fw_old_ver[2], p_pkg_head->fw_old_ver[3]);
printf("fw new ver: V%d.%d.%d.%d\r\n", p_pkg_head->fw_new_ver[0], p_pkg_head->fw_new_ver[1], p_pkg_head->fw_new_ver[2], p_pkg_head->fw_new_ver[3]);
return ERR_OK;
}
#elif (CONFIG_AUTO_UPDATE_MODE == MODE_APPEND_TO_APP)
/**
* @brief 更新固件包中的版本信息
* @note
* @param[in] part_name: 分区名称
* @retval eErrCode
*/
eErrCode FM_UpdateFirmwareVersion(const char *part_name)
{
const struct BSP_FLASH *part = NULL;
part = BSP_Flash_GetHandle(NAME_PART_APPLICATION);
if (part == NULL)
{
printf("%s: not found APP part.\r\n", __func__);
return ERR_NO_THIS_PART;
}
if (BSP_Flash_Read(part, (SIZE_PART_APPLICATION - UPK_VERSION_SIZE), (uint8_t *)&upkHdr.fw_old_ver[0], UPK_VERSION_SIZE) < 0)
{
printf("%s: read error.\r\n", __func__);
return ERR_READ_VER_ERR;
}
if (upkHdr.fw_old_ver[0] != 0xFF
|| upkHdr.fw_old_ver[1] != 0xFF
|| upkHdr.fw_old_ver[2] != 0xFF
|| upkHdr.fw_old_ver[3] != 0xFF)
{
printf("%s: version area no erase.\r\n", __func__);
return ERR_VER_AREA_NO_ERASE;
}
if (BSP_Flash_Write(part, (SIZE_PART_APPLICATION - UPK_VERSION_SIZE), (uint8_t *)&upkHdr.fw_new_ver[0], UPK_VERSION_SIZE) < 0)
{
printf("%s: write error.\r\n", __func__);
return ERR_WRITE_VER_ERR;
}
return ERR_OK;
}
#endif /* #if (CONFIG_AUTO_UPDATE_MODE == MODE_UPDATE_DOWNLOAD_HEAD) */
#endif /* #if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION) */
/* Private functions ---------------------------------------------------------*/
/**
* @brief 复位写固件的一些记录信息
* @note
* @retval None
*/
static void _Reset_Write(void)
{
_fw_start_write_flag = 0; /* 固件开始写入的标志位 */
_update_progress = 0; /* 固件更新的进度, 10000 制 */
_storage_data_size = 0; /* 固件包写入时记录暂存的固件分包大小,单位 byte */
_write_part_addr = 0; /* 固件包写入时记录写入 flash 的相对地址 */
_write_last_pkg_size = 0; /* 固件包写入时最后一个分包的大小,单位 byte */
}
uint32_t wcrc32 = 0xFFFFFFFF;
uint32_t wlen = 0;
/**
* @brief 将固件分包按顺序写入某个分区
* @note 循环调用本函数,无须指定写入地址,函数内部自行记录已写入的大小
* @param[in] part: 分区对象
* @param[in] data: 数据
* @param[in] pkg_size: 数据大小,单位 byte
* @param[in] decrypt: 0: 固件包无加密。1: 固件包有加密
* @retval eErrCode
*/
static eErrCode _Write_FirmwareSubPackage( const struct BSP_FLASH *part,
uint8_t *data,
uint16_t pkg_size,
uint8_t decrypt,
FM_FIRMWARE_WRITE_DIR write_dir)
{
uint8_t *fw_4096byte_buff = data;
/* 主机直接下发的固件分包不满 UPK_LEAST_HANDLE_BYTE 个字节,需要先暂存至满足后再写入 */
if (write_dir == FM_DIR_HOST_TO_APP) {
fw_4096byte_buff = &_upk_min_handle_buff[0];
/* 判断是否是最后一个包 */
if (_storage_data_size == 0) {
if (upkHdr.pkg_size - _write_part_addr < UPK_LEAST_HANDLE_BYTE)
{
/* 最后一个固件分包的标志 */
_write_last_pkg_size = upkHdr.pkg_size - _write_part_addr;
printf("_write_last_pkg_size : %d\r\n", _write_last_pkg_size);
}
}
/* 小于最小处理单位时,暂存 */
if (_storage_data_size < UPK_LEAST_HANDLE_BYTE) {
memcpy(&fw_4096byte_buff[_storage_data_size], data, pkg_size);
_storage_data_size += pkg_size;
if (_write_last_pkg_size) {
if (_storage_data_size < _write_last_pkg_size) {
return ERR_OK;
}
} else if (_storage_data_size < UPK_LEAST_HANDLE_BYTE) {
return ERR_OK;
}
}
}
/* 从 download 或 factory 更新至 APP ,因可以直接读取 UPK_LEAST_HANDLE_BYTE 个字节,所以无须暂存 */
else {
if (_fw_start_write_flag == 0) {
wlen = upkHdr.pkg_size;
_storage_data_size = pkg_size;
} else {
if (wlen >= pkg_size) {
wlen -= pkg_size;
_storage_data_size = pkg_size;
} else {
_storage_data_size = wlen;
}
}
}
#if (CONFIG_DECRYPT)
if (decrypt) {
AES_CBC_decrypt_buffer(&aesCtx, fw_4096byte_buff, _storage_data_size);
}
#endif
/* 保存首地址的几个字节数据,等待最后写入 */
if (_fw_start_write_flag == 0) {
for (uint8_t i = 0; i < CONFIG_WRITE_BYTES_LEASET; i++) {
_fw_first_bytes[i] = fw_4096byte_buff[i];
}
fw_4096byte_buff += CONFIG_WRITE_BYTES_LEASET;
_storage_data_size -= CONFIG_WRITE_BYTES_LEASET;
_write_part_addr = CONFIG_WRITE_BYTES_LEASET;
}
if (BSP_Flash_Write(part, _write_part_addr, fw_4096byte_buff, _storage_data_size) < 0) {
printf("%s: write error (%d) 0x%08X + 0x%08X, len %d.\r\n", __func__, __LINE__,
part->addr,_write_part_addr, _storage_data_size);
_Reset_Write();
return ERR_WRITE_PART_ERR;
}
if (_storage_data_size!=92) {
wcrc32 = crc32_step(wcrc32, fw_4096byte_buff, _storage_data_size);
}
_write_part_addr += _storage_data_size;
_storage_data_size = 0;
_fw_start_write_flag = 1;
_update_progress += _update_progress_step_num;
Firmware_OperateCallback(_update_progress);
return ERR_OK;
}
+47
View File
@@ -0,0 +1,47 @@
/**
* 此文件用于关闭 semihosting
*/
#include "common.h"
/* 告诉编译器若没有使用 MicroLIB ,则 main() 函数不需要入口参数 */
#if __IS_COMPILER_ARM_COMPILER_6__
#ifndef __MICROLIB
__asm(".global __ARM_use_no_argv\n\t");
#endif
#endif
/* 关闭 semihosting */
#if __IS_COMPILER_ARM_COMPILER_6__
__asm(".global __use_no_semihosting");
/* AC6 会因为关闭 semihosting 缺这个函数,所以要补上 */
void _sys_exit(int ret)
{
(void)ret;
while(1) {}
}
#elif __IS_COMPILER_ARM_COMPILER_5__
#pragma import(__use_no_semihosting)
#endif
/* AC5 和 AC6 都会因为关闭 semihosting 缺这个函数,所以要补上 */
#if __IS_COMPILER_ARM_COMPILER__
void _ttywrch(int ch)
{
(void)ch;
}
#endif
/* 当使用 AC6 开启 MicroLIB 时,若有使用 assert() 的需求,需要自己实现 __aeabi_assert() */
#if __IS_COMPILER_ARM_COMPILER_6__ && defined(__MICROLIB)
void __aeabi_assert(const char *chCond, const char *chLine, int wErrCode)
{
(void)chCond;
(void)chLine;
(void)wErrCode;
while(1) {
__NOP();
}
}
#endif
+100
View File
@@ -0,0 +1,100 @@
#include "transfer.h"
#if (DT_ENABLE_BROKEN_FRAME_DETECT)
static uint8_t timeo_frame = 0;
static struct drv_timer_t timerFrameBroken;
static void timerFrameBrokenCallback (void *user_data)
{
timeo_frame = 1;
//printf("frame detect clock time up!\r\n");
}
#endif
static uint8_t DT_Port_IsRecvData (struct transfer_t *xfer)
{
#if (DT_ENABLE_BROKEN_FRAME_DETECT)
if (timeo_frame) {
timeo_frame = 0;
return BSP_UART_ERR_OK;
} else if (BSP_UART_IsFrameEnd((BSP_UART_ID)xfer->if_id) == BSP_UART_ERR_OK) {
drv_timer_linkUserData(&timerFrameBroken, xfer);
drv_timer_restart(&timerFrameBroken);
return BSP_UART_ERR_NO_RECV_FRAME;
}
return BSP_UART_ERR_NO_RECV_FRAME;
#else
return BSP_UART_IsFrameEnd((BSP_UART_ID)xfer->if_id);
#endif
}
void DT_Send (struct transfer_t *xfer, uint8_t *data, uint32_t len)
{
BSP_UART_Send((BSP_UART_ID)xfer->if_id, data, len, 0xFFFF);
}
/**
* @brief 检测是否接收到一帧数据的轮询接口
* @note
* @param[in] xfer: 传输控制块对象
* @retval exRESULT
*/
exRESULT DT_PollingReceive (struct transfer_t *xfer)
{
exRESULT state = X_RESULT_NO_DATA;
if (DT_Port_IsRecvData(xfer) == 0) {
state = X_RESULT_RECV_FRAME;
}
return state;
}
/**
* @brief 数据传输层初始化
* @note
* @param[in] xfer: 传输控制块对象
* @param[in] if_id: 传输接口 ID
* @param[in] buff: 用于接收数据的缓冲池,单位 byte
* @param[in] len: 指示接收到的数据长度,单位 byte
* @param[in] buff_size: 数据池最大容量,单位 byte
* @retval None
*/
void DT_Init (struct transfer_t *xfer, uint8_t if_id, uint8_t *buff, uint16_t *len, uint32_t buff_size)
{
ASSERT(xfer != NULL);
xfer->if_id = if_id;
xfer->rx_buff = buff;
xfer->rx_len = len;
xfer->rx_buff_size = buff_size;
BSP_UART_Init((BSP_UART_ID)xfer->if_id);
BSP_UART_LinkUserData((BSP_UART_ID)xfer->if_id, xfer);
BSP_UART_EnableReceive( (BSP_UART_ID)xfer->if_id,
xfer->rx_buff,
xfer->rx_len,
xfer->rx_buff_size);
#if (DT_ENABLE_BROKEN_FRAME_DETECT)
drv_timer_init(&timerFrameBroken,
timerFrameBrokenCallback,
BROKEN_FRAME_INTERVAL_TIME,
TIMER_RUN_ONE_SHOT);
#endif
}
+104
View File
@@ -0,0 +1,104 @@
/* Includes ------------------------------------------------------------------*/
#include "utils.h"
#include "bsp_common.h"
const char Hex2Ascii[17] = "0123456789ABCDEF";
int hex_printf (const uint8_t *buff, int count)
{
uint32_t i = 0, j = 0;
char str_val[75] = {0};
uint32_t index = 0;
uint32_t str_index = 0;
uint32_t cnt = (count+15)>>4;
if (count < 0) {
return -1;
}
if (cnt > 16) {
cnt = 16;
//BSP_printf("!!! TOO LONG. ONLY SHOW HEAD 256 bytes !!!\n");
}
for (i = 0; i < cnt; i++) {
index = 0;
str_index = 0;
for (j = 0; j < 16; j++) {
if (j + (i << 4) < count) {
str_val[index++] = Hex2Ascii[(buff[j + (i << 4)] & 0xF0) >> 4];
str_val[index++] = Hex2Ascii[buff[j + (i << 4)] & 0xF];
str_val[index++] = ' ';
} else {
str_val[index++] = ' ';
str_val[index++] = ' ';
str_val[index++] = ' ';
}
}
index += str_index;
str_val[index++] = '\0';
str_val[index++] = '\0';
printf("%s\r\n", str_val);
}
return 0;
}
/******************************************************************************
* Name: CRC-16/XMODEM x16+x12+x5+1
* Poly: 0x1021
* Init: 0x0000
* Refin: False
* Refout: False
* Xorout: 0x0000
* Alias: CRC-16/ZMODEM,CRC-16/ACORN
*****************************************************************************/
uint16_t crc16_xmodem (uint8_t *data, uint16_t length)
{
uint8_t i;
uint16_t crc = 0; // Initial value
while(length--)
{
crc ^= (uint16_t)(*data++) << 8; // crc ^= (uint16_t)(*data)<<8; data++;
for (i = 0; i < 8; ++i)
{
if ( crc & 0x8000 )
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
}
return crc;
}
uint32_t crc32_step (uint32_t in_crc, const void *buf, uint32_t size)
{
static uint32_t crc_table[256] = {0, 0,};
uint32_t i = 0, j = 0, crc = 0;
if (!crc_table[1]) {
for (i = 0; i < 256; i++) {
crc = i;
for (j = 0; j < 8; j++) {
crc = (crc & 1) ? ((crc>>1)^0xEDB88320ul) : (crc>>1);
}
crc_table[i] = crc;
}
}
crc = in_crc ^ 0xFFFFFFFFul;
for (i = 0; i < size; i++) {
crc = crc_table[(crc ^ ((const uint8_t *)buf)[i]) & 0xFF]^(crc>>8);
}
return crc ^ 0xFFFFFFFFul;
}
+336
View File
@@ -0,0 +1,336 @@
#include "ymodem.h"
struct ymodem_info_t {
uint8_t isBusy; /* 正在处理主机数据的标志位 */
uint8_t enRecv; /* 使能接收主机的指令包 */
uint16_t rxLen; /* 接收到的数据长度 */
uint8_t *rxData; /* 协议解析的数据来源 */
uint8_t numPkt; /* 记录 YModem 协议的 packet number */
eYmFLOW flow; /* 记录协议的执行流程 */
union message_raw_t *msg; /* 接收主机数据包的缓存池,称为主机消息 */
struct tx_raw_t txPkt; /* 用于存放设备上发数据组包的部分参数 */
ymSend send; /* 数据发送接口 */
ymPrepareCallback prepare; /* 收到主机指令时的预备处理接口 */
ymReplyCallback reply; /* 正在执行指令时响应主机查询执行过程和结果的接口 */
};
static struct ymodem_info_t yM;
static struct drv_timer_t timerSendC; /* 用于定时向主机发送数据的定时器 */
static void timerSendCCallback (void *user_data)
{
static uint8_t c[1] = {YMODEM_C};
yM.send(c, 1, HAL_MAX_DELAY);
}
/**
* @brief 复位一些全局变量和标志信息
* @note
* @retval None
*/
static void ymodemReset (void)
{
yM.isBusy = 0;
yM.enRecv = 1;
yM.numPkt = 0;
yM.flow = YMODEM_FLOW_NONE;
}
/**
* @brief 对主机下发的心跳包的处理
* @note 对主机下发的数据帧进行回复, ymodem 没有心跳包,此处只是模拟
* @retval None
*/
static void ymodemHeartBeatProcess (void)
{
static eRESULT result;
yM.reply((eYmCMD)yM.msg->pkg.header, &result, NULL, NULL);
switch (result) {
case YM_RESULT_OK:
//yM.txPkt.response = YMODEM_ACK;
break;
case YM_RESULT_FAILED: {
/* 因前面已经加 1 ,此处是由于对数据处理有问题,非协议本身问题,因此需要减回 */
yM.numPkt--;
yM.txPkt.response = YMODEM_NAK;
break;
}
case YM_RESULT_CANCEL:
yM.txPkt.response = YMODEM_CAN;
break;
default:
/* 业务层还在处理数据,暂时不回复主机 */
return;
}
yM.isBusy = 0;
yM.send(&yM.txPkt.response, 1, HAL_MAX_DELAY);
}
/**
* @brief 对主机下发指令的处理
* @note
* @retval None
*/
static void ymodemCommandProcess (void)
{
uint16_t data_len = 0;
yM.isBusy = 1;
if ((yM.msg->pkg.header == YMODEM_SOH)||(yM.msg->pkg.header == YMODEM_STX)) {
data_len = yM.rxLen - YMODEM_FRAME_FIXED_LEN;
}
yM.prepare((eYmCMD)yM.msg->pkg.header, yM.msg->pkg.data, data_len);
}
/**
* @brief 设置协议执行流程
* @note
* @param[in] cmd: 主机的指令
* @retval eErrCode
*/
static eErrCode ymodemExeFlow (eYmCMD cmd)
{
switch (cmd) {
case YM_CMD_SOH: {
if (yM.flow == YMODEM_FLOW_NONE) { /* 第一个 SOH 数据帧 */
yM.flow = YMODEM_FLOW_START;
yM.txPkt.response = YMODEM_ACK;
} else if (yM.flow == YMODEM_FLOW_SECOND_EOT) { /* 最后一个空的 SOH 数据帧 */
drv_timer_pause(&timerSendC);
yM.flow = YMODEM_FLOW_SUCCESS;
yM.numPkt = 0;
yM.txPkt.response = YMODEM_ACK;
} else { /* 正在传输数据的 SOH 数据帧 */
/* 暂停发送字符“ C ”的定时器 */
drv_timer_pause(&timerSendC);
yM.txPkt.response = YMODEM_ACK;
}
break;
}
case YM_CMD_STX: {
/* 因为第一个有数据的数据帧可能是 STX ,因此此处有必要暂停发送字符“ C ”的定时器 */
drv_timer_pause(&timerSendC);
yM.txPkt.response = YMODEM_ACK;
break;
}
case YM_CMD_EOT: {
if (yM.flow == YMODEM_FLOW_START) { /* 第一个 EOT */
yM.flow = YMODEM_FLOW_FIRST_EOT;
yM.txPkt.response = YMODEM_NAK;
} else if (yM.flow == YMODEM_FLOW_FIRST_EOT) { /* 第二个 EOT */
yM.flow = YMODEM_FLOW_SECOND_EOT;
yM.numPkt = 0;
yM.txPkt.response = YMODEM_ACK;
/* 发完 ACK 需要继续发“ C ” */
drv_timer_restart(&timerSendC);
} else {
return ERR_EXE_FLOW;
}
break;
}
case YM_CMD_CAN: {
yM.flow = YMODEM_FLOW_CANCEL;
yM.txPkt.response = YMODEM_ACK;
break;
}
default:
break;
}
return ERR_OK;
}
/**
* @brief 协议解析处理函数
* @note 需要循环调用
* @retval eErrCode
*/
eErrCode ymodemHandler (uint8_t *data, uint16_t len)
{
eErrCode err_code;
/* 有数据 */
if (data && len && yM.enRecv) {
/* 暂存和格式化 */
yM.rxData = data;
yM.rxLen = len;
yM.msg = (union message_raw_t *)yM.rxData;
//hex_printf(data, len);
/* 只有数据帧才做以下错误检查 */
if (yM.msg->pkg.header == YMODEM_SOH || yM.msg->pkg.header == YMODEM_STX) {
/* 判断序列号是否符合顺序 */
if (yM.msg->pkg.pkt_num != yM.numPkt) {
if (yM.msg->pkg.pkt_num == (yM.numPkt - 1)) {
printf("error: duplicate frame %d %d\r\n", yM.msg->pkg.pkt_num, yM.numPkt);
err_code = ERR_DUPLICATE_FRAME;
} else {
printf("error: omission frame %d %d\r\n", yM.msg->pkg.pkt_num, yM.numPkt);
err_code = ERR_OMISSION_FRAME;
}
goto __error_exit;
}
/* 判断正反序列号是否正确 */
uint8_t pkt_num = ~(yM.msg->pkg.pkt_num);
if (yM.msg->pkg.not_pkt_num != pkt_num) {
printf("error: packet number: %.2X %.2X\r\n", yM.msg->pkg.pkt_num, yM.msg->pkg.not_pkt_num);
err_code = ERR_PKT_NUM_ERR;
goto __error_exit;
}
/* 获取协议帧中的数据字段长度 */
uint16_t data_len;
if (yM.msg->pkg.header == YMODEM_SOH) {
data_len = YMODEM_SOH_DATA_LEN;
} else if (yM.msg->pkg.header == YMODEM_STX) {
data_len = YMODEM_STX_DATA_LEN;
}
/* 帧长度判断 */
/* 奇怪的是, Xshell 在发送最后一个空 SOH 数据帧时会附加两个字节的 0x4F ,原因未知。
* 为了处理这个问题,避免误判为数据帧长度有误,此处嵌套了“ ymodem_pkt_num != 0 ”的判断 */
if (yM.numPkt != 0) {
if (yM.rxLen != (data_len + YMODEM_FRAME_FIXED_LEN)) {
//printf("error: _dev_rx_len: %d\r\n", yM.rxLen);
err_code = ERR_FRAME_LENGTH;
goto __error_exit;
}
}
/* 校验数据是否正确 */
uint16_t crc16 = crc16_xmodem(yM.msg->pkg.data, data_len);
printf("%04X", crc16);
uint16_t raw_crc16 = (yM.msg->pkg.data[data_len] << 8) | yM.msg->pkg.data[data_len + 1];
if (crc16 != raw_crc16) {
printf("error: crc16: %.4X\r\n", crc16);
printf("error: raw crc16: %.4X\r\n", raw_crc16);
err_code = ERR_FRAME_VERIFY_ERR;
goto __error_exit;
}
//printf("crc16 ok.\r\n");
/* 执行到此处记录序列号加1 */
yM.numPkt++;
}
//printf("Ymodem recv len: %d (%02X %02X %02X)\r\n",
// yM.rxLen, yM.msg->pkg.header, yM.msg->pkg.pkt_num, yM.msg->pkg.not_pkt_num);
/* 设置流程 */
if (ymodemExeFlow((eYmCMD)yM.msg->pkg.header)) {
//printf("error: flow illegal\r\n");
err_code = ERR_EXE_FLOW;
goto __error_exit;
}
/* 除了最后一个空的SOH数据帧,其他都会执行 ,包括 EOT CAN */
/* 需要注意是, 执行完后仍未回复主机,回复部分由 ymodemHeartBeatProcess 处理 */
ymodemCommandProcess();
return ERR_OK;
__error_exit:
yM.txPkt.response = YMODEM_NAK;
yM.send(&yM.txPkt.response, 1, HAL_MAX_DELAY);
return err_code;
}
if (yM.isBusy) {
/* 模拟主机的心跳处理,查询是否对协议包处理完毕,以向主机回复 */
ymodemHeartBeatProcess();
}
return ERR_OK;
}
/**
* @brief 配置协议析构层的参数
* @note
* @param[in] para: 需要进行配置的选型或参数
* @param[in] value: 对应的数据或值
* @retval None
*/
void ymodemConfig (eYmMODE mode, void *value)
{
switch (mode) {
case YM_MODE_RESET:
ymodemReset();
drv_timer_restart(&timerSendC);
break;
case YM_MODE_RECV: {
uint8_t *enable = (uint8_t *)value;
yM.enRecv = *enable;
if (yM.enRecv == 0) {
drv_timer_pause(&timerSendC);
}
break;
}
default:
break;
}
}
/**
* @brief 协议析构层的初始化
* @note
* @param[in] Send: 底层数据发送接口
* @param[in] HeartbeatCallback: 心跳包的响应接口
* @param[in] PrepareCallback: 指令包的处理接口
* @param[in] Set_ReplyInfo: 查询指令执行结果的处理接口
* @retval None
*/
void ymodem_init (ymSend Send,
ymPrepareCallback PrepareCallback,
ymReplyCallback Set_ReplyInfo)
{
yM.send = Send;
yM.prepare = PrepareCallback;
yM.reply = Set_ReplyInfo;
ymodemReset();
drv_timer_init(&timerSendC,
timerSendCCallback,
1000,
TIMER_RUN_FOREVER);
drv_timer_start(&timerSendC);
}
+90
View File
@@ -0,0 +1,90 @@
#ifndef _AES_H_
#define _AES_H_
#include <stdint.h>
// #define the macros below to 1/0 to enable/disable the mode of operation.
//
// CBC enables AES encryption in CBC-mode of operation.
// CTR enables encryption in counter-mode.
// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously.
// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
#ifndef CBC
#define CBC 1
#endif
#ifndef ECB
#define ECB 0
#endif
#ifndef CTR
#define CTR 0
#endif
//#define AES128 1
//#define AES192 1
#define AES256 1
#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only
#if defined(AES256) && (AES256 == 1)
#define AES_KEYLEN 32
#define AES_keyExpSize 240
#elif defined(AES192) && (AES192 == 1)
#define AES_KEYLEN 24
#define AES_keyExpSize 208
#else
#define AES_KEYLEN 16 // Key length in bytes
#define AES_keyExpSize 176
#endif
struct AES_ctx
{
uint8_t RoundKey[AES_keyExpSize];
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
uint8_t Iv[AES_BLOCKLEN];
#endif
};
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
#endif
#if defined(ECB) && (ECB == 1)
// buffer size is exactly AES_BLOCKLEN bytes;
// you need only AES_init_ctx as IV is not used in ECB
// NB: ECB is considered insecure for most uses
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf);
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf);
#endif // #if defined(ECB) && (ECB == !)
#if defined(CBC) && (CBC == 1)
// buffer size MUST be mutile of AES_BLOCKLEN;
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
// Same function for encrypting as for decrypting.
// IV is incremented for every block, and used after encryption as XOR-compliment for output
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#endif // #if defined(CTR) && (CTR == 1)
#endif // _AES_H_
+91
View File
@@ -0,0 +1,91 @@
#ifndef __APP_H__
#define __APP_H__
#include "firmware.h"
#include "ymodem.h"
#include "transfer.h"
#include "utils.h"
typedef enum {
EXE_FLOW_NOTHING = 0x00,
EXE_FLOW_ACCIDENT_UPDATE, /* 意外更新固件流程 */
EXE_FLOW_NEED_HOST_SEND_FIRMWARE, /* 需要主机下发固件包 */
EXE_FLOW_FIND_RUNNING_FIRMWARE, /* (0) 在各分区查找可运行的固件 */
EXE_FLOW_WAIT_FIRMWARE, /* 等待接收固件包 */
EXE_FLOW_VERIFY_FIRMWARE_HEAD, /* (1) 校验收到的固件包头 */
EXE_FLOW_ERASE_OLD_FIRMWARE, /* 擦除旧固件 */
EXE_FLOW_ERASE_OLD_FIRMWARE_DONE, /* 完成擦除旧固件 */
EXE_FLOW_WRITE_FIRMWARE_HEAD, /* 将固件包头写入 flash */
EXE_FLOW_WRITE_FIRMWARE_HEAD_DONE, /* 完成固件包头的写入 */
EXE_FLOW_VERIFY_FIRMWARE_PKG, /* (2) 校验固件分包数据的正确性 */
EXE_FLOW_WRITE_NEW_FIRMWARE, /* 写入新的固件分包到分区 */
EXE_FLOW_WRITE_NEW_FIRMWARE_DONE, /* 写入新的固件分包完成 */
EXE_FLOW_UPDATE_FIRMWARE, /* (3) 开始更新固件 */
EXE_FLOW_VERIFY_FIRMWARE, /* 校验整个固件包体的数据正确性 */
EXE_FLOW_VERIFY_FIRMWARE_DONE, /* 完成校验整个固件包体的数据正确性 */
EXE_FLOW_ERASE_APP, /* 擦除 APP 分区的固件 */
EXE_FLOW_UPDATE_TO_APP, /* 将其它分区的固件更新到 APP 分区 */
EXE_FLOW_VERIFY_APP, /* 校验 APP 分区固件的数据正确性 */
EXE_FLOW_UPDATE_TO_APP_DONE, /* 校验 APP 分区固件通过后,将剩余数据写入 */
EXE_FLOW_ERASE_DOWNLOAD, /* 擦除 download 分区 */
EXE_FLOW_ERASE_DOWNLOAD_DONE, /* 完成擦除 download 分区 */
EXE_FLOW_JUMP_TO_APP, /* 跳转至 APP 运行 */
EXE_FLOW_RECOVERY, /* 恢复出厂固件 */
EXE_FLOW_FAILED, /* 失败流程 */
} eFLOW;
/* 固件更新的缩略步骤,用于计算固件更新的进度 */
typedef enum {
STEP_VERIFY_FIRMWARE = 0x00, /* 校验接收到的固件包 */
STEP_ERASE_APP, /* 擦除 APP 分区 */
STEP_UPDATE_TO_APP, /* 更新固件包到 APP 分区 */
STEP_VERIFY_APP, /* 校验 APP 固件 */
STEP_ERASE_DOWNLOAD, /* 擦除 download 分区 */
} eSTAGE;
/* 应用状态 */
typedef enum {
BOOT_STATUS_NONE = 0x00,
BOOT_STATUS_NO_UPDATE, /* 无须更新固件的标志 */
BOOT_STATUS_ENTER_UPDATE_MODE, /* 进入固件更新模式的标志 */
BOOT_STATUS_ACCIDENT_UPDATE, /* 意外更新固件中 */
BOOT_STATUS_UPDATE_SUCCESS, /* 更新固件成功 */
BOOT_STATUS_UPDATE_FAILED, /* 更新固件失败 */
BOOT_STATUS_NO_FIRMWARE, /* 无任何可用固件 */
BOOT_STATUS_NO_APP, /* 无 APP 固件 */
BOOT_STATUS_READ_PART_ERR, /* 读取分区失败 */
BOOT_STATUS_APP_VERIFY_ERR, /* APP 固件校验错误 */
BOOT_STATUS_APP_CAN_NOT_VERIFY, /* APP 固件无法校验 */
BOOT_STATUS_AUTO_UPDATE_FAILED, /* 自动更新失败 */
} eSTATE;
struct upgrade_t {
eSTATE state; /* 记录 bootloader 所处的状态 */
eFLOW flow; /* 应用执行的流程 */
eSTAGE stage; /* 固件的更新阶段,便于程序判断 progress 的增加系数 */
eRESULT result; /* 指令执行结果 */
eErrCode errCode; /* 指令执行失败时的故障码 */
uint8_t start :1; /* 开始固件更新流程的标志 */
uint8_t :0;
uint8_t progress; /* 固件更新的总进度, 0-100 */
};
extern void System_Init (void);
extern void APP_Init (void);
extern void APP_Running (void);
#endif
+233
View File
@@ -0,0 +1,233 @@
#ifndef __APP_CONFIG_H__
#define __APP_CONFIG_H__
#define VERSION_MAIN 1
#define VERSION_SUB 0
#define VERSION_FIX 0
#define BOOT_VERSION ((VERSION_MAIN<<16)|(VERSION_SUB<<8)|VERSION_FIX)
#define BUILD_TIMESTAMP __DATE__", "__TIME__
#define NAME_PART_APPLICATION "app"
#define NAME_PART_DOWNLOAD "download"
#define NAME_PART_FACTORY "factory"
/** 配置各个分区的大小
需页对齐, 分区首地址必须是 Flash 的 每个独立 page 或 sector 的首地址,否则固件无法运行
*/
#if defined(STM32F405xx)
#define NAME_CHIP "STM32F405xx"
#define SIZE_ONCHIP_FLASH (1024 * 1024ul) // 片上 flash 总容量
#elif defined(STM32F411xE)
#define NAME_CHIP "STM32F411xE"
#define SIZE_ONCHIP_FLASH (512 * 1024ul)
#elif defined(STM32F401xC)
#define NAME_CHIP "STM32F401xC"
#define SIZE_ONCHIP_FLASH (256 * 1024ul)
#else
#error "no chip size defined"
#endif
#define SIZE_PART_BOOTLOADER (32 * 1024ul) // bootloader 占用空间(需要大于本程序bin大小)
#define SIZE_PART_PARAMETERS (32 * 1024ul) // 参数 占用空间
#define SIZE_PART_APPLICATION (SIZE_ONCHIP_FLASH/4) // app 占用空间 不少于1/4
#define SIZE_PART_DOWNLOAD (SIZE_PART_APPLICATION) // download 占用空间(不用时0)
#define SIZE_PART_FACTORY (SIZE_PART_APPLICATION) // factory 占用空间(不用时0)
#define BASE_ONCHIP_FLASH (FLASH_BASE) // on chip flash 首地址
#define OFFSET_ONCHIP_FLASH_END (BASE_ONCHIP_FLASH + SIZE_ONCHIP_FLASH)
/*
chipsize (256KB/512KB/1024KB) eg: 1024KB
32KB - bootloader = 0x00000 + 32*1024
32KB - parameter = 0x08000 + 32*1024
chipsize/2-64KB - application = 0x10000 + 448*1024
chipsize/4 - download = 0x80000 + 256*1024
chipsize/4 - factory = 0xC0000 + 256*1024
*/
#define BASE_BOOTLOADER (BASE_ONCHIP_FLASH)
#define BASE_PARAMETERS (BASE_BOOTLOADER + SIZE_PART_BOOTLOADER) // 参数分区起始地址
#define BASE_APPLICATION (BASE_ONCHIP_FLASH + SIZE_PART_BOOTLOADER+SIZE_PART_PARAMETERS) // app 分区起始地址
#define BASE_DOWNLOAD (BASE_ONCHIP_FLASH + SIZE_ONCHIP_FLASH/2) // download 分区起始地址
#define BASE_FACTORY (BASE_DOWNLOAD + SIZE_PART_DOWNLOAD) // factory 分区起始地址
/* 片上分区数量选项
* app: 可运行的固件区域
* download: 用于更新固件时的固件临时存放区域
* factory: 用于存放可在紧急情况下恢复固件使用的区域
*/
#define USE_SINGLE_PARTITION 0 // 单分区方案 仅 app
#define USE_DOUBLE_PARTITION 1 // 双分区方案 含 app + download
#define USE_TRIPLE_PARTITION 2 // 三分区方案 含 app + download + factory
#define CONFIG_CHIP_PARTS USE_TRIPLE_PARTITION
#define ENABLE_ASSERT 0 /* 是否使能函数入口参数检查 */
#define ENABLE_DEBUG_PRINT 1 /* 是否使能调试信息打印 */
#define MAX_NAME_LEN 8
// 本 bootloader 运行窗口最小时间
#define CONFIG_TIMEOUT_HOST_START (5*1000) // 设置等待主机数据的最大等待时间,单位 ms
#define CONFIG_DECRYPT 1
#if (CONFIG_DECRYPT)
// 以下同步给 upk 打包工具
#define AES256_KEY "0123456789ABCDEF0123456789ABCDEF" // 必须是 32 字节
#define AES256_IV "0123456789ABCDEF" // 必须是 16 字节
#endif
/* 判断固件包是否超过分区大小 */
#define CONFIG_CHECK_SIZE 1
/* 单次写入的最小字节数*/
#define CONFIG_WRITE_BYTES_LEASET 4
/* 自动更新固件的处理选项
* 1. 在固件更新过程中设备异常断电或重启后,选择是否自动更新已下载好的固件以及自动更新的处理方案
* 2. 该选项的执行优先级低于上位机更新的方式,这意味着除非上位机超时未发送数据,否则将会优先执行上位机的固件更新
*
* MODE_NOT_AUTO_UPDATE: 不需要自动更新,不希望有这种断电恢复固件的机制
* MODE_CLEAR_DOWNLOAD_PART: 更新完成后擦除 download 分区。设备上电时会通过检测 download 分区有无可用固件
* 以判断是否需要自动更新固件
* 选择此方案后,将无法选择是否在上电后对 APP 的固件进行安规校验( CONFIG_CHECK_APP_SECURITY )。
* 因为 APP 固件安规校验的数据来源是 download 分区的固件包。
* MODE_UPDATE_DOWNLOAD_HEAD: 更新完成后修改 download 分区的固件表头的版本信息。设备上电时会对比 download 分区固件包头记录的新旧版本,
* 若新旧版本不一致,则开始自动更新固件
* 此种方式需要修改 download 分区的数据,有以下优劣势:
* 1. 优势:上电时可校验 APP 分区的固件数据正确性和完整性,以提高 APP 固件有损坏或遭篡改时的安全性,甚至
* 可以将固件恢复正常,有效提高系统的安全等级
* 2. 劣势:需要对表头所在的 flash sector 擦除后再重新写入,这意味着每次更新都会擦除同个 sector 两次。
* MODE_APPEND_TO_APP: 更新完成后将新的固件版本写进 APP 分区的尾部,占用 16 byte ,设备上电时会对比 download 分区固件包头
* 记录的版本和 APP 存放的版本,若两个版本不一致,则开始自动更新固件
* 此种方式有以下优劣势:
* 1. 优势:上电时可校验 APP 分区的固件数据正确性和完整性,以提高 APP 固件有损坏或遭篡改时的安全性,甚至
* 可以将固件恢复正常,有效提高系统的安全等级
* 2. 劣势:需要占用 APP 分区 16 byte 的空间
*/
#define MODE_NOT_AUTO_UPDATE 0
#define MODE_CLEAR_DOWNLOAD_PART 1
#define MODE_UPDATE_DOWNLOAD_HEAD 2
#define MODE_APPEND_TO_APP 3
#if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION)
#define CONFIG_AUTO_UPDATE_MODE MODE_APPEND_TO_APP
#endif
/** 是否在上电后对 APP 的固件进行安规校验 及 APP 固件检查有问题时的操作
* 1. CONFIG_AUTO_UPDATE_MODE = MODE_UPDATE_DOWNLOAD_HEAD 时,本配置才会起效
* 2. 部分产品对固件的完整性有安规等级要求,本组件支持 APP 固件的数据完整性检查,通过配置以选择是否启用
* 3. 当启用时,通过配置 USING_APP_SAFETY_PROJECT 可选择 APP 固件检查有问题时的操作方案
* DO_NOT_CHECK : 不校验 APP 固件,即不启用
* CHECK_UNLESS_EMPTY: 校验 APP 固件,但无法校验时不校验,确保能运行 APP 而不至于等在 bootloader 中。若 APP 固件校验错误,将会
* 自动把可用和正确的固件更新至 APP
* * 无法进行 APP 固件校验的情况是: download 分区和 factory 分区均无可用固件包
* AUTO_UPDATE_APP : APP 固件校验错误后自动将可用和正确的固件更新至 APP
* * 需要注意的是,当选择了本选项,意味着你十分重视 APP 的数据完整性,也就是说,当 APP 固件校验不通过或
* 无法校验时,若 download 分区和 factory 分区均无可用固件包,则会停留在 bootloader 中,不会跳转至 APP
* 即便 APP 存在固件
* * 需要特别声明的是,有一种情况会导致 APP 无法被执行,那便是通过烧录器将固件烧录进 MCU 的 flash 中,
* 因为此时不是通过正常的固件更新程序执行, download 分区和 factory 分区均无可用固件包, APP 固件无法进行
* 完整性校验,建议采用正常的固件更新流程,即由 bootloader 处理固件更新,或选择 CHECK_UNLESS_EMPTY 选型
* * 此处的自动更新和 CONFIG_AUTO_UPDATE_MODE 的不同,本选项仅在 APP 固件校验不通过时才会
* 自动更新,而 CONFIG_AUTO_UPDATE_MODE 则是无视本选项进行固件自动更新
* DO_NOT_DO_ANYTHING: APP固件校验错误后不要做任何操作,停在 bootloader 即可,即便 download 分区或 factory 分区有可用的固件包
* * 需要注意的是, DO_NOT_DO_ANYTHING 这个选项并不能阻止 APP 分区为空时且 CONFIG_AUTO_UPDATE_MODE 启用了
* 自动更新的情况, DO_NOT_DO_ANYTHING 只能阻拦APP分区不为空且校验不通过的情况,要阻止自动更新,需要修改
* 上方的 CONFIG_AUTO_UPDATE_MODE 选项为 DO_NOT_AUTO_UPDATE
*/
#define DO_NOT_CHECK 0
#define CHECK_UNLESS_EMPTY 1
#define AUTO_UPDATE_APP 2
#define DO_NOT_DO_ANYTHING 3
#if ((CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION) \
&&((CONFIG_AUTO_UPDATE_MODE == MODE_UPDATE_DOWNLOAD_HEAD) \
||(CONFIG_AUTO_UPDATE_MODE == MODE_APPEND_TO_APP)))
#define CONFIG_CHECK_APP_SECURITY CHECK_UNLESS_EMPTY
#endif
/**
* 【选择是否可以使用 factory 分区的固件包】
* 说明:
* 当启用自动更新或校验 APP 固件完整性时,若 APP 固件不可用,且 download 分区没有可用的固件时,假设有 factory 分区,
* 且 factory 分区有可用的固件,选择是否将 factory 的固件更新至 APP 中
* 选项:
* 0: 不使用
* 1: 使用
*/
#if ((CONFIG_CHIP_PARTS == USE_TRIPLE_PARTITION) \
&&((CONFIG_CHECK_APP_SECURITY == CHECK_UNLESS_EMPTY) \
||(CONFIG_CHECK_APP_SECURITY == AUTO_UPDATE_APP)))
#define CONFIG_FACTORY_RESTORE 1
#endif
/** 是否自动纠正固件的分区
* 说明:
* 该选项是为了修正人为的将分区名写错的情况,是一种能最大程度保证固件更新正常的挽救措施
* 单分区方案下,无论本功能是否启用,固件包指定的其它分区名都会被修正为 APP 分区,使其可以正常更新
* 多分区方案下,启用后,固件包指定为 APP 分区时将会被修正为 download 分区,使其可以正常更新
* 多分区方案下,若不启用,固件包指定为 APP 分区时将会报错,并标记为更新失败
* 选项:
* 0: 不启用
* 1: 启用
*/
#if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION)
#define CONFIG_AUTO_CORRECT 1
#endif
/**
* 【选择是否使用按键恢复出厂固件的选项】
* 说明:
* 1. 使用本选项的前提是三分区方案,本选项能起效的前提是正确配置了按键且 factory 分区有可用的固件
* 2. 选择使用按键恢复出厂固件时,需要配置按键的引脚,如使用的按键和本案例不同,则需要自己配置和初始化 GPIO
* 3. 本选项仅设备在运行 bootloader 时,可通过按键恢复出厂固件,若设备运行着 APP ,则本选项是无法起效的,因此需要 APP 也同步配置
* 4. 本选项和通过指令恢复出厂固件的方式不冲突,可以同时使用,也可以不启用本选项
* 5. 当无 factory 或 factory 无可用固件时,强行恢复出厂固件,将会触发 FACTORY_NO_FIRMWARE_SOLUTION 选项
* 解释:
* ENABLE_FACTORY_FIRMWARE_BUTTON: 选择是否启用长按按键恢复出厂固件
* FACTORY_FIRMWARE_BUTTON_PRESS: 按键按下时的电平逻辑
* FACTORY_FIRMWARE_BUTTON_TIME: 按键长按的持续时间,单位 ms
* 选项:
* ENABLE_FACTORY_FIRMWARE_BUTTON 选项:
* 0: 不启用
* 1: 启用
* FACTORY_FIRMWARE_BUTTON_PRESS 选项:
* KEY_PRESS_LOW: 表示按下时为低电平
* KEY_PRESS_HIGH: 表示按下时为高电平
* FACTORY_FIRMWARE_BUTTON_TIME 选项:
* 按键长按的持续时间,单位 ms ,不能大于 65535
*/
#if (CONFIG_CHIP_PARTS == USE_TRIPLE_PARTITION)
#define ENABLE_FACTORY_FIRMWARE_BUTTON 0
#define FACTORY_FIRMWARE_BUTTON_PRESS KEY_PRESS_LOW
#define FACTORY_FIRMWARE_BUTTON_TIME 3000
#endif
/**
* 【片内 Flash 放置固件包所在 sector 的擦除粒度 ( TODO: 暂未实现 )】
* 说明:
* CONFIG_AUTO_UPDATE_MODE = MODE_UPDATE_DOWNLOAD_HEAD 时,需要给出固件包所在 sector 的擦除粒度,单位是 byte
*/
#if (CONFIG_AUTO_UPDATE_MODE == MODE_UPDATE_DOWNLOAD_HEAD)
#define ONCHIP_FLASH_ERASE_GRANULARITY UPK_LEAST_HANDLE_BYTE
#endif
#endif
+72
View File
@@ -0,0 +1,72 @@
#ifndef __FIRMWARE_MANAGE_H__
#define __FIRMWARE_MANAGE_H__
#include "bsp_common.h"
#include "utils.h"
/* upk: upgrade Package */
#define UPK_LEAST_HANDLE_BYTE 4096
#define UPK_VERSION_SIZE 16
#define UPK_USER_STRING_SIZE 16
#define UPK_PART_NAME_SIZE 16
#define UPK_HEAD_SIZE sizeof(struct upk_head_t)
#define UPK_IDENTIFIER 0x006B7075 // 'upk'
/* 固件写入的方向 */
typedef enum
{
FM_DIR_HOST_TO_APP = 0x00, /* 从主机方向将固件写入 APP 分区 */
FM_DIR_HOST_TO_DOWNLOAD, /* 从主机方向将固件写入 download/factory 分区 */
FM_DIR_DOWNLOAD_TO_APP, /* 从 download/factory 分区方向将固件写入 APP 分区 */
} FM_FIRMWARE_WRITE_DIR;
#pragma pack(1)
/* upk 固件表头的内容详见《upk固件包表头信息.xlsx》 */
struct upk_head_t {
char name[4]; /* upk 文件标识 */
uint8_t config[4]; /* 配置选项 */
char fw_old_ver[UPK_VERSION_SIZE]; /* 固件旧版本 */
char fw_new_ver[UPK_VERSION_SIZE]; /* 固件新版本 */
char user_string[UPK_USER_STRING_SIZE]; /* 用户自定义的字符水印 */
char part_name[UPK_PART_NAME_SIZE]; /* 固件包存放的分区名 */
uint32_t raw_size; /* 源固件的大小,不包含本表头 */
uint32_t pkg_size; /* 打包后固件的大小,不包含本表头 */
uint32_t timestamp; /* 打包时的 unix 时间戳,可转换为年月日时分秒信息 */
uint32_t raw_crc; /* 源固件的 CRC32 值 */
uint32_t pkg_crc; /* 打包后固件的 CRC32 值 */
uint32_t head_crc; /* 本表头的 CRC32 值 */
};
#pragma pack()
void FM_Init (void);
uint8_t FM_IsEncrypt (void);
eErrCode FM_IsEmpty (const char *part_name);
char * FM_GetNewFirmwareVersion (void);
uint32_t FM_GetRawCRC32 (void);
eErrCode FM_StorageFirmwareHead (const char *part_name, uint8_t *data);
eErrCode FM_VerifyFirmware (const char *part_name, uint32_t crc32, uint8_t is_auto_fill);
eErrCode FM_EraseFirmware (const char *part_name);
eErrCode FM_WriteFirmwareDone (const char *part_name);
eErrCode FM_WriteFirmwareSubPackage (const char *part_name, uint8_t *data, uint16_t pkg_size);
eErrCode FM_CheckFirmwareIntegrity (uint32_t addr);
#if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION)
uint8_t FM_IsNeedAutoUpdate (void);
char * FM_GetPartName (void);
char * FM_GetOldFirmwareVersion (void);
uint32_t FM_GetPackageCRC32 (void);
eErrCode FM_ReadFirmwareHead (const char *part_name);
eErrCode FM_UpdateToAPP (const char *from_part_name);
#if (CONFIG_AUTO_UPDATE_MODE == MODE_UPDATE_DOWNLOAD_HEAD || \
CONFIG_AUTO_UPDATE_MODE == MODE_APPEND_TO_APP)
eErrCode FM_UpdateFirmwareVersion (const char *part_name);
#endif
#endif
#endif
+36
View File
@@ -0,0 +1,36 @@
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f4xx_hal.h"
#if defined(STM32F405xx)
#define KEY0_Pin GPIO_PIN_8
#define KEY0_GPIO_Port GPIOC
#define LED0_Pin GPIO_PIN_8
#define LED0_GPIO_Port GPIOA
#elif defined(STM32F411xE)||defined(STM32F401xC)
#define KEY0_Pin GPIO_PIN_0
#define KEY0_GPIO_Port GPIOA
#define LED0_Pin GPIO_PIN_13
#define LED0_GPIO_Port GPIOC
#endif
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
+490
View File
@@ -0,0 +1,490 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f4xx_hal_conf_template.h
* @author MCD Application Team
* @brief HAL configuration template file.
* This file should be copied to the application folder and renamed
* to stm32f4xx_hal_conf.h.
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_HAL_CONF_H
#define __STM32F4xx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
/* #define HAL_CRYP_MODULE_ENABLED */
/* #define HAL_ADC_MODULE_ENABLED */
/* #define HAL_CAN_MODULE_ENABLED */
/* #define HAL_CRC_MODULE_ENABLED */
/* #define HAL_CAN_LEGACY_MODULE_ENABLED */
/* #define HAL_DAC_MODULE_ENABLED */
/* #define HAL_DCMI_MODULE_ENABLED */
/* #define HAL_DMA2D_MODULE_ENABLED */
/* #define HAL_ETH_MODULE_ENABLED */
/* #define HAL_NAND_MODULE_ENABLED */
/* #define HAL_NOR_MODULE_ENABLED */
/* #define HAL_PCCARD_MODULE_ENABLED */
/* #define HAL_SRAM_MODULE_ENABLED */
/* #define HAL_SDRAM_MODULE_ENABLED */
/* #define HAL_HASH_MODULE_ENABLED */
/* #define HAL_I2C_MODULE_ENABLED */
/* #define HAL_I2S_MODULE_ENABLED */
/* #define HAL_IWDG_MODULE_ENABLED */
/* #define HAL_LTDC_MODULE_ENABLED */
/* #define HAL_RNG_MODULE_ENABLED */
/* #define HAL_RTC_MODULE_ENABLED */
/* #define HAL_SAI_MODULE_ENABLED */
/* #define HAL_SD_MODULE_ENABLED */
/* #define HAL_MMC_MODULE_ENABLED */
/* #define HAL_SPI_MODULE_ENABLED */
/* #define HAL_TIM_MODULE_ENABLED */
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
/* #define HAL_SMARTCARD_MODULE_ENABLED */
/* #define HAL_SMBUS_MODULE_ENABLED */
/* #define HAL_WWDG_MODULE_ENABLED */
/* #define HAL_PCD_MODULE_ENABLED */
/* #define HAL_HCD_MODULE_ENABLED */
/* #define HAL_DSI_MODULE_ENABLED */
/* #define HAL_QSPI_MODULE_ENABLED */
/* #define HAL_QSPI_MODULE_ENABLED */
/* #define HAL_CEC_MODULE_ENABLED */
/* #define HAL_FMPI2C_MODULE_ENABLED */
/* #define HAL_FMPSMBUS_MODULE_ENABLED */
/* #define HAL_SPDIFRX_MODULE_ENABLED */
/* #define HAL_DFSDM_MODULE_ENABLED */
/* #define HAL_LPTIM_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
#define HAL_EXTI_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
/* ########################## HSE/HSI Values adaptation ##################### */
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @brief Internal Low Speed oscillator (LSI) value.
*/
#if !defined (LSI_VALUE)
#define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
/**
* @brief External Low Speed oscillator (LSE) value.
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE 32768U /*!< Value of the External Low Speed oscillator in Hz */
#endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
#endif /* LSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for I2S peripheral
* This value is used by the I2S HAL module to compute the I2S clock source
* frequency, this source is inserted directly through I2S_CKIN pad.
*/
#if !defined (EXTERNAL_CLOCK_VALUE)
#define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the External audio frequency in Hz*/
#endif /* EXTERNAL_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY 15U /*!< tick interrupt priority */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 1U
#define INSTRUCTION_CACHE_ENABLE 1U
#define DATA_CACHE_ENABLE 1U
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */
#define USE_HAL_FMPSMBUS_REGISTER_CALLBACKS 0U /* FMPSMBUS register callback disabled */
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* ################## Ethernet peripheral configuration ##################### */
/* Section 1 : Ethernet peripheral configuration */
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
#define MAC_ADDR0 2U
#define MAC_ADDR1 0U
#define MAC_ADDR2 0U
#define MAC_ADDR3 0U
#define MAC_ADDR4 0U
#define MAC_ADDR5 0U
/* Definition of the Ethernet driver buffers size and count */
#define ETH_RX_BUF_SIZE /* buffer size for receive */
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
/* Section 2: PHY configuration section */
/* DP83848_PHY_ADDRESS Address*/
#define DP83848_PHY_ADDRESS 0x01U
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
#define PHY_RESET_DELAY 0x000000FFU
/* PHY Configuration delay */
#define PHY_CONFIG_DELAY 0x00000FFFU
#define PHY_READ_TO 0x0000FFFFU
#define PHY_WRITE_TO 0x0000FFFFU
/* Section 3: Common PHY Registers */
#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
/* Section 4: Extended PHY Registers */
#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 0U
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include module's header file
*/
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32f4xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32f4xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32f4xx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32f4xx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32f4xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32f4xx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_CAN_MODULE_ENABLED
#include "stm32f4xx_hal_can.h"
#endif /* HAL_CAN_MODULE_ENABLED */
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
#include "stm32f4xx_hal_can_legacy.h"
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32f4xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
#include "stm32f4xx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_DMA2D_MODULE_ENABLED
#include "stm32f4xx_hal_dma2d.h"
#endif /* HAL_DMA2D_MODULE_ENABLED */
#ifdef HAL_DAC_MODULE_ENABLED
#include "stm32f4xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */
#ifdef HAL_DCMI_MODULE_ENABLED
#include "stm32f4xx_hal_dcmi.h"
#endif /* HAL_DCMI_MODULE_ENABLED */
#ifdef HAL_ETH_MODULE_ENABLED
#include "stm32f4xx_hal_eth.h"
#endif /* HAL_ETH_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32f4xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_SRAM_MODULE_ENABLED
#include "stm32f4xx_hal_sram.h"
#endif /* HAL_SRAM_MODULE_ENABLED */
#ifdef HAL_NOR_MODULE_ENABLED
#include "stm32f4xx_hal_nor.h"
#endif /* HAL_NOR_MODULE_ENABLED */
#ifdef HAL_NAND_MODULE_ENABLED
#include "stm32f4xx_hal_nand.h"
#endif /* HAL_NAND_MODULE_ENABLED */
#ifdef HAL_PCCARD_MODULE_ENABLED
#include "stm32f4xx_hal_pccard.h"
#endif /* HAL_PCCARD_MODULE_ENABLED */
#ifdef HAL_SDRAM_MODULE_ENABLED
#include "stm32f4xx_hal_sdram.h"
#endif /* HAL_SDRAM_MODULE_ENABLED */
#ifdef HAL_HASH_MODULE_ENABLED
#include "stm32f4xx_hal_hash.h"
#endif /* HAL_HASH_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32f4xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32f4xx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */
#ifdef HAL_I2S_MODULE_ENABLED
#include "stm32f4xx_hal_i2s.h"
#endif /* HAL_I2S_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32f4xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_LTDC_MODULE_ENABLED
#include "stm32f4xx_hal_ltdc.h"
#endif /* HAL_LTDC_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32f4xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
#include "stm32f4xx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32f4xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SAI_MODULE_ENABLED
#include "stm32f4xx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */
#ifdef HAL_SD_MODULE_ENABLED
#include "stm32f4xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32f4xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32f4xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32f4xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32f4xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32f4xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32f4xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32f4xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32f4xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_HCD_MODULE_ENABLED
#include "stm32f4xx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
#ifdef HAL_DSI_MODULE_ENABLED
#include "stm32f4xx_hal_dsi.h"
#endif /* HAL_DSI_MODULE_ENABLED */
#ifdef HAL_QSPI_MODULE_ENABLED
#include "stm32f4xx_hal_qspi.h"
#endif /* HAL_QSPI_MODULE_ENABLED */
#ifdef HAL_CEC_MODULE_ENABLED
#include "stm32f4xx_hal_cec.h"
#endif /* HAL_CEC_MODULE_ENABLED */
#ifdef HAL_FMPI2C_MODULE_ENABLED
#include "stm32f4xx_hal_fmpi2c.h"
#endif /* HAL_FMPI2C_MODULE_ENABLED */
#ifdef HAL_FMPSMBUS_MODULE_ENABLED
#include "stm32f4xx_hal_fmpsmbus.h"
#endif /* HAL_FMPSMBUS_MODULE_ENABLED */
#ifdef HAL_SPDIFRX_MODULE_ENABLED
#include "stm32f4xx_hal_spdifrx.h"
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
#ifdef HAL_DFSDM_MODULE_ENABLED
#include "stm32f4xx_hal_dfsdm.h"
#endif /* HAL_DFSDM_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
#include "stm32f4xx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
#ifdef HAL_MMC_MODULE_ENABLED
#include "stm32f4xx_hal_mmc.h"
#endif /* HAL_MMC_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* __STM32F4xx_HAL_CONF_H */
+66
View File
@@ -0,0 +1,66 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f4xx_it.h
* @brief This file contains the headers of the interrupt handlers.
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_IT_H
#define __STM32F4xx_IT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
#ifdef __cplusplus
}
#endif
#endif /* __STM32F4xx_IT_H */
+36
View File
@@ -0,0 +1,36 @@
#ifndef __TRANSFER_H__
#define __TRANSFER_H__
#include "bsp_common.h"
/* 是否使能断帧检测 */
#define DT_ENABLE_BROKEN_FRAME_DETECT 0
#define BROKEN_FRAME_INTERVAL_TIME 100 /* 断帧间隔时间判断,单位 ms */
typedef enum {
X_RESULT_RECV_FRAME = 0x00, /* 收到了一帧数据 */
X_RESULT_NO_DATA = 0x01, /* 未收到数据 */
X_RESULT_JUST_RECV = 0x02, /* 刚收到一帧数据(可能是断帧) */
X_RESULT_WAIT_DECTECT = 0x03 /* 等待断帧判断 */
} exRESULT;
struct transfer_t {
uint8_t if_id;
uint8_t *rx_buff;
uint16_t *rx_len;
uint32_t rx_buff_size;
};
extern void DT_Init (struct transfer_t *xfer, uint8_t if_id, uint8_t *buff, uint16_t *len, uint32_t buff_size);
extern void DT_Send (struct transfer_t *xfer, uint8_t *data, uint32_t len);
extern exRESULT DT_PollingReceive (struct transfer_t *xfer);
#endif /* __TRANSFER_H__ */
+13
View File
@@ -0,0 +1,13 @@
#ifndef __UTILS_H__
#define __UTILS_H__
#include <stdint.h>
extern int hex_printf (const uint8_t *buff, int count);
extern uint16_t crc16_xmodem (uint8_t *data, uint16_t length);
extern uint32_t crc32_step (uint32_t in_crc, const void *buf, uint32_t size);
#endif
+99
View File
@@ -0,0 +1,99 @@
#ifndef __YMODEM_H__
#define __YMODEM_H__
#include "bsp_common.h"
#include "firmware.h"
/* YModem 协议 */
#define YMODEM_SOH 0x01
#define YMODEM_STX 0x02
#define YMODEM_EOT 0x04
#define YMODEM_ACK 0x06
#define YMODEM_NAK 0x15
#define YMODEM_CAN 0x18 // graceful abort: two CAN (0x18)
#define YMODEM_FRAME_FIXED_LEN (5)
#define YMODEM_SOH_DATA_LEN (128)
#define YMODEM_STX_DATA_LEN (1024)
#define YMODEM_SOH_FRAME_LEN (YMODEM_FRAME_FIXED_LEN + YMODEM_SOH_DATA_LEN)
#define YMODEM_STX_FRAME_LEN (YMODEM_FRAME_FIXED_LEN + YMODEM_STX_DATA_LEN)
#define YMODEM_C 'C'
/* 协议包数据最大长度定义,因以下两个宏定义在 app.c 中也使用,因此不建议修改宏定义名称,更改宏定义内容即可 */
#define YM_BODY_SIZE_MAX YMODEM_STX_DATA_LEN
#define YM_MSG_SIZE_MAX YMODEM_STX_FRAME_LEN
typedef enum {
YMODEM_FLOW_NONE = 0x00,
YMODEM_FLOW_START,
YMODEM_FLOW_FIRST_EOT,
YMODEM_FLOW_SECOND_EOT,
YMODEM_FLOW_ASK,
YMODEM_FLOW_SUCCESS,
YMODEM_FLOW_FAILED,
YMODEM_FLOW_CANCEL
} eYmFLOW;
#pragma pack(1)
union message_raw_t {
uint8_t raw_data[YM_MSG_SIZE_MAX]; /* 数据缓存池,接收到来自上位机的原始数据 */
struct {
uint8_t header; /* start of header */
uint8_t pkt_num; /* packet number */
uint8_t not_pkt_num; /* the invert of packet number's bit */
uint8_t data[]; /* packet data */
} pkg;
};
#pragma pack()
/* 协议包含的指令 */
typedef enum {
YM_CMD_NONE = 0x00,
YM_CMD_SOH = YMODEM_SOH,
YM_CMD_STX = YMODEM_STX,
YM_CMD_EOT = YMODEM_EOT,
YM_CMD_CAN = YMODEM_CAN
} eYmCMD;
/* 协议指令的执行结果 */
typedef enum {
YM_RESULT_OK = 0x00, /* 执行成功 */
YM_RESULT_PROCESS = 0x01, /* 执行中 */
YM_RESULT_FAILED = 0x02, /* 执行失败,重试 */
YM_RESULT_CANCEL = 0x03 /* 执行失败,取消传输 */
} eRESULT;
/* 对协议析构层的配置选项 */
typedef enum {
YM_MODE_NONE = 0x00,
YM_MODE_RESET = 0x01,
YM_MODE_RECV = 0x02
} eYmMODE;
/* 需要打包发送至上位机的数据 */
struct tx_raw_t {
uint8_t response;
};
/* typedef of function */
typedef void (*ymSend)(uint8_t *data, uint16_t len, uint32_t timeout);
typedef void (*ymPrepareCallback)(eYmCMD cmd, uint8_t *data, uint16_t data_len);
typedef void (*ymReplyCallback)(eYmCMD cmd, eRESULT *result, uint8_t *data, uint16_t *data_len);
/* 函数定义 */
extern void ymodem_init (ymSend Send,
ymPrepareCallback PrepareCallback,
ymReplyCallback Set_ResponseInfo);
extern eErrCode ymodemHandler (uint8_t *data, uint16_t len);
extern void ymodemConfig (eYmMODE para, void *value);
#endif /* __YMODEM_H__ */
+202
View File
@@ -0,0 +1,202 @@
#include <stdio.h>
#include "app_config.h"
#include "main.h"
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart2_rx;
extern void System_Init(void);
extern void APP_Init(void);
extern void APP_Running(void);
#if defined(STM32F405xx)
void SystemClock_Config (void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
#elif defined(STM32F411xE)||defined(STM32F401xC)
void SystemClock_Config (void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 100;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
}
#endif
static void MX_GPIO_Init (void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
#if (ENABLE_FACTORY_FIRMWARE_BUTTON)
__HAL_RCC_GPIOE_CLK_ENABLE();
GPIO_InitStruct.Pin = KEY0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY0_GPIO_Port, &GPIO_InitStruct);
#endif
GPIO_InitStruct.Pin = LED0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(LED0_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);
}
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */
// usart1 rx
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
// usart2 rx
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
}
void MX_DMA_DeInit (void)
{
HAL_DMA_DeInit(&hdma_usart1_rx);
HAL_DMA_DeInit(&hdma_usart2_rx);
}
static void MX_USART_Init (void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart1);
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
}
void MX_USART_DeInit (void)
{
HAL_UART_DeInit(&huart1);
HAL_UART_DeInit(&huart2);
}
int main (void)
{
HAL_Init();
SystemClock_Config();
System_Init();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART_Init();
printf("\r\n\r\n========================================\r\n");
printf("\t%s boot V%d.%d.%d\r\n", NAME_CHIP,
VERSION_MAIN, VERSION_SUB, VERSION_FIX);
printf("\tbuilt @ %s\r\n", BUILD_TIMESTAMP);
printf("Chip UID: %08X - %08X - %08X\r\n",
HAL_GetUIDw0(), HAL_GetUIDw1(), HAL_GetUIDw2());
printf("========================================\r\n");
APP_Init();
while (1) {
APP_Running();
}
return -1;
}
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE * f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1,&ch, 1, 0xffff);
return ch;
}
+95
View File
@@ -0,0 +1,95 @@
#include "main.h"
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart2_rx;
void HAL_MspInit (void)
{
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
}
void HAL_UART_MspInit (UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (huart->Instance == USART1) {
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
// PA9 ------> USART1_TX
// PA10 ------> USART1_RX
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
hdma_usart1_rx.Instance = DMA2_Stream2;
hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_usart1_rx);
__HAL_LINKDMA(huart, hdmarx, hdma_usart1_rx);
HAL_NVIC_SetPriority(USART1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
} else if (huart->Instance == USART2) {
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
// PA2 ------> USART2_TX
// PA3 ------> USART2_RX
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
hdma_usart2_rx.Instance = DMA1_Stream5;
hdma_usart2_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_usart2_rx);
__HAL_LINKDMA(huart, hdmarx, hdma_usart2_rx);
HAL_NVIC_SetPriority(USART2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
}
}
void HAL_UART_MspDeInit (UART_HandleTypeDef* huart)
{
if (huart->Instance == USART1) {
__HAL_RCC_USART1_CLK_DISABLE();
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
HAL_DMA_DeInit(huart->hdmarx);
HAL_NVIC_DisableIRQ(USART1_IRQn);
} else if (huart->Instance == USART2) {
__HAL_RCC_USART2_CLK_DISABLE();
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
HAL_DMA_DeInit(huart->hdmarx);
HAL_NVIC_DisableIRQ(USART2_IRQn);
}
}
+204
View File
@@ -0,0 +1,204 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f4xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1)
{
}
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
* @brief This function handles Pre-fetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
extern void drv_timer_handler (uint8_t ms);
drv_timer_handler(1);
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
+747
View File
@@ -0,0 +1,747 @@
/**
******************************************************************************
* @file system_stm32f4xx.c
* @author MCD Application Team
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32f4xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
*
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32f4xx_system
* @{
*/
/** @addtogroup STM32F4xx_System_Private_Includes
* @{
*/
#include "stm32f4xx.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Defines
* @{
*/
/************************* Miscellaneous Configuration ************************/
/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
|| defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
/* #define DATA_IN_ExtSRAM */
#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\
STM32F412Zx || STM32F412Vx */
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
/* #define DATA_IN_ExtSDRAM */
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\
STM32F479xx */
/* Note: Following vector table addresses must be defined in line with linker
configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
anywhere in Flash or Sram, else the vector table is kept at the automatic
remap of boot address selected */
/* #define USER_VECT_TAB_ADDRESS */
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
/******************************************************************************/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Variables
* @{
*/
/* This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = 16000000;
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
* @{
*/
#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
static void SystemInit_ExtMemCtl(void);
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system
* Initialize the FPU setting, vector table location and External memory
* configuration.
* @param None
* @retval None
*/
void SystemInit(void)
{
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
/* Configure the Vector Table location -------------------------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
* 16 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value
* depends on the application requirements), user has to ensure that HSE_VALUE
* is same as the real frequency of the crystal used. Otherwise, this function
* may have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void)
{
uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp)
{
case 0x00: /* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x04: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x08: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
SYSCLK = PLL_VCO / PLL_P
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
if (pllsource != 0)
{
/* HSE used as PLL clock source */
pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
}
else
{
/* HSI used as PLL clock source */
pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
}
pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
SystemCoreClock = pllvco/pllp;
break;
default:
SystemCoreClock = HSI_VALUE;
break;
}
/* Compute HCLK frequency --------------------------------------------------*/
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
/* HCLK frequency */
SystemCoreClock >>= tmp;
}
#if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM)
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F469xx) || defined(STM32F479xx)
/**
* @brief Setup the external memory controller.
* Called in startup_stm32f4xx.s before jump to main.
* This function configures the external memories (SRAM/SDRAM)
* This SRAM/SDRAM will be used as program data memory (including heap and stack).
* @param None
* @retval None
*/
void SystemInit_ExtMemCtl(void)
{
__IO uint32_t tmp = 0x00;
register uint32_t tmpreg = 0, timeout = 0xFFFF;
register __IO uint32_t index;
/* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */
RCC->AHB1ENR |= 0x000001F8;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x00CCC0CC;
GPIOD->AFR[1] = 0xCCCCCCCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xAAAA0A8A;
/* Configure PDx pins speed to 100 MHz */
GPIOD->OSPEEDR = 0xFFFF0FCF;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00CC0CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA828A;
/* Configure PEx pins speed to 100 MHz */
GPIOE->OSPEEDR = 0xFFFFC3CF;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0xCCCCCCCC;
GPIOF->AFR[1] = 0xCCCCCCCC;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA800AAA;
/* Configure PFx pins speed to 50 MHz */
GPIOF->OSPEEDR = 0xAA800AAA;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0xCCCCCCCC;
GPIOG->AFR[1] = 0xCCCCCCCC;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0xAAAAAAAA;
/* Configure PGx pins speed to 50 MHz */
GPIOG->OSPEEDR = 0xAAAAAAAA;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
/* Connect PHx pins to FMC Alternate function */
GPIOH->AFR[0] = 0x00C0CC00;
GPIOH->AFR[1] = 0xCCCCCCCC;
/* Configure PHx pins in Alternate function mode */
GPIOH->MODER = 0xAAAA08A0;
/* Configure PHx pins speed to 50 MHz */
GPIOH->OSPEEDR = 0xAAAA08A0;
/* Configure PHx pins Output type to push-pull */
GPIOH->OTYPER = 0x00000000;
/* No pull-up, pull-down for PHx pins */
GPIOH->PUPDR = 0x00000000;
/* Connect PIx pins to FMC Alternate function */
GPIOI->AFR[0] = 0xCCCCCCCC;
GPIOI->AFR[1] = 0x00000CC0;
/* Configure PIx pins in Alternate function mode */
GPIOI->MODER = 0x0028AAAA;
/* Configure PIx pins speed to 50 MHz */
GPIOI->OSPEEDR = 0x0028AAAA;
/* Configure PIx pins Output type to push-pull */
GPIOI->OTYPER = 0x00000000;
/* No pull-up, pull-down for PIx pins */
GPIOI->PUPDR = 0x00000000;
/*-- FMC Configuration -------------------------------------------------------*/
/* Enable the FMC interface clock */
RCC->AHB3ENR |= 0x00000001;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
FMC_Bank5_6->SDCR[0] = 0x000019E4;
FMC_Bank5_6->SDTR[0] = 0x01115351;
/* SDRAM initialization sequence */
/* Clock enable command */
FMC_Bank5_6->SDCMR = 0x00000011;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Delay */
for (index = 0; index<1000; index++);
/* PALL command */
FMC_Bank5_6->SDCMR = 0x00000012;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Auto refresh command */
FMC_Bank5_6->SDCMR = 0x00000073;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* MRD register program */
FMC_Bank5_6->SDCMR = 0x00046014;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Set refresh count */
tmpreg = FMC_Bank5_6->SDRTR;
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
/* Disable write protection */
tmpreg = FMC_Bank5_6->SDCR[0];
FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001011;
FMC_Bank1->BTCR[3] = 0x00000201;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
#if defined(STM32F469xx) || defined(STM32F479xx)
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001091;
FMC_Bank1->BTCR[3] = 0x00110212;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F469xx || STM32F479xx */
(void)(tmp);
}
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
#elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
/**
* @brief Setup the external memory controller.
* Called in startup_stm32f4xx.s before jump to main.
* This function configures the external memories (SRAM/SDRAM)
* This SRAM/SDRAM will be used as program data memory (including heap and stack).
* @param None
* @retval None
*/
void SystemInit_ExtMemCtl(void)
{
__IO uint32_t tmp = 0x00;
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
#if defined (DATA_IN_ExtSDRAM)
register uint32_t tmpreg = 0, timeout = 0xFFFF;
register __IO uint32_t index;
#if defined(STM32F446xx)
/* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface
clock */
RCC->AHB1ENR |= 0x0000007D;
#else
/* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
clock */
RCC->AHB1ENR |= 0x000001F8;
#endif /* STM32F446xx */
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
#if defined(STM32F446xx)
/* Connect PAx pins to FMC Alternate function */
GPIOA->AFR[0] |= 0xC0000000;
GPIOA->AFR[1] |= 0x00000000;
/* Configure PDx pins in Alternate function mode */
GPIOA->MODER |= 0x00008000;
/* Configure PDx pins speed to 50 MHz */
GPIOA->OSPEEDR |= 0x00008000;
/* Configure PDx pins Output type to push-pull */
GPIOA->OTYPER |= 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOA->PUPDR |= 0x00000000;
/* Connect PCx pins to FMC Alternate function */
GPIOC->AFR[0] |= 0x00CC0000;
GPIOC->AFR[1] |= 0x00000000;
/* Configure PDx pins in Alternate function mode */
GPIOC->MODER |= 0x00000A00;
/* Configure PDx pins speed to 50 MHz */
GPIOC->OSPEEDR |= 0x00000A00;
/* Configure PDx pins Output type to push-pull */
GPIOC->OTYPER |= 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOC->PUPDR |= 0x00000000;
#endif /* STM32F446xx */
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x000000CC;
GPIOD->AFR[1] = 0xCC000CCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xA02A000A;
/* Configure PDx pins speed to 50 MHz */
GPIOD->OSPEEDR = 0xA02A000A;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00000CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA800A;
/* Configure PEx pins speed to 50 MHz */
GPIOE->OSPEEDR = 0xAAAA800A;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0xCCCCCCCC;
GPIOF->AFR[1] = 0xCCCCCCCC;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA800AAA;
/* Configure PFx pins speed to 50 MHz */
GPIOF->OSPEEDR = 0xAA800AAA;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0xCCCCCCCC;
GPIOG->AFR[1] = 0xCCCCCCCC;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0xAAAAAAAA;
/* Configure PGx pins speed to 50 MHz */
GPIOG->OSPEEDR = 0xAAAAAAAA;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F469xx) || defined(STM32F479xx)
/* Connect PHx pins to FMC Alternate function */
GPIOH->AFR[0] = 0x00C0CC00;
GPIOH->AFR[1] = 0xCCCCCCCC;
/* Configure PHx pins in Alternate function mode */
GPIOH->MODER = 0xAAAA08A0;
/* Configure PHx pins speed to 50 MHz */
GPIOH->OSPEEDR = 0xAAAA08A0;
/* Configure PHx pins Output type to push-pull */
GPIOH->OTYPER = 0x00000000;
/* No pull-up, pull-down for PHx pins */
GPIOH->PUPDR = 0x00000000;
/* Connect PIx pins to FMC Alternate function */
GPIOI->AFR[0] = 0xCCCCCCCC;
GPIOI->AFR[1] = 0x00000CC0;
/* Configure PIx pins in Alternate function mode */
GPIOI->MODER = 0x0028AAAA;
/* Configure PIx pins speed to 50 MHz */
GPIOI->OSPEEDR = 0x0028AAAA;
/* Configure PIx pins Output type to push-pull */
GPIOI->OTYPER = 0x00000000;
/* No pull-up, pull-down for PIx pins */
GPIOI->PUPDR = 0x00000000;
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
/*-- FMC Configuration -------------------------------------------------------*/
/* Enable the FMC interface clock */
RCC->AHB3ENR |= 0x00000001;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
/* Configure and enable SDRAM bank1 */
#if defined(STM32F446xx)
FMC_Bank5_6->SDCR[0] = 0x00001954;
#else
FMC_Bank5_6->SDCR[0] = 0x000019E4;
#endif /* STM32F446xx */
FMC_Bank5_6->SDTR[0] = 0x01115351;
/* SDRAM initialization sequence */
/* Clock enable command */
FMC_Bank5_6->SDCMR = 0x00000011;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Delay */
for (index = 0; index<1000; index++);
/* PALL command */
FMC_Bank5_6->SDCMR = 0x00000012;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Auto refresh command */
#if defined(STM32F446xx)
FMC_Bank5_6->SDCMR = 0x000000F3;
#else
FMC_Bank5_6->SDCMR = 0x00000073;
#endif /* STM32F446xx */
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* MRD register program */
#if defined(STM32F446xx)
FMC_Bank5_6->SDCMR = 0x00044014;
#else
FMC_Bank5_6->SDCMR = 0x00046014;
#endif /* STM32F446xx */
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Set refresh count */
tmpreg = FMC_Bank5_6->SDRTR;
#if defined(STM32F446xx)
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1));
#else
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
#endif /* STM32F446xx */
/* Disable write protection */
tmpreg = FMC_Bank5_6->SDCR[0];
FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
#endif /* DATA_IN_ExtSDRAM */
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
|| defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
#if defined(DATA_IN_ExtSRAM)
/*-- GPIOs Configuration -----------------------------------------------------*/
/* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
RCC->AHB1ENR |= 0x00000078;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x00CCC0CC;
GPIOD->AFR[1] = 0xCCCCCCCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xAAAA0A8A;
/* Configure PDx pins speed to 100 MHz */
GPIOD->OSPEEDR = 0xFFFF0FCF;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00CC0CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA828A;
/* Configure PEx pins speed to 100 MHz */
GPIOE->OSPEEDR = 0xFFFFC3CF;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0x00CCCCCC;
GPIOF->AFR[1] = 0xCCCC0000;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA000AAA;
/* Configure PFx pins speed to 100 MHz */
GPIOF->OSPEEDR = 0xFF000FFF;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0x00CCCCCC;
GPIOG->AFR[1] = 0x000000C0;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0x00085AAA;
/* Configure PGx pins speed to 100 MHz */
GPIOG->OSPEEDR = 0x000CAFFF;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
/*-- FMC/FSMC Configuration --------------------------------------------------*/
/* Enable the FMC/FSMC interface clock */
RCC->AHB3ENR |= 0x00000001;
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001011;
FMC_Bank1->BTCR[3] = 0x00000201;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
#if defined(STM32F469xx) || defined(STM32F479xx)
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001091;
FMC_Bank1->BTCR[3] = 0x00110212;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F469xx || STM32F479xx */
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\
|| defined(STM32F412Zx) || defined(STM32F412Vx)
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);
/* Configure and enable Bank1_SRAM2 */
FSMC_Bank1->BTCR[2] = 0x00001011;
FSMC_Bank1->BTCR[3] = 0x00000201;
FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF;
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */
#endif /* DATA_IN_ExtSRAM */
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\
STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */
(void)(tmp);
}
#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
+1507
View File
File diff suppressed because it is too large Load Diff
+22
View File
@@ -0,0 +1,22 @@
mainmenu "RT-Thread Configuration"
BSP_DIR := .
RTT_DIR := ../../rt-thread
PKGS_DIR := packages
config SOC_STM32F405RG
bool
select SOC_SERIES_STM32F4
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
default y
source "$(RTT_DIR)/Kconfig"
osource "$PKGS_DIR/Kconfig"
rsource "$(RTT_DIR)/bsp/stm32/libraries/Kconfig"
if !RT_USING_NANO
rsource "board/Kconfig"
endif
+20
View File
@@ -0,0 +1,20 @@
# for module compiling
import os
Import('RTT_ROOT')
Import('env')
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
env.Append(CPPDEFINES = ['STM32F405xx'])
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
objs = objs + SConscript(os.path.join(cwd, '../../lib/SConscript'))
Return('objs')
+60
View File
@@ -0,0 +1,60 @@
import os
import sys
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../../rt-thread')
print("RTT_ROOT : " + RTT_ROOT)
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
try:
from building import *
except:
print('Cannot found RT-Thread root directory, please check RTT_ROOT')
print(RTT_ROOT)
exit(-1)
TARGET = 'chrg.' + rtconfig.TARGET_EXT
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
if rtconfig.PLATFORM in ['iccarm']:
env.Replace(CCCOM = ['$CC $CFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
env.Replace(ARFLAGS = [''])
env.Replace(LINKCOM = env["LINKCOM"] + ' --map chrg.map')
Export('env')
Export('RTT_ROOT')
Export('rtconfig')
SDK_ROOT = os.path.abspath('./')
print("SDK_ROOT : " + SDK_ROOT)
if os.path.exists(SDK_ROOT + '/libraries'):
libraries_path_prefix = SDK_ROOT + '/libraries'
else:
libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/../rt-thread/bsp/stm32/libraries'
print("libraries_path_prefix : " + libraries_path_prefix)
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
rtconfig.BSP_LIBRARY_TYPE = None
# include drivers
objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript'),variant_dir='build/libraries/'+'HAL_Drivers', duplicate=0))
# make a building
DoBuilding(TARGET, objs)
+15
View File
@@ -0,0 +1,15 @@
from building import *
import os
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
list = os.listdir(cwd)
for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
group = group + SConscript(os.path.join(item, 'SConscript'))
Return('group')
+41
View File
@@ -0,0 +1,41 @@
#include "shell.h"
#include <board.h>
#include <rtthread.h>
#include <drv_gpio.h>
#ifndef RT_USING_NANO
#include <rtdevice.h>
#endif /* RT_USING_NANO */
/* defined the LED0 pin: PC4 */
/* LEDs: PC4, PA8, PC5, PA10 */
#define LED0_PIN GET_PIN(A, 8)
void show_app_version (void)
{
rt_kprintf("\r\n\r\n============================================\r\n");
rt_kprintf("\tcharger control via RT-Thread v%d.%d.%d\r\n",
RT_VERSION_MAJOR, RT_VERSION_MINOR, RT_VERSION_PATCH);
rt_kprintf("\tbuilt @ %s, %s\r\n", __DATE__, __TIME__);
rt_kprintf("Chip UID: %08X - %08X - %08X\r\n",
HAL_GetUIDw0(), HAL_GetUIDw1(), HAL_GetUIDw2());
rt_kprintf("============================================\r\n");
}
int main(void)
{
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
finsh_set_prompt("chrg ");
#endif
/* set LED0 pin mode to output */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
while (1)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED0_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
}
+6
View File
@@ -0,0 +1,6 @@
# files format check exclude path, please follow the instructions below to modify;
# If you need to exclude an entire folder, add the folder path in dir_path;
# If you need to exclude a file, add the path to the file in file_path.
dir_path:
- CubeMX_Config
+17
View File
@@ -0,0 +1,17 @@
[PreviousGenFiles]
HeaderPath=D:/mywork/stm32f405/board/CubeMX_Config/Inc
HeaderFiles=stm32f4xx_it.h;stm32f4xx_hal_conf.h;main.h;
SourcePath=D:/mywork/stm32f405/board/CubeMX_Config/Src
SourceFiles=stm32f4xx_it.c;stm32f4xx_hal_msp.c;main.c;
[PreviousLibFiles]
LibFiles=Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f405xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Drivers/CMSIS/Include/arm_common_tables.h;Drivers/CMSIS/Include/arm_const_structs.h;Drivers/CMSIS/Include/arm_math.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armcc_V6.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cmFunc.h;Drivers/CMSIS/Include/core_cmInstr.h;Drivers/CMSIS/Include/core_cmSimd.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;
[PreviousUsedIarFiles]
SourceFiles=..\Src\main.c;..\Src\stm32f4xx_it.c;..\Src\stm32f4xx_hal_msp.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../\Src/system_stm32f4xx.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../\Src/system_stm32f4xx.c;../Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;null;
HeaderPath=..\Drivers\STM32F4xx_HAL_Driver\Inc;..\Drivers\STM32F4xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F4xx\Include;..\Drivers\CMSIS\Include;..\Inc;
[PreviousUsedKeilFiles]
SourceFiles=..\Src\main.c;..\Src\stm32f4xx_it.c;..\Src\stm32f4xx_hal_msp.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../\Src/system_stm32f4xx.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../\Src/system_stm32f4xx.c;../Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;null;
HeaderPath=..\Drivers\STM32F4xx_HAL_Driver\Inc;..\Drivers\STM32F4xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F4xx\Include;..\Drivers\CMSIS\Include;..\Inc;
@@ -0,0 +1,110 @@
#MicroXplorer Configuration settings - do not modify
File.Version=6
KeepUserPlacement=false
Mcu.Family=STM32F4
Mcu.IP0=NVIC
Mcu.IP1=RCC
Mcu.IP2=SYS
Mcu.IP3=USART2
Mcu.IPNb=4
Mcu.Name=STM32F405RGTx
Mcu.Package=LQFP64
Mcu.Pin0=PC14-OSC32_IN
Mcu.Pin1=PC15-OSC32_OUT
Mcu.Pin2=PH0-OSC_IN
Mcu.Pin3=PH1-OSC_OUT
Mcu.Pin4=PA2
Mcu.Pin5=PA3
Mcu.Pin6=VP_SYS_VS_Systick
Mcu.PinsNb=7
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F405RGTx
MxCube.Version=5.0.0
MxDb.Version=DB.5.0.0
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false
PA2.GPIOParameters=GPIO_PuPd
PA2.GPIO_PuPd=GPIO_PULLUP
PA2.Mode=Asynchronous
PA2.Signal=USART2_TX
PA3.GPIOParameters=GPIO_PuPd
PA3.GPIO_PuPd=GPIO_PULLUP
PA3.Mode=Asynchronous
PA3.Signal=USART2_RX
PC14-OSC32_IN.Mode=LSE-External-Oscillator
PC14-OSC32_IN.Signal=RCC_OSC32_IN
PC15-OSC32_OUT.Mode=LSE-External-Oscillator
PC15-OSC32_OUT.Signal=RCC_OSC32_OUT
PCC.Checker=false
PCC.Line=STM32F405/415
PCC.MCU=STM32F405RGTx
PCC.PartNumber=STM32F405RGTx
PCC.Seq0=0
PCC.Series=STM32F4
PCC.Temperature=25
PCC.Vdd=3.3
PH0-OSC_IN.Mode=HSE-External-Oscillator
PH0-OSC_IN.Signal=RCC_OSC_IN
PH1-OSC_OUT.Mode=HSE-External-Oscillator
PH1-OSC_OUT.Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=false
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32F405RGTx
ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.23.0
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x200
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=0
ProjectManager.MainLocation=Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=CubeMX_Config.ioc
ProjectManager.ProjectName=CubeMX_Config
ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=EWARM V8
ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USART2_UART_Init-USART2-false-HAL-true
RCC.AHBFreq_Value=16000000
RCC.APB1Freq_Value=16000000
RCC.APB2Freq_Value=16000000
RCC.CortexFreq_Value=16000000
RCC.FamilyName=M
RCC.HSE_VALUE=8000000
RCC.HSI_VALUE=16000000
RCC.I2SClocksFreq_Value=96000000
RCC.IPParameters=AHBFreq_Value,APB1Freq_Value,APB2Freq_Value,CortexFreq_Value,FamilyName,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSI_VALUE,PLLCLKFreq_Value,PLLQCLKFreq_Value,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S
RCC.LSI_VALUE=32000
RCC.PLLCLKFreq_Value=96000000
RCC.PLLQCLKFreq_Value=48000000
RCC.RTCFreq_Value=32000
RCC.RTCHSEDivFreq_Value=4000000
RCC.SYSCLKFreq_VALUE=16000000
RCC.VCOI2SOutputFreq_Value=192000000
RCC.VCOInputFreq_Value=1000000
RCC.VCOOutputFreq_Value=192000000
RCC.VcooutputI2S=96000000
USART2.IPParameters=VirtualMode
USART2.VirtualMode=VM_ASYNC
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
board=custom
+91
View File
@@ -0,0 +1,91 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.h
* @brief : Header for main.c file.
* This file contains the common defines of the application.
******************************************************************************
** This notice applies to any and all portions of this file
* that are not between comment pairs USER CODE BEGIN and
* USER CODE END. Other portions of this file, whether
* inserted by the user or by software development tools
* are owned by their respective copyright owners.
*
* COPYRIGHT(c) 2018 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,451 @@
/**
******************************************************************************
* @file stm32f4xx_hal_conf.h
* @brief HAL configuration file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_HAL_CONF_H
#define __STM32F4xx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
/* #define HAL_ADC_MODULE_ENABLED */
/* #define HAL_CRYP_MODULE_ENABLED */
/* #define HAL_CAN_MODULE_ENABLED */
/* #define HAL_CRC_MODULE_ENABLED */
/* #define HAL_CRYP_MODULE_ENABLED */
/* #define HAL_DAC_MODULE_ENABLED */
/* #define HAL_DCMI_MODULE_ENABLED */
/* #define HAL_DMA2D_MODULE_ENABLED */
/* #define HAL_ETH_MODULE_ENABLED */
/* #define HAL_NAND_MODULE_ENABLED */
/* #define HAL_NOR_MODULE_ENABLED */
/* #define HAL_PCCARD_MODULE_ENABLED */
/* #define HAL_SRAM_MODULE_ENABLED */
/* #define HAL_SDRAM_MODULE_ENABLED */
/* #define HAL_HASH_MODULE_ENABLED */
/* #define HAL_I2C_MODULE_ENABLED */
/* #define HAL_I2S_MODULE_ENABLED */
/* #define HAL_IWDG_MODULE_ENABLED */
/* #define HAL_LTDC_MODULE_ENABLED */
/* #define HAL_RNG_MODULE_ENABLED */
/* #define HAL_RTC_MODULE_ENABLED */
/* #define HAL_SAI_MODULE_ENABLED */
/* #define HAL_SD_MODULE_ENABLED */
/* #define HAL_MMC_MODULE_ENABLED */
/* #define HAL_SPI_MODULE_ENABLED */
/* #define HAL_TIM_MODULE_ENABLED */
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
/* #define HAL_SMARTCARD_MODULE_ENABLED */
/* #define HAL_WWDG_MODULE_ENABLED */
/* #define HAL_PCD_MODULE_ENABLED */
/* #define HAL_HCD_MODULE_ENABLED */
/* #define HAL_DSI_MODULE_ENABLED */
/* #define HAL_QSPI_MODULE_ENABLED */
/* #define HAL_QSPI_MODULE_ENABLED */
/* #define HAL_CEC_MODULE_ENABLED */
/* #define HAL_FMPI2C_MODULE_ENABLED */
/* #define HAL_SPDIFRX_MODULE_ENABLED */
/* #define HAL_DFSDM_MODULE_ENABLED */
/* #define HAL_LPTIM_MODULE_ENABLED */
/* #define HAL_EXTI_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
/* ########################## HSE/HSI Values adaptation ##################### */
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @brief Internal Low Speed oscillator (LSI) value.
*/
#if !defined (LSI_VALUE)
#define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
/**
* @brief External Low Speed oscillator (LSE) value.
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */
#endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
#endif /* LSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for I2S peripheral
* This value is used by the I2S HAL module to compute the I2S clock source
* frequency, this source is inserted directly through I2S_CKIN pad.
*/
#if !defined (EXTERNAL_CLOCK_VALUE)
#define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/
#endif /* EXTERNAL_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 1U
#define INSTRUCTION_CACHE_ENABLE 1U
#define DATA_CACHE_ENABLE 1U
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* ################## Ethernet peripheral configuration ##################### */
/* Section 1 : Ethernet peripheral configuration */
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
#define MAC_ADDR0 2U
#define MAC_ADDR1 0U
#define MAC_ADDR2 0U
#define MAC_ADDR3 0U
#define MAC_ADDR4 0U
#define MAC_ADDR5 0U
/* Definition of the Ethernet driver buffers size and count */
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
/* Section 2: PHY configuration section */
/* DP83848_PHY_ADDRESS Address*/
#define DP83848_PHY_ADDRESS 0x01U
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
#define PHY_RESET_DELAY ((uint32_t)0x000000FFU)
/* PHY Configuration delay */
#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU)
#define PHY_READ_TO ((uint32_t)0x0000FFFFU)
#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
/* Section 3: Common PHY Registers */
#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
/* Section 4: Extended PHY Registers */
#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 0U
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include module's header file
*/
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32f4xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32f4xx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32f4xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32f4xx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32f4xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32f4xx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_CAN_MODULE_ENABLED
#include "stm32f4xx_hal_can.h"
#endif /* HAL_CAN_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32f4xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
#include "stm32f4xx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_DMA2D_MODULE_ENABLED
#include "stm32f4xx_hal_dma2d.h"
#endif /* HAL_DMA2D_MODULE_ENABLED */
#ifdef HAL_DAC_MODULE_ENABLED
#include "stm32f4xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */
#ifdef HAL_DCMI_MODULE_ENABLED
#include "stm32f4xx_hal_dcmi.h"
#endif /* HAL_DCMI_MODULE_ENABLED */
#ifdef HAL_ETH_MODULE_ENABLED
#include "stm32f4xx_hal_eth.h"
#endif /* HAL_ETH_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32f4xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_SRAM_MODULE_ENABLED
#include "stm32f4xx_hal_sram.h"
#endif /* HAL_SRAM_MODULE_ENABLED */
#ifdef HAL_NOR_MODULE_ENABLED
#include "stm32f4xx_hal_nor.h"
#endif /* HAL_NOR_MODULE_ENABLED */
#ifdef HAL_NAND_MODULE_ENABLED
#include "stm32f4xx_hal_nand.h"
#endif /* HAL_NAND_MODULE_ENABLED */
#ifdef HAL_PCCARD_MODULE_ENABLED
#include "stm32f4xx_hal_pccard.h"
#endif /* HAL_PCCARD_MODULE_ENABLED */
#ifdef HAL_SDRAM_MODULE_ENABLED
#include "stm32f4xx_hal_sdram.h"
#endif /* HAL_SDRAM_MODULE_ENABLED */
#ifdef HAL_HASH_MODULE_ENABLED
#include "stm32f4xx_hal_hash.h"
#endif /* HAL_HASH_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32f4xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_I2S_MODULE_ENABLED
#include "stm32f4xx_hal_i2s.h"
#endif /* HAL_I2S_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32f4xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_LTDC_MODULE_ENABLED
#include "stm32f4xx_hal_ltdc.h"
#endif /* HAL_LTDC_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32f4xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
#include "stm32f4xx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32f4xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SAI_MODULE_ENABLED
#include "stm32f4xx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */
#ifdef HAL_SD_MODULE_ENABLED
#include "stm32f4xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
#ifdef HAL_MMC_MODULE_ENABLED
#include "stm32f4xx_hal_mmc.h"
#endif /* HAL_MMC_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32f4xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32f4xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32f4xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32f4xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32f4xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32f4xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32f4xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32f4xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_HCD_MODULE_ENABLED
#include "stm32f4xx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
#ifdef HAL_DSI_MODULE_ENABLED
#include "stm32f4xx_hal_dsi.h"
#endif /* HAL_DSI_MODULE_ENABLED */
#ifdef HAL_QSPI_MODULE_ENABLED
#include "stm32f4xx_hal_qspi.h"
#endif /* HAL_QSPI_MODULE_ENABLED */
#ifdef HAL_CEC_MODULE_ENABLED
#include "stm32f4xx_hal_cec.h"
#endif /* HAL_CEC_MODULE_ENABLED */
#ifdef HAL_FMPI2C_MODULE_ENABLED
#include "stm32f4xx_hal_fmpi2c.h"
#endif /* HAL_FMPI2C_MODULE_ENABLED */
#ifdef HAL_SPDIFRX_MODULE_ENABLED
#include "stm32f4xx_hal_spdifrx.h"
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
#ifdef HAL_DFSDM_MODULE_ENABLED
#include "stm32f4xx_hal_dfsdm.h"
#endif /* HAL_DFSDM_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
#include "stm32f4xx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr: If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* __STM32F4xx_HAL_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,84 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f4xx_it.h
* @brief This file contains the headers of the interrupt handlers.
******************************************************************************
*
* COPYRIGHT(c) 2018 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_IT_H
#define __STM32F4xx_IT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
#ifdef __cplusplus
}
#endif
#endif /* __STM32F4xx_IT_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,208 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : stm32f4xx_hal_msp.c
* Description : This file provides code for the MSP Initialization
* and de-Initialization codes.
******************************************************************************
** This notice applies to any and all portions of this file
* that are not between comment pairs USER CODE BEGIN and
* USER CODE END. Other portions of this file, whether
* inserted by the user or by software development tools
* are owned by their respective copyright owners.
*
* COPYRIGHT(c) 2018 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
#include <drv_common.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Define */
/* USER CODE END Define */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
/* USER CODE END Macro */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* External functions --------------------------------------------------------*/
/* USER CODE BEGIN ExternalFunctions */
/* USER CODE END ExternalFunctions */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
/* System interrupt init*/
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
/**
* @brief UART MSP Initialization
* This function configures the hardware resources used in this example
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(huart->Instance==USART1) {
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
} else if(huart->Instance==USART2) {
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
}
/**
* @brief UART MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{
if(huart->Instance==USART1) {
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA3 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
} else if(huart->Instance==USART2) {
/* USER CODE BEGIN USART2_MspDeInit 0 */
/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
/* USER CODE BEGIN USART2_MspDeInit 1 */
/* USER CODE END USART2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,217 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f4xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
*
* COPYRIGHT(c) 2018 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
* @brief This function handles Pre-fetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+100
View File
@@ -0,0 +1,100 @@
menu "Hardware Drivers Config"
menu "Onboard Peripheral Drivers"
endmenu
menu "On-chip Peripheral Drivers"
config BSP_USING_GPIO
bool "Enable GPIO"
select RT_USING_PIN
default y
menuconfig BSP_USING_UART
bool "Enable UART"
default y
select RT_USING_SERIAL
if BSP_USING_UART
config BSP_STM32_UART_V1_TX_TIMEOUT
int "UART TX timeout"
default 2000
depends on RT_USING_SERIAL_V1
config BSP_USING_UART1
bool "Enable UART1"
default y
config BSP_UART1_RX_USING_DMA
bool "Enable UART1 RX DMA"
depends on BSP_USING_UART1
select RT_SERIAL_USING_DMA
default n
config BSP_UART1_TX_USING_DMA
bool "Enable UART1 TX DMA"
depends on BSP_USING_UART1
select RT_SERIAL_USING_DMA
default n
config BSP_UART1_RX_BUFSIZE
int "Set UART1 RX buffer size"
range 64 65535
depends on BSP_USING_UART1 && RT_USING_SERIAL_V2
default 64
config BSP_UART1_TX_BUFSIZE
int "Set UART1 TX buffer size"
range 0 65535
depends on BSP_USING_UART1 && RT_USING_SERIAL_V2
default 0
config BSP_UART1_DMA_PING_BUFSIZE
int "Set UART1 RX DMA ping-pong buffer size"
range 32 65535
depends on RT_USING_SERIAL_V2 && BSP_UART1_RX_USING_DMA
default 32
config BSP_USING_UART2
bool "Enable UART2"
default y
config BSP_UART2_RX_USING_DMA
bool "Enable UART2 RX DMA"
depends on BSP_USING_UART2
select RT_SERIAL_USING_DMA
default n
config BSP_UART2_TX_USING_DMA
bool "Enable UART2 TX DMA"
depends on BSP_USING_UART2
select RT_SERIAL_USING_DMA
default n
config BSP_UART2_RX_BUFSIZE
int "Set UART2 RX buffer size"
range 64 65535
depends on BSP_USING_UART2 && RT_USING_SERIAL_V2
default 64
config BSP_UART2_TX_BUFSIZE
int "Set UART2 TX buffer size"
range 0 65535
depends on BSP_USING_UART2 && RT_USING_SERIAL_V2
default 0
config BSP_UART2_DMA_PING_BUFSIZE
int "Set UART2 RX DMA ping-pong buffer size"
range 32 65535
depends on RT_USING_SERIAL_V2 && BSP_UART2_RX_USING_DMA
default 32
endif
source "$(RTT_DIR)/bsp/stm32/libraries/HAL_Drivers/drivers/Kconfig"
endmenu
menu "Board extended module Drivers"
endmenu
endmenu
+27
View File
@@ -0,0 +1,27 @@
import os
from building import *
cwd = GetCurrentDir()
# add general drivers
src = Split('''
board.c
CubeMX_Config/Src/stm32f4xx_hal_msp.c
''')
path = [cwd]
path += [os.path.join(cwd, 'CubeMX_Config', 'Inc')]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
# if os.path.isfile(os.path.join(cwd, "ports", 'SConscript')):
# group = group + SConscript(os.path.join("ports", 'SConscript'))
list = os.listdir(cwd)
for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
group = group + SConscript(os.path.join(item, 'SConscript'))
Return('group')
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-06 SummerGift first version
*/
#include <board.h>
#include <drv_common.h>
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/**Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
+47
View File
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-5 SummerGift first version
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <stm32f4xx.h>
#ifdef __cplusplus
extern "C" {
#endif
#define STM32_FLASH_START_ADRESS ((uint32_t)0x08000000)
#define STM32_FLASH_SIZE (1024 * 1024)
#define STM32_FLASH_END_ADDRESS ((uint32_t)(STM32_FLASH_START_ADRESS + STM32_FLASH_SIZE))
#define STM32_SRAM_SIZE (128)
#define STM32_SRAM_END (0x20000000 + STM32_SRAM_SIZE * 1024)
#if defined(__ARMCC_VERSION)
extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit)
#elif __ICCARM__
#pragma section="CSTACK"
#define HEAP_BEGIN (__segment_end("CSTACK"))
#else
extern int __bss_end;
#define HEAP_BEGIN (&__bss_end)
#endif
#define HEAP_END STM32_SRAM_END
void SystemClock_Config(void);
#ifdef __cplusplus
}
#endif
#endif
+30
View File
@@ -0,0 +1,30 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
define symbol __ICFEDIT_region_RAM1_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM1_end__ = 0x2001FFFF;
define symbol __ICFEDIT_region_RAM2_start__ = 0x10000000;
define symbol __ICFEDIT_region_RAM2_end__ = 0x1000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x0400;
define symbol __ICFEDIT_size_heap__ = 0x000;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM1_region = mem:[from __ICFEDIT_region_RAM1_start__ to __ICFEDIT_region_RAM1_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM1_region { readwrite, last block CSTACK };
+159
View File
@@ -0,0 +1,159 @@
/*
* linker script for STM32F4xx with GNU ld
* bernard.xiong 2009-10-14
* flybreak 2018-11-19 Add support for RAM2
*/
/* Program Entry, set to mark it as "used" and avoid gc */
MEMORY
{
CODE (rx) : ORIGIN = 0x08000000, LENGTH = 1024k /* 1024KB flash */
RAM1 (rw) : ORIGIN = 0x20000000, LENGTH = 128k /* 128K sram */
RAM2 (rw) : ORIGIN = 0x10000000, LENGTH = 64k /* 64K sram */
}
ENTRY(Reset_Handler)
_system_stack_size = 0x400;
SECTIONS
{
.text :
{
. = ALIGN(4);
_stext = .;
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t*)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
PROVIDE(__ctors_start__ = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE(__ctors_end__ = .);
. = ALIGN(4);
_etext = .;
} > CODE = 0
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
/* This is used by the startup in order to initialize the .data secion */
_sidata = .;
} > CODE
__exidx_end = .;
/* .data section which is used for initialized data */
.data : AT (_sidata)
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_sdata = . ;
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
PROVIDE(__dtors_start__ = .);
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
PROVIDE(__dtors_end__ = .);
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_edata = . ;
} >RAM1
.stack :
{
. = ALIGN(4);
_sstack = .;
. = . + _system_stack_size;
. = ALIGN(4);
_estack = .;
} >RAM1
__bss_start = .;
.bss :
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_ebss = . ;
*(.bss.init)
} > RAM1
__bss_end = .;
_end = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
File diff suppressed because it is too large Load Diff
+483
View File
@@ -0,0 +1,483 @@
#ifndef RT_CONFIG_H__
#define RT_CONFIG_H__
#define SOC_STM32F405RG
/* RT-Thread Kernel */
/* klibc options */
/* rt_vsnprintf options */
/* end of rt_vsnprintf options */
/* rt_vsscanf options */
/* end of rt_vsscanf options */
/* rt_memset options */
/* end of rt_memset options */
/* rt_memcpy options */
/* end of rt_memcpy options */
/* rt_memmove options */
/* end of rt_memmove options */
/* rt_memcmp options */
/* end of rt_memcmp options */
/* rt_strstr options */
/* end of rt_strstr options */
/* rt_strcasecmp options */
/* end of rt_strcasecmp options */
/* rt_strncpy options */
/* end of rt_strncpy options */
/* rt_strcpy options */
/* end of rt_strcpy options */
/* rt_strncmp options */
/* end of rt_strncmp options */
/* rt_strcmp options */
/* end of rt_strcmp options */
/* rt_strlen options */
/* end of rt_strlen options */
/* rt_strnlen options */
/* end of rt_strnlen options */
/* end of klibc options */
#define RT_NAME_MAX 16
#define RT_CPUS_NR 1
#define RT_ALIGN_SIZE 8
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 1000
#define RT_USING_OVERFLOW_CHECK
#define RT_USING_HOOK
#define RT_HOOK_USING_FUNC_PTR
#define RT_USING_IDLE_HOOK
#define RT_IDLE_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 256
/* kservice options */
/* end of kservice options */
#define RT_USING_DEBUG
#define RT_DEBUGING_ASSERT
#define RT_DEBUGING_COLOR
#define RT_DEBUGING_CONTEXT
/* Inter-Thread communication */
#define RT_USING_SEMAPHORE
#define RT_USING_MUTEX
#define RT_USING_EVENT
#define RT_USING_MAILBOX
#define RT_USING_MESSAGEQUEUE
/* end of Inter-Thread communication */
/* Memory Management */
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
#define RT_USING_HEAP
/* end of Memory Management */
#define RT_USING_DEVICE
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLE_DEVICE_NAME "uart1"
#define RT_VER_NUM 0x50201
#define RT_BACKTRACE_LEVEL_MAX_NR 32
/* end of RT-Thread Kernel */
#define RT_USING_HW_ATOMIC
#define RT_USING_CPU_FFS
#define ARCH_ARM
#define ARCH_ARM_CORTEX_M
#define ARCH_ARM_CORTEX_M4
/* RT-Thread Components */
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE 2048
#define RT_MAIN_THREAD_PRIORITY 10
#define RT_USING_MSH
#define RT_USING_FINSH
#define FINSH_USING_MSH
#define FINSH_THREAD_NAME "tshell"
#define FINSH_THREAD_PRIORITY 20
#define FINSH_THREAD_STACK_SIZE 4096
#define FINSH_USING_HISTORY
#define FINSH_HISTORY_LINES 5
#define FINSH_USING_SYMTAB
#define FINSH_CMD_SIZE 80
#define MSH_USING_BUILT_IN_COMMANDS
#define FINSH_USING_DESCRIPTION
#define FINSH_ARG_MAX 10
#define FINSH_USING_OPTION_COMPLETION
/* DFS: device virtual file system */
/* end of DFS: device virtual file system */
/* Device Drivers */
#define RT_USING_DEVICE_IPC
#define RT_UNAMED_PIPE_NUMBER 64
#define RT_USING_SYSTEM_WORKQUEUE
#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048
#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
#define RT_USING_SERIAL
#define RT_USING_SERIAL_V1
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_PIN
/* end of Device Drivers */
/* C/C++ and POSIX layer */
/* ISO-ANSI C layer */
/* Timezone and Daylight Saving Time */
#define RT_LIBC_USING_LIGHT_TZ_DST
#define RT_LIBC_TZ_DEFAULT_HOUR 8
#define RT_LIBC_TZ_DEFAULT_MIN 0
#define RT_LIBC_TZ_DEFAULT_SEC 0
/* end of Timezone and Daylight Saving Time */
/* end of ISO-ANSI C layer */
/* POSIX (Portable Operating System Interface) layer */
/* Interprocess Communication (IPC) */
/* Socket is in the 'Network' category */
/* end of Interprocess Communication (IPC) */
/* end of POSIX (Portable Operating System Interface) layer */
/* end of C/C++ and POSIX layer */
/* Network */
#define RT_USING_SAL
#define SAL_INTERNET_CHECK
/* Docking with protocol stacks */
/* end of Docking with protocol stacks */
#define SAL_SOCKETS_NUM 16
#define RT_USING_NETDEV
#define NETDEV_USING_IFCONFIG
#define NETDEV_USING_PING
#define NETDEV_USING_NETSTAT
#define NETDEV_USING_AUTO_DEFAULT
#define NETDEV_IPV4 1
#define NETDEV_IPV6 0
/* end of Network */
/* Memory protection */
/* end of Memory protection */
/* Utilities */
/* end of Utilities */
/* Using USB legacy version */
/* end of Using USB legacy version */
/* end of RT-Thread Components */
/* RT-Thread online packages */
/* IoT - internet of things */
#define PKG_USING_FREEMODBUS
#define PKG_MODBUS_MASTER
/* advanced configuration */
#define RT_M_DISCRETE_INPUT_START 0
#define RT_M_DISCRETE_INPUT_NDISCRETES 16
#define RT_M_COIL_START 0
#define RT_M_COIL_NCOILS 64
#define RT_M_REG_INPUT_START 0
#define RT_M_REG_INPUT_NREGS 100
#define RT_M_REG_HOLDING_START 0
#define RT_M_REG_HOLDING_NREGS 100
#define RT_M_HD_RESERVE 0
#define RT_M_IN_RESERVE 0
#define RT_M_CO_RESERVE 0
#define RT_M_DI_RESERVE 0
/* end of advanced configuration */
#define PKG_MODBUS_MASTER_RTU
#define PKG_MODBUS_MASTER_SAMPLE
#define MB_SAMPLE_TEST_SLAVE_ADDR 1
#define MB_MASTER_USING_PORT_NUM 1
#define MB_MASTER_USING_PORT_BAUDRATE 115200
#define PKG_MODBUS_SLAVE
/* advanced configuration */
#define RT_S_DISCRETE_INPUT_START 0
#define RT_S_DISCRETE_INPUT_NDISCRETES 16
#define RT_S_COIL_START 0
#define RT_S_COIL_NCOILS 64
#define RT_S_REG_INPUT_START 0
#define RT_S_REG_INPUT_NREGS 100
#define RT_S_REG_HOLDING_START 0
#define RT_S_REG_HOLDING_NREGS 100
#define RT_S_HD_RESERVE 0
#define RT_S_IN_RESERVE 0
#define RT_S_CO_RESERVE 0
#define RT_S_DI_RESERVE 0
/* end of advanced configuration */
#define PKG_MODBUS_SLAVE_RTU
#define PKG_MODBUS_SLAVE_SAMPLE
#define MB_SAMPLE_SLAVE_ADDR 1
#define MB_SLAVE_USING_PORT_NUM 2
#define MB_SLAVE_USING_PORT_BAUDRATE 115200
#define PKG_USING_FREEMODBUS_LATEST_VERSION
/* Wi-Fi */
/* Marvell WiFi */
/* end of Marvell WiFi */
/* Wiced WiFi */
/* end of Wiced WiFi */
/* CYW43012 WiFi */
/* end of CYW43012 WiFi */
/* BL808 WiFi */
/* end of BL808 WiFi */
/* CYW43439 WiFi */
/* end of CYW43439 WiFi */
/* end of Wi-Fi */
/* IoT Cloud */
/* end of IoT Cloud */
/* end of IoT - internet of things */
/* security packages */
/* end of security packages */
/* language packages */
/* JSON: JavaScript Object Notation, a lightweight data-interchange format */
/* end of JSON: JavaScript Object Notation, a lightweight data-interchange format */
/* XML: Extensible Markup Language */
/* end of XML: Extensible Markup Language */
/* end of language packages */
/* multimedia packages */
/* LVGL: powerful and easy-to-use embedded GUI library */
/* end of LVGL: powerful and easy-to-use embedded GUI library */
/* u8g2: a monochrome graphic library */
/* end of u8g2: a monochrome graphic library */
/* end of multimedia packages */
/* tools packages */
/* end of tools packages */
/* system packages */
/* enhanced kernel services */
/* end of enhanced kernel services */
/* acceleration: Assembly language or algorithmic acceleration packages */
/* end of acceleration: Assembly language or algorithmic acceleration packages */
/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
#define PKG_USING_CMSIS_CORE
#define PKG_USING_CMSIS_CORE_LATEST_VERSION
/* end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
/* Micrium: Micrium software products porting for RT-Thread */
/* end of Micrium: Micrium software products porting for RT-Thread */
/* end of system packages */
/* peripheral libraries and drivers */
/* HAL & SDK Drivers */
/* STM32 HAL & SDK Drivers */
#define PKG_USING_STM32F4_HAL_DRIVER
#define PKG_USING_STM32F4_HAL_DRIVER_LATEST_VERSION
#define PKG_USING_STM32F4_CMSIS_DRIVER
#define PKG_USING_STM32F4_CMSIS_DRIVER_LATEST_VERSION
/* end of STM32 HAL & SDK Drivers */
/* Infineon HAL Packages */
/* end of Infineon HAL Packages */
/* Kendryte SDK */
/* end of Kendryte SDK */
/* WCH HAL & SDK Drivers */
/* end of WCH HAL & SDK Drivers */
/* AT32 HAL & SDK Drivers */
/* end of AT32 HAL & SDK Drivers */
/* HC32 DDL Drivers */
/* end of HC32 DDL Drivers */
/* NXP HAL & SDK Drivers */
/* end of NXP HAL & SDK Drivers */
/* NUVOTON Drivers */
/* end of NUVOTON Drivers */
/* GD32 Drivers */
/* end of GD32 Drivers */
/* end of HAL & SDK Drivers */
/* sensors drivers */
/* end of sensors drivers */
/* touch drivers */
/* end of touch drivers */
/* end of peripheral libraries and drivers */
/* AI packages */
/* end of AI packages */
/* Signal Processing and Control Algorithm Packages */
/* end of Signal Processing and Control Algorithm Packages */
/* miscellaneous packages */
/* project laboratory */
/* end of project laboratory */
/* samples: kernel and components samples */
/* end of samples: kernel and components samples */
/* entertainment: terminal games and other interesting software packages */
/* end of entertainment: terminal games and other interesting software packages */
/* end of miscellaneous packages */
/* Arduino libraries */
/* Projects and Demos */
/* end of Projects and Demos */
/* Sensors */
/* end of Sensors */
/* Display */
/* end of Display */
/* Timing */
/* end of Timing */
/* Data Processing */
/* end of Data Processing */
/* Data Storage */
/* Communication */
/* end of Communication */
/* Device Control */
/* end of Device Control */
/* Other */
/* end of Other */
/* Signal IO */
/* end of Signal IO */
/* Uncategorized */
/* end of Arduino libraries */
/* end of RT-Thread online packages */
#define SOC_FAMILY_STM32
#define SOC_SERIES_STM32F4
/* Hardware Drivers Config */
/* Onboard Peripheral Drivers */
/* On-chip Peripheral Drivers */
#define BSP_USING_GPIO
#define BSP_USING_UART
#define BSP_STM32_UART_V1_TX_TIMEOUT 2000
#define BSP_USING_UART1
#define BSP_USING_UART2
/* end of On-chip Peripheral Drivers */
/* Board extended module Drivers */
/* end of Hardware Drivers Config */
#endif
+184
View File
@@ -0,0 +1,184 @@
import os
# toolchains options
ARCH='arm'
CPU='cortex-m4'
CROSS_TOOL='gcc'
# bsp lib config
BSP_LIBRARY_TYPE = None
if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC')
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
# cross_tool provides the cross compiler
# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = r'/usr/bin'
elif CROSS_TOOL == 'keil':
PLATFORM = 'armcc'
EXEC_PATH = r'C:/Keil_v5'
elif CROSS_TOOL == 'iar':
PLATFORM = 'iccarm'
EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.3'
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
BUILD = 'debug'
if PLATFORM == 'gcc':
# toolchains
PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
CXX = PREFIX + 'g++'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections'
CFLAGS = DEVICE + ' -Dgcc'
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb '
LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.lds'
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -gdwarf-2 -g'
AFLAGS += ' -gdwarf-2'
else:
CFLAGS += ' -O2'
CXXFLAGS = CFLAGS
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
elif PLATFORM == 'armcc':
# toolchains
CC = 'armcc'
CXX = 'armcc'
AS = 'armasm'
AR = 'armar'
LINK = 'armlink'
TARGET_EXT = 'axf'
DEVICE = ' --cpu Cortex-M4.fp '
CFLAGS = '-c ' + DEVICE + ' --apcs=interwork --c99'
AFLAGS = DEVICE + ' --apcs=interwork '
LFLAGS = DEVICE + ' --scatter "board\linker_scripts\link.sct" --info sizes --info totals --info unused --info veneers --list rt-thread.map --strict'
CFLAGS += ' -I' + EXEC_PATH + '/ARM/ARMCC/include'
LFLAGS += ' --libpath=' + EXEC_PATH + '/ARM/ARMCC/lib'
CFLAGS += ' -D__MICROLIB '
AFLAGS += ' --pd "__MICROLIB SETA 1" '
LFLAGS += ' --library_type=microlib '
EXEC_PATH += '/ARM/ARMCC/bin/'
if BUILD == 'debug':
CFLAGS += ' -g -O0'
AFLAGS += ' -g'
else:
CFLAGS += ' -O2'
CXXFLAGS = CFLAGS
CFLAGS += ' -std=c99'
POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET'
elif PLATFORM == 'armclang':
# toolchains
CC = 'armclang'
CXX = 'armclang'
AS = 'armasm'
AR = 'armar'
LINK = 'armlink'
TARGET_EXT = 'axf'
DEVICE = ' --cpu Cortex-M4.fp '
CFLAGS = ' --target=arm-arm-none-eabi -mcpu=cortex-m4 '
CFLAGS += ' -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 '
CFLAGS += ' -mfloat-abi=hard -c -fno-rtti -funsigned-char -fshort-enums -fshort-wchar '
CFLAGS += ' -gdwarf-3 -ffunction-sections '
AFLAGS = DEVICE + ' --apcs=interwork '
LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers '
LFLAGS += ' --list rt-thread.map '
LFLAGS += r' --strict --scatter "board\linker_scripts\link.sct" '
CFLAGS += ' -I' + EXEC_PATH + '/ARM/ARMCLANG/include'
LFLAGS += ' --libpath=' + EXEC_PATH + '/ARM/ARMCLANG/lib'
EXEC_PATH += '/ARM/ARMCLANG/bin/'
if BUILD == 'debug':
CFLAGS += ' -g -O1' # armclang recommend
AFLAGS += ' -g'
else:
CFLAGS += ' -O2'
CXXFLAGS = CFLAGS
CFLAGS += ' -std=c99'
POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET'
elif PLATFORM == 'iccarm':
# toolchains
CC = 'iccarm'
CXX = 'iccarm'
AS = 'iasmarm'
AR = 'iarchive'
LINK = 'ilinkarm'
TARGET_EXT = 'out'
DEVICE = '-Dewarm'
CFLAGS = DEVICE
CFLAGS += ' --diag_suppress Pa050'
CFLAGS += ' --no_cse'
CFLAGS += ' --no_unroll'
CFLAGS += ' --no_inline'
CFLAGS += ' --no_code_motion'
CFLAGS += ' --no_tbaa'
CFLAGS += ' --no_clustering'
CFLAGS += ' --no_scheduling'
CFLAGS += ' --endian=little'
CFLAGS += ' --cpu=Cortex-M4'
CFLAGS += ' -e'
CFLAGS += ' --fpu=VFPv4_sp'
CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"'
CFLAGS += ' --silent'
AFLAGS = DEVICE
AFLAGS += ' -s+'
AFLAGS += ' -w+'
AFLAGS += ' -r'
AFLAGS += ' --cpu Cortex-M4'
AFLAGS += ' --fpu VFPv4_sp'
AFLAGS += ' -S'
if BUILD == 'debug':
CFLAGS += ' --debug'
CFLAGS += ' -On'
else:
CFLAGS += ' -Oh'
LFLAGS = ' --config "board/linker_scripts/link.icf"'
LFLAGS += ' --entry __iar_program_start'
CXXFLAGS = CFLAGS
EXEC_PATH = EXEC_PATH + '/arm/bin/'
POST_ACTION = 'ielftool --bin $TARGET rtthread.bin'
def dist_handle(BSP_ROOT, dist_dir):
import sys
cwd_path = os.getcwd()
sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools'))
from sdk_dist import dist_do_building
dist_do_building(BSP_ROOT, dist_dir)
+390
View File
@@ -0,0 +1,390 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
<SchemaVersion>2.1</SchemaVersion>
<Header>### uVision Project, (C) Keil Software</Header>
<Targets>
<Target>
<TargetName>rt-thread</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<uAC6>0</uAC6>
<TargetOption>
<TargetCommonOption>
<Device>STM32F405RG</Device>
<Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32F4xx_DFP.3.1.0</PackID>
<PackURL>https://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x20000000-0x2001FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) CPUTYPE("Cortex-M4") FPU2</Cpu>
<FlashUtilSpec></FlashUtilSpec>
<StartupFile>"Startup\ST\STM32F4xx\startup_stm32f40_41xxx.s" ("STM32F40/41xxx Startup Code")</StartupFile>
<FlashDriverDll>UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F4xx_1024 -FS08000000 -FL0100000)</FlashDriverDll>
<DeviceId>6100</DeviceId>
<RegisterFile>stm32f4xx.h</RegisterFile>
<MemoryEnv></MemoryEnv>
<Cmp></Cmp>
<Asm></Asm>
<Linker></Linker>
<OHString></OHString>
<InfinionOptionDll></InfinionOptionDll>
<SLE66CMisc>-DSTM32F40_41xxx</SLE66CMisc>
<SLE66AMisc></SLE66AMisc>
<SLE66LinkerMisc></SLE66LinkerMisc>
<SFDFile>SFD\ST\STM32F4xx\STM32F40x.sfr</SFDFile>
<bCustSvd>0</bCustSvd>
<UseEnv>0</UseEnv>
<BinPath></BinPath>
<IncludePath></IncludePath>
<LibPath></LibPath>
<RegisterFilePath>ST\STM32F4xx\</RegisterFilePath>
<DBRegisterFilePath>ST\STM32F4xx\</DBRegisterFilePath>
<TargetStatus>
<Error>0</Error>
<ExitCodeStop>0</ExitCodeStop>
<ButtonStop>0</ButtonStop>
<NotGenerated>0</NotGenerated>
<InvalidFlash>1</InvalidFlash>
</TargetStatus>
<OutputDirectory>.\build\keil\Obj\</OutputDirectory>
<OutputName>rt-thread</OutputName>
<CreateExecutable>1</CreateExecutable>
<CreateLib>0</CreateLib>
<CreateHexFile>1</CreateHexFile>
<DebugInformation>1</DebugInformation>
<BrowseInformation>0</BrowseInformation>
<ListingPath>.\build\keil\List\</ListingPath>
<HexFormatSelection>1</HexFormatSelection>
<Merge32K>0</Merge32K>
<CreateBatchFile>0</CreateBatchFile>
<BeforeCompile>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopU1X>0</nStopU1X>
<nStopU2X>0</nStopU2X>
</BeforeCompile>
<BeforeMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopB1X>0</nStopB1X>
<nStopB2X>0</nStopB2X>
</BeforeMake>
<AfterMake>
<RunUserProg1>1</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name>fromelf --bin !L -o @L.bin</UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopA1X>0</nStopA1X>
<nStopA2X>0</nStopA2X>
</AfterMake>
<SelectedForBatchBuild>0</SelectedForBatchBuild>
<SVCSIdString></SVCSIdString>
</TargetCommonOption>
<CommonProperty>
<UseCPPCompiler>0</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>0</AlwaysBuild>
<GenerateAssemblyFile>0</GenerateAssemblyFile>
<AssembleAssemblyFile>0</AssembleAssemblyFile>
<PublicsOnly>0</PublicsOnly>
<StopOnExitCode>3</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<DllOption>
<SimDllName>SARMCM3.DLL</SimDllName>
<SimDllArguments>-MPU -REMAP</SimDllArguments>
<SimDlgDll>DCM.DLL</SimDlgDll>
<SimDlgDllArguments>-pCM4</SimDlgDllArguments>
<TargetDllName>SARMCM3.DLL</TargetDllName>
<TargetDllArguments>-MPU</TargetDllArguments>
<TargetDlgDll>TCM.DLL</TargetDlgDll>
<TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
</DllOption>
<DebugOption>
<OPTHX>
<HexSelection>1</HexSelection>
<HexRangeLowAddress>0</HexRangeLowAddress>
<HexRangeHighAddress>0</HexRangeHighAddress>
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
</DebugOption>
<Utilities>
<Flash1>
<UseTargetDll>1</UseTargetDll>
<UseExternalTool>0</UseExternalTool>
<RunIndependent>0</RunIndependent>
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
<Capability>1</Capability>
<DriverSelection>4096</DriverSelection>
</Flash1>
<bUseTDR>1</bUseTDR>
<Flash2>BIN\UL2CM3.DLL</Flash2>
<Flash3>"" ()</Flash3>
<Flash4></Flash4>
<pFcarmOut></pFcarmOut>
<pFcarmGrp></pFcarmGrp>
<pFcArmRoot></pFcArmRoot>
<FcArmLst>0</FcArmLst>
</Utilities>
<TargetArmAds>
<ArmAdsMisc>
<GenerateListings>0</GenerateListings>
<asHll>1</asHll>
<asAsm>1</asAsm>
<asMacX>1</asMacX>
<asSyms>1</asSyms>
<asFals>1</asFals>
<asDbgD>1</asDbgD>
<asForm>1</asForm>
<ldLst>0</ldLst>
<ldmm>1</ldmm>
<ldXref>1</ldXref>
<BigEnd>0</BigEnd>
<AdsALst>1</AdsALst>
<AdsACrf>1</AdsACrf>
<AdsANop>0</AdsANop>
<AdsANot>0</AdsANot>
<AdsLLst>1</AdsLLst>
<AdsLmap>1</AdsLmap>
<AdsLcgr>1</AdsLcgr>
<AdsLsym>1</AdsLsym>
<AdsLszi>1</AdsLszi>
<AdsLtoi>1</AdsLtoi>
<AdsLsun>1</AdsLsun>
<AdsLven>1</AdsLven>
<AdsLsxf>1</AdsLsxf>
<RvctClst>0</RvctClst>
<GenPPlst>0</GenPPlst>
<AdsCpuType>"Cortex-M4"</AdsCpuType>
<RvctDeviceName></RvctDeviceName>
<mOS>0</mOS>
<uocRom>0</uocRom>
<uocRam>0</uocRam>
<hadIROM>1</hadIROM>
<hadIRAM>1</hadIRAM>
<hadXRAM>0</hadXRAM>
<uocXRam>0</uocXRam>
<RvdsVP>1</RvdsVP>
<RvdsMve>0</RvdsMve>
<RvdsCdeCp>0</RvdsCdeCp>
<hadIRAM2>1</hadIRAM2>
<hadIROM2>0</hadIROM2>
<StupSel>8</StupSel>
<useUlib>0</useUlib>
<EndSel>0</EndSel>
<uLtcg>0</uLtcg>
<nSecure>0</nSecure>
<RoSelD>3</RoSelD>
<RwSelD>3</RwSelD>
<CodeSel>0</CodeSel>
<OptFeed>0</OptFeed>
<NoZi1>0</NoZi1>
<NoZi2>0</NoZi2>
<NoZi3>0</NoZi3>
<NoZi4>0</NoZi4>
<NoZi5>0</NoZi5>
<Ro1Chk>0</Ro1Chk>
<Ro2Chk>0</Ro2Chk>
<Ro3Chk>0</Ro3Chk>
<Ir1Chk>1</Ir1Chk>
<Ir2Chk>0</Ir2Chk>
<Ra1Chk>0</Ra1Chk>
<Ra2Chk>0</Ra2Chk>
<Ra3Chk>0</Ra3Chk>
<Im1Chk>1</Im1Chk>
<Im2Chk>0</Im2Chk>
<OnChipMemories>
<Ocm1>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm1>
<Ocm2>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm2>
<Ocm3>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm3>
<Ocm4>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm4>
<Ocm5>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm5>
<Ocm6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm6>
<IRAM>
<Type>0</Type>
<StartAddress>0x20000000</StartAddress>
<Size>0x20000</Size>
</IRAM>
<IROM>
<Type>1</Type>
<StartAddress>0x8000000</StartAddress>
<Size>0x100000</Size>
</IROM>
<XRAM>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</XRAM>
<OCR_RVCT1>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT1>
<OCR_RVCT2>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT2>
<OCR_RVCT3>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT3>
<OCR_RVCT4>
<Type>1</Type>
<StartAddress>0x8000000</StartAddress>
<Size>0x100000</Size>
</OCR_RVCT4>
<OCR_RVCT5>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT5>
<OCR_RVCT6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT6>
<OCR_RVCT7>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT7>
<OCR_RVCT8>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT8>
<OCR_RVCT9>
<Type>0</Type>
<StartAddress>0x20000000</StartAddress>
<Size>0x20000</Size>
</OCR_RVCT9>
<OCR_RVCT10>
<Type>0</Type>
<StartAddress>0x10000000</StartAddress>
<Size>0x10000</Size>
</OCR_RVCT10>
</OnChipMemories>
<RvctStartVector></RvctStartVector>
</ArmAdsMisc>
<Cads>
<interw>1</interw>
<Optim>1</Optim>
<oTime>0</oTime>
<SplitLS>0</SplitLS>
<OneElfS>1</OneElfS>
<Strict>0</Strict>
<EnumInt>0</EnumInt>
<PlainCh>0</PlainCh>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<wLevel>2</wLevel>
<uThumb>0</uThumb>
<uSurpInc>0</uSurpInc>
<uC99>1</uC99>
<uGnu>0</uGnu>
<useXO>0</useXO>
<v6Lang>1</v6Lang>
<v6LangP>1</v6LangP>
<vShortEn>1</vShortEn>
<vShortWch>1</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>STM32F405xx, USE_HAL_DRIVER</Define>
<Undefine></Undefine>
<IncludePath>.;..\..\..\include;applications;.;board;board\CubeMX_Config\Inc;..\libraries\HAL_Drivers;..\libraries\HAL_Drivers\config;packages\led;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m4;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\finsh;..\libraries\STM32F4xx_HAL\STM32F4xx_HAL_Driver\Inc;..\libraries\STM32F4xx_HAL\CMSIS\Device\ST\STM32F4xx\Include;..\libraries\STM32F4xx_HAL\CMSIS\Include</IncludePath>
</VariousControls>
</Cads>
<Aads>
<interw>1</interw>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<thumb>0</thumb>
<SplitLS>0</SplitLS>
<SwStkChk>0</SwStkChk>
<NoWarn>0</NoWarn>
<uSurpInc>0</uSurpInc>
<useXO>0</useXO>
<ClangAsOpt>1</ClangAsOpt>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Aads>
<LDads>
<umfTarg>0</umfTarg>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<noStLib>0</noStLib>
<RepFail>1</RepFail>
<useFile>0</useFile>
<TextAddressRange>0x08000000</TextAddressRange>
<DataAddressRange>0x20000000</DataAddressRange>
<pXoBase></pXoBase>
<ScatterFile>.\board\linker_scripts\link.sct</ScatterFile>
<IncludeLibs></IncludeLibs>
<IncludeLibsPath></IncludeLibsPath>
<Misc>--keep *.o(.rti_fn.*) --keep *.o(FSymTab)</Misc>
<LinkerInputFile></LinkerInputFile>
<DisabledWarnings></DisabledWarnings>
</LDads>
</TargetArmAds>
</TargetOption>
</Target>
</Targets>
<RTE>
<apis/>
<components/>
<files/>
</RTE>
</Project>