245 lines
13 KiB
C
245 lines
13 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 */
|
|
#endif
|
|
|
|
#if defined (AT32F435VGT7)
|
|
__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 */
|
|
|
|
#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
|
|
} |