/**************************************************************************************************/ /** * @file main.c * @brief Hello world example file. * @version V1.0.0 * @date December-2022 * @author Zhixin Semiconductor * * @note * Copyright (C) 2021-2023 Zhixin Semiconductor Ltd. All rights reserved. * **************************************************************************************************/ #include "common_drv.h" #include "wdog_drv.h" #include "stim_drv.h" #include "int_drv.h" #include "clock_config.h" #include "bl_flash.h" #include "bl_can.h" #include "bl_task.h" #include "gpio_drv.h" #include "bl_crc.h" #include "../uds/uds_fbl_mgr.h" #include "spi_drv.h" #include "bl_bom.h" #include "../cdd/CddSbc/CddSbc_TLE9471.h" #define AppValidFlagAddr 0x00027FF4U #define APP_ENTRY_ADDR 0x00040000U #define APP_RstHdl_OFFSET 0x04U #define STA_NOT_LINKED 0x00U #define STA_UPGRADE_SUCC 0x01U #define STA_UPGRADE_FAIL 0x02U /*Macro definition for Platform*/ #define Capri_Platform_X 'X' #define Capri_Platform_0 '0' #define Capri_Platform_1 '1' #define Capri_Platform_2 '2' #define Capri_Platform_underline '_' #define Capri_Platform_A 'A' #define Capri_Platform_N 'N' #define Capri_Platform_S 'S' #define Capri_Platform_W 'W' #define Capri_Platform_F 'F' #define Capri_Platform_B 'B' #define Capri_Platform_Point '.' /*Macro definition for FBL Version*/ #define FBL_nVersionMajor '0' #define FBL_nVersionMinor '0' #define FBL_nVersionSub '1' /*Macro definition for FBL Requirement Spec Version*/ #define FBLReqSpec_nVersionMajor '1' #define FBLReqSpec_nVersionMinor '0' #define FBLReqSpec_nVersionSub '1' /*Macro definition for FLU Version*/ #define FLU_nVersionMajor '0' #define FLU_nVersionMinor '0' /* systick interrupt counter*/ static volatile uint32_t gSystickCount = 0; uint32_t u32LEDCNT = 0x00; extern CAN_MsgBuf_t CAN1RxBuf; extern uint8_t system_20msdelayCNT; #pragma ghs section bss=".Reprogpatn" //uint32_t Test_u32ResetReason; #pragma ghs section bss = default //uint32_t Test_u32FBLVersion __attribute__((section (".loader_and_spec_version"))) = 0x32303042;/*FBL Version: B002*/ //uint32_t Test_u32FBLSpecVersion __attribute__((section (".loader_and_spec_version"))) = 0x31303153;/*FBL Requirement Spec Version: S101*/ #pragma ghs section rodata = ".loader_and_spec_version" const uint8_t FBL_au8FLID[32] = { Capri_Platform_X,Capri_Platform_0,Capri_Platform_1,Capri_Platform_underline,Capri_Platform_A,Capri_Platform_N,Capri_Platform_0,Capri_Platform_1, Capri_Platform_2,Capri_Platform_underline,Capri_Platform_S,Capri_Platform_W,Capri_Platform_F,Capri_Platform_B,Capri_Platform_underline, 'B',FBL_nVersionMajor,FBL_nVersionMinor,FBL_nVersionSub,Capri_Platform_Point, 'S',FBLReqSpec_nVersionMajor,FBLReqSpec_nVersionMinor,FBLReqSpec_nVersionSub, Capri_Platform_Point,FLU_nVersionMajor,FLU_nVersionMinor,Capri_Platform_Point,Capri_Platform_Point,Capri_Platform_Point,Capri_Platform_Point,Capri_Platform_Point }; //const uint8_t FBLReqSpec_au8FLID[4] = {'S',FBLReqSpec_nVersionMajor,FBLReqSpec_nVersionMinor,FBLReqSpec_nVersionSub}; #pragma ghs section rodata = default /*return to normal memory writing*/ typedef void(*AppEntry)(void); /* STIM configuration */ static const STIM_Config_t stimConfig = { .workMode = STIM_FREE_COUNT, /*counter clock is 16M, compare value = 1600000, period = 100ms*/ .compareValue = 1600000, .countResetMode = STIM_INCREASE_FROM_0, .clockSource = STIM_FUNCTION_CLOCK, }; /* PLL parameter structure*/ CLK_PLLConfig_t PLL160M = { .pllPreDivider = PLL_PRE_DIV_VALUE_2, /* PLL pre divider value is 2 */ .pllPostDivider = PLL_POST_DIV_VALUE_8, /* PLL post divider value is 8 */ .pllMultiplier = 80, /* PLL multiplier value is 80 */ .pllRefClock = PLL_OSC_CLK, /* PLL select OSC as reference clock */ .pllPreScaler = PLL_SCALER_VALUE_2, /* PLL prescaler value is 2 */ }; /* spi master initial configuration */ const SPI_Config_t spiMasterConfigStruct = { .mode = SPI_MODE_MASTER, /* spi mode */ .dataSize = 16, /* data frame size--16 Bits */ .clkPhase = SPI_CLK_PHASE_SECOND, /* clock phase */ .clkPolarity = SPI_CLK_INACTIVE_LOW, /* clock polarity */ .transMode = SPI_TMOD_TR, /* transfer mode */ .clkDivider = 32, /* clock Divider--16MHz OSC/32 = 500kHz,it means SPI communication clock is 500kHz.*/ .transFifoThr = 1, /* transmit FIFO threshold level */ .recvFifoThr = 1 /* receive FIFO threshold level */ }; void BL_ProcessFLUJumpToFBLFlag(void) { uint8_t bl_rspdata[4]; /* response data */ bl_rspdata[0] = 0x71; bl_rspdata[1] = 0x01; bl_rspdata[2] = 0xFF; bl_rspdata[3] = 0x01; if(ChkFLU_JumpTo_FBLFlag() == SET) { network_send_udsmsg(bl_rspdata,4); ClearFLU_JumpTo_FBLFlag(); } else { /* currently nothing to do */ } } static FlagStatus_t CheckAppValid(void) { FlagStatus_t res = RESET; uint32_t AppValidFlag = *((uint32_t*)(AppValidFlagAddr)); if(AppValidFlag == 0xAA55AA55) { res = SET; } return res; } void JumpToApp(void) { AppEntry appEntryFunc; /*When Jump to App, the SP value of App should set by bootloader*/ uint32_t AppStackTopAddr = *(volatile uint32_t*)APP_ENTRY_ADDR; appEntryFunc = (AppEntry)(*(uint32_t *)(APP_ENTRY_ADDR + APP_RstHdl_OFFSET)); Z20_SCB->VTOR = APP_ENTRY_ADDR; COMMON_SetMSP(AppStackTopAddr); /*Set MSP resgister value to App Stack Point Address*/ COMMON_SetPSP(AppStackTopAddr); /*Set PSP resgister value to App Stack Point Address*/ COMMON_DSB(); /*data sync??*/ appEntryFunc(); while(1){;} } void SpiInit(void) { /* choose osc clock as function clock of spi0 */ CLK_ModuleSrc(CLK_SPI0, CLK_SRC_OSC40M); /* set divide ratio of spi0's function clock*/ CLK_SetClkDivider(CLK_SPI0, CLK_DIV_1); /* Reset SPI */ SYSCTRL_ResetModule(SYSCTRL_SPI0); /* Enable SPI clock*/ SYSCTRL_EnableModule(SYSCTRL_SPI0); /* choose osc clock as function clock of portb */ CLK_ModuleSrc(CLK_PORTB, CLK_SRC_OSC40M); /* choose osc clock as function clock of porte */ CLK_ModuleSrc(CLK_PORTE, CLK_SRC_OSC40M); /* enable clock for portb */ SYSCTRL_EnableModule(SYSCTRL_PORTB); /* enable clock for porte */ SYSCTRL_EnableModule(SYSCTRL_PORTE); /* pte0: spi clock -- SPI_A.CLK_uC: PTE0*/ PORT_PinmuxConfig(PORT_E, GPIO_0, PTE0_SPI0_SCK); /* pte1: spi master rx -- SPI_A.MISO: PTE1*/ PORT_PinmuxConfig(PORT_E, GPIO_1, PTE1_SPI0_SIN); /* pte2: spi master tx -- SPI_A.MOSI_uC: PTE2*/ PORT_PinmuxConfig(PORT_E, GPIO_2, PTE2_SPI0_SOUT); /* ptb5: spi pcs0:cs_sbc -- SPI_A.CS_SBC: PTB5 -- Up to 2 slave peripheral select signals(SS) supported when in the master mode*/ PORT_PinmuxConfig(PORT_B, GPIO_5, PTB5_SPI0_PCS0); /* Initiate spi0 */ SPI_Init(SPI_ID_0, &spiMasterConfigStruct); /* Pull down the CS signal to select slave */ SPI_SelectSlave(SPI_ID_0, SPI_SS_PCS0); /* Enable spi */ SPI_Enable(SPI_ID_0); } void SpiDeInit(void) { /* Reset SPI */ SYSCTRL_ResetModule(SYSCTRL_SPI0); /* Disable spi */ SPI_Disable(SPI_ID_0); /* Disable SPI clock*/ SYSCTRL_DisableModule(SYSCTRL_SPI0); } static void CANPinmuxInit(void) { #if ((BL_INTERFACE == BL_INTERFACE_CAN_FD)||(BL_INTERFACE == BL_INTERFACE_CAN)) /* Enable PORTA module*/ CLK_ModuleSrc(CLK_PORTA, CLK_SRC_OSC40M); CLK_SetClkDivider(CLK_PORTA, CLK_DIV_1); SYSCTRL_EnableModule(BL_CAN_SYS_PORT); SYSCTRL_EnableModule(SYSCTRL_GPIO); /* Set pin mux */ PORT_PinmuxConfig(BL_CAN_PORT, BL_CAN_TX_IO, BL_CAN_TX_PINMUX); PORT_PinmuxConfig(BL_CAN_PORT, BL_CAN_RX_IO, BL_CAN_RX_PINMUX); /*How to set CAN transceiver StandBy Pin of SBC ???*/ #endif } static void CANPinmuxDeInit(void) { SYSCTRL_ResetModule(BL_CAN_SYS_PORT); SYSCTRL_ResetModule(SYSCTRL_GPIO); SYSCTRL_DisableModule(BL_CAN_SYS_PORT); SYSCTRL_DisableModule(SYSCTRL_GPIO); } static void STIM_IntCallBack(void) { /*100ms interrupt*/ if(u32LEDCNT < 60) { u32LEDCNT++; } else { u32LEDCNT = 0; } if((u32LEDCNT % 20) == 0) { /*Feed watchdog at each 2000ms timeout and watch dog time out setting value is 3000ms--base on 32 kHz clock src LPO32KHz*/ FeedWatchdog(); } } /*SysTick interrupt handler, base on PLL 160MHz system core clock, only can reach max resolution 100ms*/ void SysTick_Handler(void) { /*1ms interrupt*/ SystemPollingServiceTop1For1ms(); if(gSystickCount < 2000) { gSystickCount++; } else { gSystickCount = 0x0; } } ResultStatus_t SystickInit() { /* Interrupt period is 1ms---base on system clock is PLL160MHz,set counter value to 160000,then the interrupt period is 1ms*/ if (0 != SysTick_Config(160000)) { return ERR; } return SUCC; } static void SysTickDisable(void) { Z20_SYSTICK->LOAD = 0U; /* set reload register */ Z20_SYSTICK->VAL = 0UL; /* Load the SysTick Counter Value */ Z20_SYSTICK->CTRL = 0U; /* Disable SysTick IRQ and SysTick Timer */ INT_SetPriority (SysTick_IRQn, 0U); /* set Priority for Systick Interrupt */ } static void WatchdogInit(void) { volatile uint32_t uLoop = 0; /* clock LPO, no interrupt, normal mode */ if((WDOG_W->WDOG_CS & 0x00070371U) != 0x00040041U) { /* unlock */ WDOG->WDOG_CNT.CNT = 0xB0D9A1C4U; WDOG->WDOG_CNT.CNT = 0x1A1E3B0FU; WDOG_W->WDOG_CS = 0x00040041U; WDOG->WDOG_TMO.TMO = 96000U; while (1U != WDOG->WDOG_CS.CFGUF) { if (uLoop > 0xFFFFFU) { break; } uLoop++; } } else { /* about 3000 ms */ if(SUCC != WDOG_SetTimeoutValue(96000U)) { } } FeedWatchdog(); } static void WatchdogDeinit(void) { if(SUCC != WDOG_SetTimeoutValue(0x1FFFFU)) { } FeedWatchdog(); } static ResultStatus_t ClockInit(void) { ResultStatus_t res = SUCC; /* Set Core and bus clock */ CLK_SetClkDivider(CLK_CORE, CLK_DIV_1); CLK_SetClkDivider(CLK_BUS, CLK_DIV_1); CLK_SetClkDivider(CLK_SLOW, CLK_DIV_2); /* Enable OSC40M */ if(CLK_OSC40MEnable(CLK_OSC_FREQ_MODE_HIGH, ENABLE, CLK_OSC_XTAL) != SUCC) { res = ERR; return res; } /* Init PLL as 160M */ CLK_PLLConfig(&PLL160M); CLK_PLLEnable(ENABLE); /* Choose PLL as system clock */ while(CLK_SysClkSrc(CLK_SYS_PLL)); /* config Flash clock---OSC16MHz/2 = 8MHz */ SYSCTRL_DisableModule(SYSCTRL_FLASH); CLK_ModuleSrc(CLK_FLASH, CLK_SRC_OSC40M); CLK_SetClkDivider(CLK_FLASH, CLK_DIV_2); SYSCTRL_EnableModule(SYSCTRL_FLASH); /* config CAN clock---16MHz */ if(ERR == CLK_ModuleSrc(CLK_CAN1, CLK_SRC_OSC40M)) { res = ERR; return res; } CLK_SetClkDivider(CLK_CAN1, CLK_DIV_1); return res; } static void ClockDeInit(void) { /* select FIRC64M clock as system clock source */ CLK_FIRC64MEnable(ENABLE); if(SUCC == CLK_SysClkSrc(CLK_SYS_FIRC64M)) { CLK_SetClkDivider(CLK_CORE, CLK_DIV_2); CLK_SetClkDivider(CLK_BUS, CLK_DIV_2); CLK_SetClkDivider(CLK_SLOW, CLK_DIV_4); } /* resume CAN clock */ if(SUCC == CLK_ModuleSrc(CLK_CAN1, CLK_SRC_NO)) { } } void StimInit(void) { /* Configure STIM function clock---External XTAL(OSC) is 16MHz*/ CLK_ModuleSrc(CLK_STIM, CLK_SRC_OSC40M); CLK_SetClkDivider(CLK_STIM, CLK_DIV_1); /* Enable STIM module */ SYSCTRL_EnableModule(SYSCTRL_STIM); /* Enable STIM NVIC IRQ*/ INT_EnableIRQ(STIM_IRQn); /* Init STIM_0*/ STIM_Init(STIM_0,&stimConfig); /* Install interrupt callback function */ STIM_InstallCallBackFunc(STIM_0,STIM_INT,STIM_IntCallBack); /* Enable STIM_0 interrupt*/ STIM_IntCmd(STIM_0, ENABLE); /*Enable STIM*/ STIM_Enable(STIM_0); } void StimDeInit(void) { /*Disable STIM*/ STIM_Disable(STIM_0); /* Disable STIM_0 interrupt*/ STIM_IntCmd(STIM_0, DISABLE); /* Disable STIM module */ SYSCTRL_DisableModule(SYSCTRL_STIM); /* Disable STIM NVIC IRQ*/ INT_DisableIRQ(STIM_IRQn); } void SBC_Init(void) { /*Need implementation later*/ SpiInit(); } void SBC_DeInit(void) { /*Need implementation later*/ SpiDeInit(); } static void CrcDeinit(void) { SYSCTRL_ResetModule(SYSCTRL_CRC); SYSCTRL_DisableModule(SYSCTRL_CRC); } void SysInit(void) { /* Watchdog init and watch dog timeout value is 3s--Clock source of watch dog is LPO32KHz */ WatchdogInit(); /* CLock init*/ ClockInit(); /* System Tick init*/ SystickInit(); /* Init stim*/ StimInit(); /* CAN-FD init*/ CanInit(); /* CAN Port/IO init */ CANPinmuxInit(); /*Init Flash Driver*/ FlashInit(); /* SBC Init--TBD and need to do--System Basic Chip---may be only need feed SBC chip watchdog */ SBC_Init(); /*Uds service Init*/ Uds_init(); /* Init CRC*/ Crc_HwInit(); sbcinit(); /* Disable wdog (wdog is enabled when default)*/ /*WDOG_Disable();*/ Crc_Test(); BL_ProcessFLUJumpToFBLFlag(); } void SysDeInit(void) { CANPinmuxDeInit(); SYSCTRL_DisableModule(SYSCTRL_REGFILE); CrcDeinit(); CanReset();/*Caused HardFault Exception, so temporary commented it*/ SysTickDisable(); ClockDeInit(); WatchdogDeinit(); StimDeInit();/*Caused HardFault Exception, so temporary commented it*/ SBC_DeInit();/*Caused HardFault Exception, so temporary commented it*/ } int main(void) { bool boFBL20ms_Window_Reopen = FALSE; /*Each time system reset we should ReSET 20ms delay counter*/ system_20msdelayCNT = 0x0; /*JumpToApp();*/ SYSCTRL_EnableModule(SYSCTRL_REGFILE); SysInit(); if(((*(uint32_t*)0x20000984) != 0x55AA55AA) && (SET == CheckAppValid())) { /*When External reprogramming flag is invalid and APP is valid, then start 20ms window time delay*/ while(system_20msdelayCNT <= 20) { /* During the 20ms window time delay, if we received UDS 0x10 0x03 command, we should stay in FBL extend session and not jump to APP*/ if(udsFbl_GetCurrentSessionMode() == 0x04) { boFBL20ms_Window_Reopen = TRUE; } } if(boFBL20ms_Window_Reopen == FALSE) { /*During the 20ms window time delay, we don't received UDS 0x10 0x03 command,we should jump to APP immediately*/ SysDeInit(); JumpToApp(); } } while(1) { Task_mananager(); } }