Initial commit: CCU621_M firmware project with BLE debug link support.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
#include "sys_drv_init.h"
|
||||
#include "gpio.h"
|
||||
#include "usart.h"
|
||||
#include "app_rtc/app_rtc.h"
|
||||
#include "gd32h7xx.h"
|
||||
#include "can.h"
|
||||
#include "adc_temp.h"
|
||||
#include "nandflash_exmc_MT29F4G08.h"
|
||||
#include "exflash_spi4_gd25qxx.h"
|
||||
#include "flash_external_data.h"
|
||||
#include "adc_spi3_insuVolt.h"
|
||||
#include "adc_spi5_batVoltCurr.h"
|
||||
#include "fm24cl16.h"
|
||||
#include "tim/app_tim.h"
|
||||
#include "main.h"
|
||||
//#include <cachel1_armv7.h>
|
||||
|
||||
/**
|
||||
* @brief 使能 Cortex-M7 指令/数据缓存
|
||||
* @note 先失效 D-Cache,再开启 D-Cache,避免历史脏数据影响
|
||||
*/
|
||||
static void cache_enable(void)
|
||||
{
|
||||
SCB_EnableICache();
|
||||
SCB_DisableDCache();
|
||||
SCB_InvalidateDCache();
|
||||
SCB_EnableDCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 配置 NVIC 优先级分组
|
||||
* @note FreeRTOS 建议使用 PRE4_SUB0(4 位抢占优先级 + 0 位子优先级)
|
||||
*/
|
||||
static void nvic_configuration(void)
|
||||
{
|
||||
/* 统一中断优先级配置入口(参考 CCU601E_D 的 NVIC_Priority_Config 思路) */
|
||||
nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
|
||||
|
||||
/* ENET IRQ 内会调用 xSemaphoreGiveFromISR,优先级必须 >= configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY(5) */
|
||||
#ifdef USE_ENET0
|
||||
nvic_irq_enable(ENET0_IRQn, 6U, 0U);
|
||||
#endif
|
||||
#ifdef USE_ENET1
|
||||
nvic_irq_enable(ENET1_IRQn, 6U, 0U);
|
||||
#endif
|
||||
|
||||
/* USART/UART 中断优先级统一配置 */
|
||||
nvic_irq_enable(USART0_IRQn, 3U, 1U);
|
||||
nvic_irq_enable(USART2_IRQn, 3U, 2U);
|
||||
nvic_irq_enable(UART3_IRQn, 3U, 0U);
|
||||
nvic_irq_enable(UART4_IRQn, 2U, 0U);
|
||||
nvic_irq_enable(USART5_IRQn, 1U, 0U);
|
||||
nvic_irq_enable(UART6_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(UART7_IRQn, 3U, 7U);
|
||||
|
||||
/* ADC DMA 中断优先级统一配置 */
|
||||
nvic_irq_enable(DMA1_Channel0_IRQn, 6U, 0U);
|
||||
|
||||
/* CAN 中断优先级统一配置 */
|
||||
nvic_irq_enable(CAN0_Message_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN1_Message_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN2_Message_IRQn, 0U, 0U);
|
||||
/* CAN error/busoff/warning IRQs (some CAN configs may route events here) */
|
||||
nvic_irq_enable(CAN0_Busoff_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN0_Error_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN0_TEC_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN0_REC_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN1_Busoff_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN1_Error_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN1_TEC_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN1_REC_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN2_Busoff_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN2_Error_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN2_TEC_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(CAN2_REC_IRQn, 0U, 0U);
|
||||
nvic_irq_enable(TIMER7_UP_IRQn, 5U, 0U);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 配置 MPU(Memory Protection Unit)区域属性
|
||||
*
|
||||
* 详细说明:
|
||||
* 1) 该函数主要用于给“被 DMA 与 CPU 同时访问”的内存区域设置合适的属性,
|
||||
* 避免 D-Cache 引入的数据一致性问题(CPU 看到旧数据、DMA 写入不可见等)。
|
||||
*
|
||||
* 2) 当前配置了两块 16KB 区域(均位于 SRAM3):
|
||||
* - 区域0:0x30000000 ~ 0x30003FFF
|
||||
* 典型用于 DMA 描述符、ETH Rx/Tx 缓冲等需要强一致性的内存。
|
||||
* - 区域1:0x30004000 ~ 0x30007FFF
|
||||
* 典型用于 lwIP heap(pbuf/memp 等运行期内存)。
|
||||
*
|
||||
* 3) 两个区域都设置为 Non-Cacheable(不可缓存):
|
||||
* - 目的:让 CPU 每次都从实际内存读取,保证与 DMA 读写一致。
|
||||
* - 代价:这部分区域访问速度会比 Cacheable 区域慢,但稳定性更高。
|
||||
*
|
||||
* 4) 该函数应在外设初始化前执行(当前在 v_sys_hardware_init() 早期调用),
|
||||
* 这样后续网络/DMA模块在运行时就使用了正确的内存属性。
|
||||
*
|
||||
* 5) 结论:此函数是“网络与 DMA 稳定运行”的基础配置,尤其在 Cortex-M7
|
||||
* 启用 D-Cache 场景下必不可少。
|
||||
*/
|
||||
void mpu_config(void)
|
||||
{
|
||||
mpu_region_init_struct mpu_init_struct;
|
||||
mpu_region_struct_para_init(&mpu_init_struct);
|
||||
|
||||
/* disable MPU */
|
||||
ARM_MPU_SetRegion(0U, 0U);
|
||||
|
||||
/* 区域0:DMA描述符/收发缓冲区(非缓存,避免 DMA 与 Cache 不一致) */
|
||||
mpu_init_struct.region_base_address = 0x30000000;
|
||||
mpu_init_struct.region_size = MPU_REGION_SIZE_16KB;
|
||||
mpu_init_struct.access_permission = MPU_AP_FULL_ACCESS;
|
||||
mpu_init_struct.access_bufferable = MPU_ACCESS_BUFFERABLE;
|
||||
mpu_init_struct.access_cacheable = MPU_ACCESS_NON_CACHEABLE;
|
||||
mpu_init_struct.access_shareable = MPU_ACCESS_NON_SHAREABLE;
|
||||
mpu_init_struct.region_number = MPU_REGION_NUMBER0;
|
||||
mpu_init_struct.subregion_disable = MPU_SUBREGION_ENABLE;
|
||||
mpu_init_struct.instruction_exec = MPU_INSTRUCTION_EXEC_PERMIT;
|
||||
mpu_init_struct.tex_type = MPU_TEX_TYPE0;
|
||||
mpu_region_config(&mpu_init_struct);
|
||||
mpu_region_enable();
|
||||
|
||||
/* 区域1:lwIP heap(非缓存 + shareable,便于总线主设备协同访问) */
|
||||
mpu_init_struct.region_base_address = 0x30004000;
|
||||
mpu_init_struct.region_size = MPU_REGION_SIZE_16KB;
|
||||
mpu_init_struct.access_permission = MPU_AP_FULL_ACCESS;
|
||||
mpu_init_struct.access_bufferable = MPU_ACCESS_NON_BUFFERABLE;
|
||||
mpu_init_struct.access_cacheable = MPU_ACCESS_NON_CACHEABLE;
|
||||
mpu_init_struct.access_shareable = MPU_ACCESS_SHAREABLE;
|
||||
mpu_init_struct.region_number = MPU_REGION_NUMBER1;
|
||||
mpu_init_struct.subregion_disable = MPU_SUBREGION_ENABLE;
|
||||
mpu_init_struct.instruction_exec = MPU_INSTRUCTION_EXEC_PERMIT;
|
||||
mpu_init_struct.tex_type = MPU_TEX_TYPE1;
|
||||
mpu_region_config(&mpu_init_struct);
|
||||
mpu_region_enable();
|
||||
|
||||
/* enable MPU */
|
||||
ARM_MPU_Enable(MPU_MODE_PRIV_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 系统硬件初始化总入口
|
||||
* @note 按“基础系统 -> 通信/IO -> 业务外设”顺序初始化
|
||||
*/
|
||||
void v_sys_hardware_init(void)
|
||||
{
|
||||
/* 基础系统配置 */
|
||||
nvic_configuration();
|
||||
mpu_config();
|
||||
cache_enable();
|
||||
|
||||
/* 基础外设 */
|
||||
/* 先初始化关键DO输出,避免上电过程继电器抖动/误动作 */
|
||||
v_outpin_config();
|
||||
v_rtc_init();
|
||||
v_inpin_config();
|
||||
|
||||
|
||||
/* 通信外设 */
|
||||
v_usart_init_all();
|
||||
/* EEPROM(FM24CL16) I2C1 初始化 */
|
||||
eeprom_driver_init();
|
||||
/* SPI Flash 驱动初始化(统一封装接口) */
|
||||
(void)v_flash_dataflash_init();
|
||||
/* CAN init moved into hardware stage to avoid first-frame loss after power-on. */
|
||||
v_can_interface_init();
|
||||
/* 1ms hardware timer interrupt for periodic software counters. */
|
||||
v_app_tim_init();
|
||||
/* 以太网与 lwIP 须在 FreeRTOS 调度器启动后初始化(见 app_os_init),
|
||||
* 否则 enet_system_setup() 失败会死在 while(1),运行灯也不会亮。 */
|
||||
|
||||
/* 采样与电源相关外设 */
|
||||
adc_spi3_insuVolt_init();
|
||||
adc_spi5_batVoltCurr_init();
|
||||
v_temp_config();
|
||||
// v_4g_config();
|
||||
|
||||
/* 可选外设(按需启用)
|
||||
exmc_nandflash_init();
|
||||
lwip_system_init();
|
||||
*/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user