stmbl/stm32f103/bootloader/main.c

134 lines
3.4 KiB
C

#include "f103.h"
#define STACK_TOP 0x20002000 // just a tiny stack for demo
static void nmi_handler(void);
static void hardfault_handler(void);
int main(void);
// Define the vector table
uint32_t *myvectors[4]
__attribute__ ((section("vectors"))) = {
(uint32_t *) STACK_TOP, // stack pointer
(uint32_t *) main, // code entry point
(uint32_t *) nmi_handler, // NMI handler (not really)
(uint32_t *) hardfault_handler // hard fault handler
};
void clock_setup(){ // 8MHz HSE -> 72MHz
FLASH->ACR.LATENCY = 2; // flash latency = 2 wait states
RCC->CR.HSEON = 1; // enable HSE
RCC->CFGR.PLLXTPRE = 0; // HSE prediv = 1
while(RCC->CR.HSERDY == 0){} // wait for HSE startup
RCC->CFGR.PLLSRC = 1; // pll input = HSE
RCC->CFGR.PLLMUL = 7; // pll multiplicator = 9
RCC->CR.PLLON = 1; // enable pll
while(RCC->CR.PLLRDY == 0){} // wait for pll startup
RCC->CFGR.HPRE = 0; // HCLK prescaler = 1
RCC->CFGR.SW = 2; // SYSCLK = PLL
while(RCC->CFGR.SWS != 2){} // wait for SYSCLK switch
RCC->CFGR.PPRE1 = 4; // APB1 prescaler = 2
RCC->CFGR.PPRE2 = 0; // APB2 prescaler = 1
RCC->CFGR.ADCPRE = 2; // ADC prescaler = 6
}
void gpio_setup(){
RCC->APB2ENR.IOPCEN = 1; // enable GPIOC
GPIOC->CRL.MODE0 = 2; // PC0 = output 2MHz
GPIOC->CRL.CNF0 = 0; // PC0 = push pull
GPIOC->CRL.MODE1 = 2; // PC1 = output 2MHz
GPIOC->CRL.CNF1 = 0; // PC1 = push pull
GPIOC->CRL.MODE2 = 2; // PC2 = output 2MHz
GPIOC->CRL.CNF2 = 0; // PC2 = push pull
//RCC->AHBENR.IOPAEN = 1; // enable GPIOA
}
void uart_setup(){
RCC->APB1ENR.USART2EN = 1; // usart2 en
RCC->APB2ENR.AFIOEN = 1; // afio en
RCC->APB2ENR.IOPAEN = 1; // enable GPIOA
GPIOA->CRL.MODE2 = 1; // PA2 = output 10MHz
GPIOA->CRL.CNF2 = 2; // PA2 = afio push pull
GPIOA->CRL.MODE3 = 0; // PA2 = input
GPIOA->CRL.CNF3 = 1; // PA2 = floating input
uint32_t div = 72000000 / 2 / 2250000 + 0.5;
USART2->BRR.DIV_Mantissa = div / 16;
USART2->BRR.DIV_Fraction = div & 0x000F;
// USART2->BRR.w = div;
// USART2->BRR.w = 16;
USART2->CR1.RE = 1; // rx en
USART2->CR1.TE = 1; // tx en
USART2->CR1.UE = 1; // usart en
}
void flash_unlock(){
FLASH->KEYR.KEY = 0x45670123;
FLASH->KEYR.KEY = 0xCDEF89AB;
FLASH->CR.PG = 1;
}
void flash_clear(uint32_t page){
while(FLASH->SR.BSY == 1){}
FLASH->CR.PER = 1;
FLASH->AR.FAR = page;
FLASH->CR.STRT = 1;
while(FLASH->SR.BSY == 1){}
FLASH->CR.PER = 0;// only lib, not in docs
//TODO: verify
}
void flash_write(uint32_t addr, uint16_t data){
while(FLASH->SR.BSY == 1){}
FLASH->CR.PG = 1;
*(volatile uint16_t*)addr = data;
while(FLASH->SR.BSY == 1){}
FLASH->CR.PG = 0;// only lib, not in docs
//TODO: verify
}
int main(void)
{
uint32_t i=0;
gpio_setup();
clock_setup();
uart_setup();
flash_unlock();
for(int i = 1024;i<2048*2;i+=2){
flash_write(0x8000000+i,0x5555);
}
flash_clear(0x8000000+1024);
for(;;){
if(USART2->SR.RXNE == 1 && USART2->SR.TXE == 1){
USART2->DR.DR = USART2->DR.DR;
}
i++;
if(i > 100000){
GPIOC->ODR.ODR0 = 0; // reset PC0
//USART2->DR.DR = 0x55;
}
if(i > 200000){ // read PA0
GPIOC->ODR.ODR0 = 1; // set PC0
// USART2->DR.DR = 0xAA;
i = 0;
}
}
}
void nmi_handler(void)
{
for(;;);
}
void hardfault_handler(void)
{
for(;;);
}