BootJump_ARTERY_AT32/Src/BootJump.c

171 lines
8.0 KiB
C

//
// Created by xemon on 02.11.22.
//
#include CMSIS_device_header
typedef void (*pFunction)(void);
__attribute__(( naked, noreturn )) void BootJumpASM(uint32_t SP, uint32_t RH) {
__asm("MSR MSP,r0");
__asm("BX r1");
}
#define EnablePrivilegedMode() __asm("SVC #0")
static void BootJumpA(uint32_t *Address) {
if (CONTROL_nPRIV_Msk &
__get_CONTROL()) //THIS is from the arm doku, but it is always false in our implementation and skipped.
{ /* not in privileged mode */
EnablePrivilegedMode( ) ;
}
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICPR[0] = 0xFFFFFFFF;
SysTick->CTRL = 0;
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
if (CONTROL_SPSEL_Msk &
__get_CONTROL()) //THIS is from the arm doku, but it is always false in our implementation and skipped. (only 1 stack pointer used)
{ /* MSP is not active */
__set_MSP(__get_PSP());
__set_CONTROL(__get_CONTROL() & ~CONTROL_SPSEL_Msk);
}
SCB->VTOR = (uint32_t) Address; //Setting the Vector Table Offset Register to the start of the user app.
// BootJumpASM(Address[0], Address[1]); //This function is taken from the Arm Documentation
}
void BootJumpToAddress(const uint32_t address) {
BootJumpA(address);
//
// while (1);
#if defined (AT32F437xx)
__disable_irq();
/* ahb periph1 */
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, FALSE); /*!< gpioa periph clock */
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, FALSE); /*!< gpiob periph clock */
crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, FALSE); /*!< gpioc periph clock */
crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, FALSE); /*!< gpiod periph clock */
crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, FALSE); /*!< gpioe periph clock */
crm_periph_clock_enable(CRM_GPIOF_PERIPH_CLOCK, FALSE); /*!< gpiof periph clock */
crm_periph_clock_enable(CRM_GPIOG_PERIPH_CLOCK, FALSE); /*!< gpiog periph clock */
crm_periph_clock_enable(CRM_GPIOH_PERIPH_CLOCK, FALSE); /*!< gpioh periph clock */
crm_periph_clock_enable(CRM_CRC_PERIPH_CLOCK, FALSE); /*!< crc periph clock */
crm_periph_clock_enable(CRM_EDMA_PERIPH_CLOCK, FALSE); /*!< edma periph clock */
crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, FALSE); /*!< dma1 periph clock */
crm_periph_clock_enable(CRM_DMA2_PERIPH_CLOCK, FALSE); /*!< dma2 periph clock */
crm_periph_clock_enable(CRM_EMAC_PERIPH_CLOCK, FALSE); /*!< emac periph clock */
crm_periph_clock_enable(CRM_EMACTX_PERIPH_CLOCK, FALSE); /*!< emac tx periph clock */
crm_periph_clock_enable(CRM_EMACRX_PERIPH_CLOCK, FALSE); /*!< emac rx periph clock */
crm_periph_clock_enable(CRM_EMACPTP_PERIPH_CLOCK, FALSE); /*!< emac ptp periph clock */
crm_periph_clock_enable(CRM_OTGFS2_PERIPH_CLOCK, FALSE); /*!< otgfs2 periph clock */
/* ahb periph2 */
crm_periph_clock_enable(CRM_DVP_PERIPH_CLOCK, FALSE); /*!< dvp periph clock */
crm_periph_clock_enable(CRM_OTGFS1_PERIPH_CLOCK, FALSE); /*!< otgfs1 periph clock */
crm_periph_clock_enable(CRM_SDIO1_PERIPH_CLOCK, FALSE); /*!< sdio1 periph clock */
/* ahb periph3 */
crm_periph_clock_enable(CRM_XMC_PERIPH_CLOCK, FALSE); /*!< xmc periph clock */
crm_periph_clock_enable(CRM_QSPI1_PERIPH_CLOCK, FALSE); /*!< qspi1 periph clock */
crm_periph_clock_enable(CRM_QSPI2_PERIPH_CLOCK, FALSE); /*!< qspi2 periph clock */
crm_periph_clock_enable(CRM_SDIO2_PERIPH_CLOCK, FALSE); /*!< sdio2 periph clock */
/* apb1 periph */
crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, FALSE); /*!< tmr2 periph clock */
crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, FALSE); /*!< tmr3 periph clock */
crm_periph_clock_enable(CRM_TMR4_PERIPH_CLOCK, FALSE); /*!< tmr4 periph clock */
crm_periph_clock_enable(CRM_TMR5_PERIPH_CLOCK, FALSE); /*!< tmr5 periph clock */
crm_periph_clock_enable(CRM_TMR6_PERIPH_CLOCK, FALSE); /*!< tmr6 periph clock */
crm_periph_clock_enable(CRM_TMR7_PERIPH_CLOCK, FALSE); /*!< tmr7 periph clock */
crm_periph_clock_enable(CRM_TMR12_PERIPH_CLOCK, FALSE); /*!< tmr12 periph clock */
crm_periph_clock_enable(CRM_TMR13_PERIPH_CLOCK, FALSE); /*!< tmr13 periph clock */
crm_periph_clock_enable(CRM_TMR14_PERIPH_CLOCK, FALSE); /*!< tmr14 periph clock */
crm_periph_clock_enable(CRM_WWDT_PERIPH_CLOCK, FALSE); /*!< wwdt periph clock */
crm_periph_clock_enable(CRM_SPI2_PERIPH_CLOCK, FALSE); /*!< spi2 periph clock */
crm_periph_clock_enable(CRM_SPI3_PERIPH_CLOCK, FALSE); /*!< spi3 periph clock */
crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, FALSE); /*!< usart2 periph clock */
crm_periph_clock_enable(CRM_USART3_PERIPH_CLOCK, FALSE); /*!< usart3 periph clock */
crm_periph_clock_enable(CRM_UART4_PERIPH_CLOCK, FALSE); /*!< uart4 periph clock */
crm_periph_clock_enable(CRM_UART5_PERIPH_CLOCK, FALSE); /*!< uart5 periph clock */
crm_periph_clock_enable(CRM_I2C1_PERIPH_CLOCK, FALSE); /*!< i2c1 periph clock */
crm_periph_clock_enable(CRM_I2C2_PERIPH_CLOCK, FALSE); /*!< i2c2 periph clock */
crm_periph_clock_enable(CRM_I2C3_PERIPH_CLOCK, FALSE); /*!< i2c3 periph clock */
crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, FALSE); /*!< can1 periph clock */
crm_periph_clock_enable(CRM_CAN2_PERIPH_CLOCK, FALSE); /*!< can2 periph clock */
crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, FALSE); /*!< pwc periph clock */
crm_periph_clock_enable(CRM_DAC_PERIPH_CLOCK, FALSE); /*!< dac periph clock */
crm_periph_clock_enable(CRM_UART7_PERIPH_CLOCK, FALSE); /*!< uart7 periph clock */
crm_periph_clock_enable(CRM_UART8_PERIPH_CLOCK, FALSE); /*!< uart8 periph clock */
/* apb2 periph */
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, FALSE); /*!< tmr1 periph clock */
crm_periph_clock_enable(CRM_TMR8_PERIPH_CLOCK, FALSE); /*!< tmr8 periph clock */
crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, FALSE); /*!< usart1 periph clock */
crm_periph_clock_enable(CRM_USART6_PERIPH_CLOCK, FALSE); /*!< usart6 periph clock */
crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, FALSE); /*!< adc1 periph clock */
crm_periph_clock_enable(CRM_ADC2_PERIPH_CLOCK, FALSE); /*!< adc2 periph clock */
crm_periph_clock_enable(CRM_ADC3_PERIPH_CLOCK, FALSE); /*!< adc3 periph clock */
crm_periph_clock_enable(CRM_SPI1_PERIPH_CLOCK, FALSE); /*!< spi1 periph clock */
crm_periph_clock_enable(CRM_SPI4_PERIPH_CLOCK, FALSE); /*!< spi4 periph clock */
crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, FALSE); /*!< scfg periph clock */
crm_periph_clock_enable(CRM_TMR9_PERIPH_CLOCK, FALSE); /*!< tmr9 periph clock */
crm_periph_clock_enable(CRM_TMR10_PERIPH_CLOCK, FALSE); /*!< tmr10 periph clock */
crm_periph_clock_enable(CRM_TMR11_PERIPH_CLOCK, FALSE); /*!< tmr11 periph clock */
crm_periph_clock_enable(CRM_TMR20_PERIPH_CLOCK, FALSE); /*!< tmr20 periph clock */
crm_periph_clock_enable(CRM_ACC_PERIPH_CLOCK, FALSE); /*!< acc periph clock */
#elif
#error "нужно сделать выключение всей переферии под текущий контроллер, пример выше"
#endif
uint32_t appStack;
pFunction appEntry;
// get the application stack pointer (1st entry in the app vector table)
appStack = (uint32_t) *((__IO uint32_t *) address);
// Get the app entry point (2nd entry in the app vector table
appEntry = (pFunction) *(__IO uint32_t *) (address + 4);
// HAL_RCC_DeInit();
// HAL_DeInit();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
uint32_t i = SCB->VTOR;
i++;
// Reconfigure vector table offset to match the app location
//#if (SET_VECTOR_TABLE)
// SCB->VTOR = address;
//#endif
//
//// __disable_irq(); // disable interrupt
//// __enable_irq();
//// __set_PRIMASK(1);
//// __set_MSP(appStack); // Set app stack pointer
//останавливаем SysTick
SysTick->CTRL = 0UL;
SysTick->VAL = 0UL;
__set_MSP(appStack);
SCB->VTOR = address;
__enable_irq();
// __asm volatile ( "bl 0x08020004");
appEntry(); // Start the app
while (1); // never reached
}