Files
2026-05-09 17:09:52 +08:00

316 lines
8.0 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "sysctrl.h"
#include "gpio.h"
#include "flash.h"
#include "bsp.h"
#include "lpuart.h"
#include "bt.h"
#include "wdt.h"
extern void DebugUartIRQ(uint8_t Data);
extern void BleIRQHandler(uint8_t rData);
extern void SysTick_CallBack(void);
extern void KeyIRQHandler(void);
static __IO uint32_t SysTickCnt = 0;
static __IO bool LpUart0_Tx_Flag;
#define WAKEUP_TIME_ARR 1000
#define USE_RCL_TRIM 0
#define DBG_LOG(...)
#if (SYSCLK == SYSCLK_RCH)
static void SystemClkInit(en_sysctrl_rch_freq_t enRchFreq)
{
///< RCH时钟不同频率的切换,需要先将时钟切换到RCL
Sysctrl_SetRCLTrim(SysctrlRclFreq32768);
Sysctrl_SetRCLStableTime(SysctrlRclStableCycle64);
Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);
Sysctrl_SysClkSwitch(SysctrlClkRCL);
///< 加载目标频率的RCH的TRIM值
Sysctrl_SetRCHTrim(enRchFreq);
///< 使能RCH
Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
///< 时钟切换到RCH
Sysctrl_SysClkSwitch(SysctrlClkRCH);
///< HCLK不超过24M:此处设置FLASH读等待周期为0 cycle
Flash_WaitCycle(FlashWaitCycle0);
}
#elif (SYSCLK == SYSCLK_XTH)
static void SystemClkInit(en_sysctrl_xth_freq_t enXthFreq)
{
///<======================== 切换至XTH32MHz ==============================
///< 当使用的时钟源HCLK大于24M:设置FLASH 读等待周期为1 cycle(默认值也为1 cycle)
if(SysctrlXthFreq24_32MHz == enXthFreq)
{
Flash_WaitCycle(FlashWaitCycle1);
}
///< 切换时钟前(根据外部高速晶振)设置XTH频率范围,配置晶振参数,使能目标时钟,此处为SYSTEM_XTH = 32MHz
Sysctrl_SetXTHFreq(enXthFreq);
Sysctrl_XTHDriverCfg(SysctrlXtalDriver3);
Sysctrl_SetXTHStableTime(SysctrlXthStableCycle16384);
Sysctrl_ClkSourceEnable(SysctrlClkXTH, TRUE);
delay1ms(10);
Sysctrl_SysClkSwitch(SysctrlClkXTH);
if(SysctrlXthFreq24_32MHz != enXthFreq)
{
Flash_WaitCycle(FlashWaitCycle0);
}
//M0P_SYSCTRL->SYSCTRL0_f.WAKEUP_BYRCH = 0; //唤醒保持原时钟
}
#elif (SYSCLK == SYSCLK_PLL)
///<请注意根据外部晶振配置宏——[SYSTEM_XTH],如果使用PLLXTH必须小于24MHz
static void SystemClkInit(void)
{
stc_sysctrl_pll_cfg_t stcPLLCfg;
///< 切换时钟前(根据外部高速晶振)设置XTH频率范围,配置晶振参数,使能目标时钟,此处为SYSTEM_XTH = 32MHz
// Sysctrl_SetXTHFreq(SysctrlXthFreq4_8MHz);
// Sysctrl_XTHDriverCfg(SysctrlXtalDriver3);
// Sysctrl_SetXTHStableTime(SysctrlXthStableCycle16384);
// Sysctrl_ClkSourceEnable(SysctrlClkXTH, TRUE);
Sysctrl_SetRCHTrim(SysctrlRchFreq8MHz);
Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
delay1ms(10);
stcPLLCfg.enInFreq = SysctrlPllInFreq6_12MHz; //XTH 8MHz
stcPLLCfg.enOutFreq = SysctrlPllOutFreq36_48MHz; //PLL 输出
stcPLLCfg.enPllClkSrc = SysctrlPllRch; //输入时钟源选择RCH
stcPLLCfg.enPllMul = SysctrlPllMul6; //8MHz x 6 = 48MHz
Sysctrl_SetPLLFreq(&stcPLLCfg);
///< 当使用的时钟源HCLK大于24M:设置FLASH 读等待周期为1 cycle(默认值也为1 cycle)
Flash_WaitCycle(FlashWaitCycle1);
///< 使能PLL
Sysctrl_ClkSourceEnable(SysctrlClkPLL, TRUE);
///< 时钟切换到PLL
Sysctrl_SysClkSwitch(SysctrlClkPLL);
}
#endif
static void SystemRCLInit(void)
{
Sysctrl_SetRCLTrim(SysctrlRclFreq38400); ///< 配置RCL时钟为32kHz
Sysctrl_SetRCLStableTime(SysctrlRclStableCycle256);
Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE); ///< 使能RCL时钟
}
static void LPUartInit(void)
{
stc_gpio_cfg_t stcGpioCfg;
stc_lpuart_cfg_t stcCfg;
DDL_ZERO_STRUCT(stcGpioCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
///<TX
stcGpioCfg.enDir = GpioDirOut;
Gpio_Init(LPUART_TX_PORT, LPUART_TX_PIN, &stcGpioCfg);
Gpio_SetAfMode(LPUART_TX_PORT, LPUART_TX_PIN, LPUART_TX_AF); //配置PA00为LPUART1_TX
//<RX
stcGpioCfg.enDir = GpioDirIn;
Gpio_Init(LPUART_RX_PORT, LPUART_RX_PIN,&stcGpioCfg);
Gpio_SetAfMode(LPUART_RX_PORT, LPUART_RX_PIN, LPUART_RX_AF); //配置PA01为LPUART1_RX
DDL_ZERO_STRUCT(stcCfg);
Sysctrl_SetPeripheralGate(LPUART_PERIPHERAL_CLK,TRUE);
///<LPUART 初始化
stcCfg.enStopBit = LPUart1bit; ///<1停止位
stcCfg.enMmdorCk = LPUartEven; ///<偶校验
stcCfg.stcBaud.enSclkSel = LPUartMskRcl; ///<传输时钟源
stcCfg.stcBaud.u32Sclk = 38400; ///<PCLK获取
stcCfg.stcBaud.enSclkDiv = LPUartMsk4Or8Div; ///<采样分频
stcCfg.stcBaud.u32Baud = 9600; ///<波特率
stcCfg.enRunMode = LPUartMskMode1; ///<工作模式
LPUart_Init(LPUART, &stcCfg);
///<LPUART 中断使能
LPUart_ClrStatus(LPUART,LPUartRC); ///<清接收中断请求
LPUart_ClrStatus(LPUART,LPUartTC); ///<清发送中断请求
LPUart_EnableIrq(LPUART,LPUartTxIrq); ///<使能发送中断
LPUart_EnableIrq(LPUART,LPUartRxIrq); ///<使能接收中断
EnableNvic(LPUART_IRQN,IrqLevel3,TRUE); ///<系统中断使能
}
void DBGUartSend(uint8_t *sData, int sLen)
{
uint16_t dlyCnt = 0xffff;
RS485_CTRL_TX();
delay_ms(1);
for(int i = 0; i < sLen; i++) {
LpUart0_Tx_Flag = false;
dlyCnt = 0xffff;
LPUart_SendDataIt(LPUART, sData[i]);
while(dlyCnt > 0) {
dlyCnt--;
if(LpUart0_Tx_Flag)
break;
}
}
RS485_CTRL_RX();
}
#if(LP_UART_CH == 0)
void LpUart0_IRQHandler(void)
{
if(LPUart_GetStatus(LPUART, LPUartTC)) {
LPUart_ClrStatus(LPUART, LPUartTC); ///<清发送中断请求
LpUart0_Tx_Flag = true;
}
if(LPUart_GetStatus(LPUART, LPUartRC)) { ///接收数据
LPUart_ClrStatus(LPUART, LPUartRC); ///<清接收中断请求
uint8_t u8RxData = LPUart_ReceiveData(LPUART); ///读取数据
DebugUartIRQ(u8RxData);
}
}
#else
void LpUart1_IRQHandler(void)
{
if(LPUart_GetStatus(LPUART, LPUartTC)) {
LPUart_ClrStatus(LPUART, LPUartTC); ///<清发送中断请求
LpUart0_Tx_Flag = true;
}
if(LPUart_GetStatus(LPUART, LPUartRC)) { ///接收数据
LPUart_ClrStatus(LPUART, LPUartRC); ///<清接收中断请求
uint8_t u8RxData = LPUart_ReceiveData(LPUART); ///读取数据
DebugUartIRQ(u8RxData);
}
}
#endif
static void GPIOInit(void)
{
stc_gpio_cfg_t GpioInitStruct;
DDL_ZERO_STRUCT(GpioInitStruct);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
GpioInitStruct.enDir = GpioDirOut; ///< 端口方向配置->输入
GpioInitStruct.enDrv = GpioDrvH; ///< 端口驱动能力配置->高驱动能力
GpioInitStruct.enPu = GpioPuDisable; ///< 端口上下拉配置->无
GpioInitStruct.enPd = GpioPdDisable;
GpioInitStruct.enOD = GpioOdDisable; ///< 端口开漏输出配置->开漏输出关闭
GpioInitStruct.enCtrlMode = GpioAHB; ///< 端口输入/输出值寄存器总线控制模式配置->AHB
GpioInitStruct.bOutputVal = false;
Gpio_Init(RS485_CTRL_PORT, RS485_CTRL_PIN, &GpioInitStruct);
RS485_CTRL_RX();
}
static void WdtInit(void)
{
#if (USE_WDT == 1)
///< 开启WDT外设时钟
Sysctrl_SetPeripheralGate(SysctrlPeripheralWdt,TRUE);
///< WDT 初始化
Wdt_Init(WdtResetEn, WdtT52s4);
Wdt_Start();
#endif
}
static void FlashWrite(uint32_t *wData, uint8_t wLen)
{
while(Ok != Flash_SectorErase(BOOT_PARA_ADDRESS));
for(int i = 0; i < wLen / 4; i++) {
Flash_WriteWord(BOOT_PARA_ADDRESS + i * 4, wData[i]);
}
}
static void FlashRead(uint32_t *rData, uint8_t rLen)
{
uint32_t u32Addr = BOOT_PARA_ADDRESS;
for(int i = 0; i < rLen / 4; i++) {
rData[i] = *((volatile uint32_t*)(u32Addr + i * 4));
}
}
void FeedDog(void)
{
#if (USE_WDT == 1)
Wdt_Feed();
#endif
}
uint32_t GetSysTick(void)
{
return SysTickCnt;
}
void Delay(uint8_t time)
{
while(time > 0) {
time --;
}
}
void delay_ms(uint32_t mS)
{
volatile uint32_t cTick, mTick;
cTick = GetSysTick();
while(1){
mTick = GetSysTick();
if(mTick - cTick >= mS)
break;
}
}
void SystemReset(void)
{
NVIC_SystemReset();
}
void BspInit(void)
{
//SystemClkInit(SysctrlXthFreq4_8MHz);
SystemClkInit(SysctrlRchFreq16MHz);
SystemCoreClockUpdate();
SysTick_Config(SystemCoreClock/1000);
SystemRCLInit();
GPIOInit();
LPUartInit();
while(Ok != Flash_Init(4, TRUE));
WdtInit();
}
void SysTick_IRQHandler(void)
{
SysTickCnt++;
SysTick_CallBack();
}
void ReadBootPara(BootPara rData)
{
FlashRead((uint32_t *)rData, sizeof(BootPara_t));
}
void WriteBootPara(BootPara wData)
{
FlashWrite((uint32_t *)wData, sizeof(BootPara_t));
}
void EraseFlash(void)
{
for(int Addr = APP_ADDRESS; Addr < FLASH_SIZE; Addr += FLASH_SECTOR_SIZE) {
Flash_SectorErase(Addr);
}
}