#include #include "bsp.h" /***************************************************************************************** * System Clock - HRC 16MHz -> MPLL 200MHz (不用外部晶振) ****************************************************************************************/ static void SystemClockConfig(void) { stc_clk_sysclk_cfg_t stcSysClkCfg; stc_clk_mpll_cfg_t stcMpllCfg; stc_sram_config_t stcSramConfig; MEM_ZERO_STRUCT(stcSysClkCfg); MEM_ZERO_STRUCT(stcMpllCfg); MEM_ZERO_STRUCT(stcSramConfig); /* Set bus clk div. */ stcSysClkCfg.enHclkDiv = ClkSysclkDiv1; stcSysClkCfg.enExclkDiv = ClkSysclkDiv2; stcSysClkCfg.enPclk0Div = ClkSysclkDiv1; stcSysClkCfg.enPclk1Div = ClkSysclkDiv2; stcSysClkCfg.enPclk2Div = ClkSysclkDiv4; stcSysClkCfg.enPclk3Div = ClkSysclkDiv4; stcSysClkCfg.enPclk4Div = ClkSysclkDiv2; CLK_SysClkConfig(&stcSysClkCfg); /* sram init include read/write wait cycle setting */ stcSramConfig.u8SramIdx = Sram12Idx | Sram3Idx | SramHsIdx | SramRetIdx; stcSramConfig.enSramRC = SramCycle2; stcSramConfig.enSramWC = SramCycle2; SRAM_Init(&stcSramConfig); /* flash read wait cycle setting */ EFM_Unlock(); EFM_SetLatency(EFM_LATENCY_5); EFM_Lock(); /* Config HRC and enable HRC */ CLK_HrcCmd(Enable); /* MPLL config (HRC / pllmDiv * plln / PllpDiv = 16/2*50/2 = 200M). */ stcMpllCfg.pllmDiv = 2ul; stcMpllCfg.plln = 50ul; stcMpllCfg.PllpDiv = 2ul; stcMpllCfg.PllqDiv = 2ul; stcMpllCfg.PllrDiv = 2ul; CLK_SetPllSource(ClkPllSrcHRC); CLK_MpllConfig(&stcMpllCfg); /* Enable MPLL. */ CLK_MpllCmd(Enable); /* Wait MPLL ready. */ while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy)) { ; } /* Switch driver ability */ PWC_HS2HP(); /* Switch system clock source to MPLL. */ CLK_SetSysClkSource(CLKSysSrcMPLL); SystemCoreClockUpdate(); } /***************************************************************************************** * Debug Uart (USART1) ****************************************************************************************/ static uint8_t DbgUartRec(void) { uint16_t u16Data = USART_RecData(DBG_USART_CH); return (uint8_t)u16Data; } static void DBGUsartErrIrqCallback(void) { if(DBG_USART_CH->SR_f.ORE) { DBG_USART_CH->CR1_f.CORE = 1; USART_RecData(DBG_USART_CH); } if(DBG_USART_CH->SR_f.PE) DBG_USART_CH->CR1_f.CPE = 1; if(DBG_USART_CH->SR_f.FE) DBG_USART_CH->CR1_f.CFE = 1; } static void DBGUsartRxIrqCallback(void) { uint8_t rData = DbgUartRec(); DbgRxIrqCallback(rData); } void DbgUart_Config(uint32_t BaudRate) { stc_usart_uart_init_t stcInitCfg; stc_irq_regi_conf_t stcIrqRegiCfg; en_result_t enRet; stc_port_init_t stcPortInit; MEM_ZERO_STRUCT(stcPortInit); stcPortInit.enPinOType = Pin_OType_Cmos; PORT_Init(DBG_USART_RX_PORT, DBG_USART_RX_PIN, &stcPortInit); PORT_Init(DBG_USART_TX_PORT, DBG_USART_TX_PIN, &stcPortInit); stcInitCfg.enClkMode = UsartIntClkCkNoOutput; stcInitCfg.enClkDiv = UsartClkDiv_1; stcInitCfg.enDataLength = UsartDataBits8; stcInitCfg.enDirection = UsartDataLsbFirst; stcInitCfg.enStopBit = UsartOneStopBit; stcInitCfg.enParity = UsartParityNone; stcInitCfg.enSampleMode = UsartSampleBit8; stcInitCfg.enDetectMode = UsartStartBitFallEdge; stcInitCfg.enHwFlow = UsartRtsEnable; PWC_Fcg1PeriphClockCmd(DBG_FCG1_PERIPH, Enable); PORT_SetFunc(DBG_USART_RX_PORT, DBG_USART_RX_PIN, DBG_USART_RX_FUNC, Disable); PORT_SetFunc(DBG_USART_TX_PORT, DBG_USART_TX_PIN, DBG_USART_TX_FUNC, Disable); enRet = USART_UART_Init(DBG_USART_CH, &stcInitCfg); if(enRet != Ok) { Error_Handler(); } enRet = USART_SetBaudrate(DBG_USART_CH, BaudRate); if(enRet != Ok) { Error_Handler(); } stcIrqRegiCfg.enIRQn = DBGUART_IRQn; stcIrqRegiCfg.pfnCallback = &DBGUsartRxIrqCallback; stcIrqRegiCfg.enIntSrc = DBG_USART_RI_NUM; enIrqRegistration(&stcIrqRegiCfg); NVIC_SetPriority(stcIrqRegiCfg.enIRQn, 2); NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn); NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn); stcIrqRegiCfg.enIRQn = DBGUART_EI_IRQn; stcIrqRegiCfg.pfnCallback = &DBGUsartErrIrqCallback; stcIrqRegiCfg.enIntSrc = DBG_USART_EI_NUM; enIrqRegistration(&stcIrqRegiCfg); NVIC_SetPriority(stcIrqRegiCfg.enIRQn, 2); NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn); NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn); USART_FuncCmd(DBG_USART_CH, UsartTx, Enable); USART_FuncCmd(DBG_USART_CH, UsartRx, Enable); USART_FuncCmd(DBG_USART_CH, UsartRxInt, Enable); } void DebugUartSend(uint8_t *sData, uint16_t sLen) { for(int i = 0; i < sLen; i++) { USART_SendData(DBG_USART_CH, sData[i]); while(USART_GetStatus(DBG_USART_CH, UsartTxComplete) == Reset); } } /***************************************************************************************** * RS485 Ch1 (USART2) - 升级通道, 按GateWay APP配置方式 ****************************************************************************************/ static uint8_t RS485Ch1UartRec(void) { uint16_t u16Data = USART_RecData(RS485_CH1_USART_CH); return (uint8_t)u16Data; } static void RS485Ch1UsartErrIrqCallback(void) { if(RS485_CH1_USART_CH->SR_f.ORE) { RS485_CH1_USART_CH->CR1_f.CORE = 1; USART_RecData(RS485_CH1_USART_CH); } if(RS485_CH1_USART_CH->SR_f.PE) RS485_CH1_USART_CH->CR1_f.CPE = 1; if(RS485_CH1_USART_CH->SR_f.FE) RS485_CH1_USART_CH->CR1_f.CFE = 1; } static void RS485Ch1UsartRxIrqCallback(void) { uint8_t rData = RS485Ch1UartRec(); RS485Ch1RxIrqCallback(rData); } void RS485Ch1_Config(uint32_t BaudRate) { stc_usart_uart_init_t stcInitCfg; stc_irq_regi_conf_t stcIrqRegiCfg; en_result_t enRet; stc_port_init_t stcPortInit; MEM_ZERO_STRUCT(stcPortInit); stcPortInit.enPinOType = Pin_OType_Cmos; PORT_Init(RS485_CH1_USART_RX_PORT, RS485_CH1_USART_RX_PIN, &stcPortInit); PORT_Init(RS485_CH1_USART_TX_PORT, RS485_CH1_USART_TX_PIN, &stcPortInit); stcInitCfg.enClkMode = UsartIntClkCkNoOutput; stcInitCfg.enClkDiv = UsartClkDiv_16; stcInitCfg.enDataLength = UsartDataBits8; stcInitCfg.enDirection = UsartDataLsbFirst; stcInitCfg.enStopBit = UsartOneStopBit; stcInitCfg.enParity = UsartParityNone; stcInitCfg.enSampleMode = UsartSampleBit8; stcInitCfg.enDetectMode = UsartStartBitFallEdge; stcInitCfg.enHwFlow = UsartRtsEnable; PWC_Fcg1PeriphClockCmd(RS485_CH1_FCG1_PERIPH, Enable); PORT_SetFunc(RS485_CH1_USART_RX_PORT, RS485_CH1_USART_RX_PIN, RS485_CH1_USART_RX_FUNC, Disable); PORT_SetFunc(RS485_CH1_USART_TX_PORT, RS485_CH1_USART_TX_PIN, RS485_CH1_USART_TX_FUNC, Disable); enRet = USART_UART_Init(RS485_CH1_USART_CH, &stcInitCfg); if(enRet != Ok) { Error_Handler(); } enRet = USART_SetBaudrate(RS485_CH1_USART_CH, BaudRate); if(enRet != Ok) { Error_Handler(); } stcIrqRegiCfg.enIRQn = RS485CH1_UART_IRQn; stcIrqRegiCfg.pfnCallback = &RS485Ch1UsartRxIrqCallback; stcIrqRegiCfg.enIntSrc = RS485_CH1_USART_RI_NUM; enIrqRegistration(&stcIrqRegiCfg); NVIC_SetPriority(stcIrqRegiCfg.enIRQn, 2); NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn); NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn); stcIrqRegiCfg.enIRQn = RS485CH1_UART_EI_IRQn; stcIrqRegiCfg.pfnCallback = &RS485Ch1UsartErrIrqCallback; stcIrqRegiCfg.enIntSrc = RS485_CH1_USART_EI_NUM; enIrqRegistration(&stcIrqRegiCfg); NVIC_SetPriority(stcIrqRegiCfg.enIRQn, 2); NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn); NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn); USART_FuncCmd(RS485_CH1_USART_CH, UsartTx, Enable); USART_FuncCmd(RS485_CH1_USART_CH, UsartRx, Enable); USART_FuncCmd(RS485_CH1_USART_CH, UsartRxInt, Enable); } void RS485Ch1UartSend(uint8_t *sData, uint16_t sLen) { RS485_CH1_TX(); for(int i = 0; i < sLen; i++) { USART_SendData(RS485_CH1_USART_CH, sData[i]); while(USART_GetStatus(RS485_CH1_USART_CH, UsartTxComplete) == Reset); } RS485_CH1_RX(); } /***************************************************************************************** * RS485 Ch2 (USART3) ****************************************************************************************/ static uint8_t RS485Ch2UartRec(void) { uint16_t u16Data = USART_RecData(RS485_CH2_USART_CH); return (uint8_t)u16Data; } static void RS485Ch2UsartErrIrqCallback(void) { if(RS485_CH2_USART_CH->SR_f.ORE) { RS485_CH2_USART_CH->CR1_f.CORE = 1; USART_RecData(RS485_CH2_USART_CH); } if(RS485_CH2_USART_CH->SR_f.PE) RS485_CH2_USART_CH->CR1_f.CPE = 1; if(RS485_CH2_USART_CH->SR_f.FE) RS485_CH2_USART_CH->CR1_f.CFE = 1; } static void RS485Ch2UsartRxIrqCallback(void) { uint8_t rData = RS485Ch2UartRec(); RS485Ch2RxIrqCallback(rData); } void RS485Ch2_Config(uint32_t BaudRate) { stc_usart_uart_init_t stcInitCfg; stc_irq_regi_conf_t stcIrqRegiCfg; en_result_t enRet; stc_port_init_t stcPortInit; MEM_ZERO_STRUCT(stcPortInit); stcPortInit.enPinOType = Pin_OType_Cmos; PORT_Init(RS485_CH2_USART_RX_PORT, RS485_CH2_USART_RX_PIN, &stcPortInit); PORT_Init(RS485_CH2_USART_TX_PORT, RS485_CH2_USART_TX_PIN, &stcPortInit); stcInitCfg.enClkMode = UsartIntClkCkNoOutput; stcInitCfg.enClkDiv = UsartClkDiv_16; stcInitCfg.enDataLength = UsartDataBits8; stcInitCfg.enDirection = UsartDataLsbFirst; stcInitCfg.enStopBit = UsartOneStopBit; stcInitCfg.enParity = UsartParityNone; stcInitCfg.enSampleMode = UsartSampleBit8; stcInitCfg.enDetectMode = UsartStartBitFallEdge; stcInitCfg.enHwFlow = UsartRtsEnable; PWC_Fcg1PeriphClockCmd(RS485_CH2_FCG1_PERIPH, Enable); PORT_SetFunc(RS485_CH2_USART_RX_PORT, RS485_CH2_USART_RX_PIN, RS485_CH2_USART_RX_FUNC, Disable); PORT_SetFunc(RS485_CH2_USART_TX_PORT, RS485_CH2_USART_TX_PIN, RS485_CH2_USART_TX_FUNC, Disable); enRet = USART_UART_Init(RS485_CH2_USART_CH, &stcInitCfg); if(enRet != Ok) { Error_Handler(); } enRet = USART_SetBaudrate(RS485_CH2_USART_CH, BaudRate); if(enRet != Ok) { Error_Handler(); } stcIrqRegiCfg.enIRQn = RS485CH2_UART_IRQn; stcIrqRegiCfg.pfnCallback = &RS485Ch2UsartRxIrqCallback; stcIrqRegiCfg.enIntSrc = RS485_CH2_USART_RI_NUM; enIrqRegistration(&stcIrqRegiCfg); NVIC_SetPriority(stcIrqRegiCfg.enIRQn, 2); NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn); NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn); stcIrqRegiCfg.enIRQn = RS485CH2_UART_EI_IRQn; stcIrqRegiCfg.pfnCallback = &RS485Ch2UsartErrIrqCallback; stcIrqRegiCfg.enIntSrc = RS485_CH2_USART_EI_NUM; enIrqRegistration(&stcIrqRegiCfg); NVIC_SetPriority(stcIrqRegiCfg.enIRQn, 2); NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn); NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn); USART_FuncCmd(RS485_CH2_USART_CH, UsartTx, Enable); USART_FuncCmd(RS485_CH2_USART_CH, UsartRx, Enable); USART_FuncCmd(RS485_CH2_USART_CH, UsartRxInt, Enable); } void RS485Ch2UartSend(uint8_t *sData, uint16_t sLen) { RS485_CH2_TX(); for(int i = 0; i < sLen; i++) { USART_SendData(RS485_CH2_USART_CH, sData[i]); while(USART_GetStatus(RS485_CH2_USART_CH, UsartTxComplete) == Reset); } RS485_CH2_RX(); } /***************************************************************************************** * GPIO - RS485收发控制引脚 (PC7=Ch1方向, PB13=Ch2方向), PC10供电不动 ****************************************************************************************/ static void GPIO_Config(void) { stc_port_init_t stcPortInit; stc_port_pub_set_t stcPortPub; PORT_DebugPortSetting(TDO_SWO, Disable); PORT_DebugPortSetting(TDI, Disable); PORT_DebugPortSetting(TRST, Disable); MEM_ZERO_STRUCT(stcPortInit); MEM_ZERO_STRUCT(stcPortPub); stcPortPub.enReadWait = WaitCycle3; PORT_PubSetting(&stcPortPub); stcPortInit.enPinMode = Pin_Mode_Out; stcPortInit.enPinOType = Pin_OType_Cmos; stcPortInit.enPinDrv = Pin_Drv_H; stcPortInit.enPullUp = Disable; /* RS485 Ch1 方向控制 PC7: 高=发送, 低=接收 */ PORT_Init(RS485_CH1_CTRL_PORT, RS485_CH1_CTRL_PIN, &stcPortInit); RS485_CH1_RX(); /* RS485 Ch2 方向控制 PB13 */ PORT_Init(RS485_CH2_CTRL_PORT, RS485_CH2_CTRL_PIN, &stcPortInit); RS485_CH2_RX(); } void Error_Handler(void) { while(1){ ; } } /***************************************************************************************** * Watch Dog - HC32F460 SWDT由ICG硬件启动, 周期喂狗 ****************************************************************************************/ void FeedDog(void) { #if (WATCH_DOG == 1) SWDT_RefreshCounter(); #endif } void BSP_Init(void) { SystemClockConfig(); GPIO_Config(); RS485Ch1_Config(500000); FeedDog(); SysTick_Init(1000); FeedDog(); } /***************************************************************************************** * Flash操作 ****************************************************************************************/ void FlashWrite(uint32_t Addr, uint32_t *wData, uint8_t wLen) { EFM_Unlock(); EFM_FlashCmd(Enable); while(Set != EFM_GetFlagStatus(EFM_FLAG_RDY)) { ; } for(int i = 0; i < wLen; i++) { if(EFM_SingleProgram(Addr + i * 4, wData[i]) != Ok) { break; } } EFM_Lock(); } static void FlashRead(uint32_t u32Addr, uint32_t *rData, uint8_t rLen) { for(int i = 0; i < rLen / 4; i++) { rData[i] = *((volatile uint32_t*)(u32Addr + i * 4)); } } void ReadBootPara(BootPara rData) { FlashRead(BOOT_PARA_ADDRESS, (uint32_t *)rData, sizeof(BootPara_t)); } void WriteBootPara(BootPara wData) { int wLen; uint32_t *Data; Data = (uint32_t *)wData; wLen = sizeof(BootPara_t) / 4; EFM_Unlock(); EFM_FlashCmd(Enable); while(Set != EFM_GetFlagStatus(EFM_FLAG_RDY)) { ; } /* Erase sector. */ EFM_SectorErase(BOOT_PARA_ADDRESS); for(int i = 0; i < wLen; i++) { if(EFM_SingleProgram(BOOT_PARA_ADDRESS + i * 4, Data[i]) != Ok) { break; } } EFM_Lock(); } void EraseFlash(void) { EFM_Unlock(); EFM_FlashCmd(Enable); while(Set != EFM_GetFlagStatus(EFM_FLAG_RDY)) { ; } /* 只擦APP区, 不擦参数区(BOOT_PARA_ADDRESS) */ for(int Addr = APP_ADDRESS; Addr < BOOT_PARA_ADDRESS; Addr += FLASH_SECTOR_SIZE) { EFM_SectorErase(Addr); FeedDog(); } EFM_Lock(); } /***************************************************************************************** * User Irq CallBack (weak) ****************************************************************************************/ __weak void DbgRxIrqCallback(uint8_t rData) { } __weak void RS485Ch1RxIrqCallback(uint8_t rData) { } __weak void RS485Ch2RxIrqCallback(uint8_t rData) { }