FLASH OPTR write routine implemented and tested.
Fixed wrong GPIO output values initialization.
This commit is contained in:
true 2023-10-21 04:43:58 -07:00
parent 13700b96ca
commit b581b87b86
6 changed files with 62 additions and 24 deletions

View File

@ -48,7 +48,7 @@
#define CONF_MODE_AN ADC_CHSELR_CHSEL7
#define RGBSEL0_PORT GPIOA
#define RGBSEL0_PIN 12 // output, default low
#define RGBSEL0_PIN 12 // output, default high
#define UART_PORT GPIOA
#define UART_DEV USART1
@ -64,7 +64,7 @@
#define CONF_SET0_AN ADC_CHSELR_CHSEL8
#define RGBSEL1_PORT GPIOB
#define RGBSEL1_PIN 1 // output, default low
#define RGBSEL1_PIN 1 // output, default high
#define PROBESEL_PORT GPIOF

View File

@ -871,7 +871,7 @@ ErrorStatus LL_FLASH_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
FLASH->CR|=FLASH_CR_OPTSTRT;
/* set bit EOPIE */
// FLASH->CR|=FLASH_CR_EOPIE;
FLASH->CR|=FLASH_CR_EOPIE;
/* trigger program */
*((__IO uint32_t *)(0x40022080))=0xff;

View File

@ -110,7 +110,8 @@ SECTIONS
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.ramfunc*)
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH

View File

@ -108,6 +108,7 @@ SECTIONS
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.ramfunc*)
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */

View File

@ -47,20 +47,12 @@ void flash_optr_checkfix()
}
}
/*
* manually load values into flash option byte, to configure
* the BOR and configure the reset pin to be PF2.
*/
void flash_optr_set()
{
FLASH->OPTR &= (FLASH_OPTR_BOR_EN_Msk | FLASH_OPTR_BOR_LEV_Msk | FLASH_OPTR_NRST_MODE_Msk);
FLASH->OPTR |= OB_BOR_ENABLE | OB_BOR_LEVEL_2p3_2p4 | OB_RESET_MODE_GPIO;
}
void flash_init()
void flash_write_timings_8MHz()
{
// load flash write timings for 8MHz operation
// (these are listed in the datasheet)
// note: if you decide to operate at a different frequency, then either
// update these values, or reduce speed to 8MHz when writing to flash
FLASH->TS0 = 0x3c;
FLASH->TS2P = 0x3c;
FLASH->TS3 = 0x3c;
@ -72,4 +64,45 @@ void flash_init()
FLASH->SMERTPE = 0x5dc0;
FLASH->PRGTPE = 0x1f40;
FLASH->PRETPE = 0x640;
}
__attribute__ ((long_call, section(".ramfunc"))) void flash_init()
{
// configure flash timings
flash_write_timings_8MHz();
// is the PF2/NRST pin configured as reset?
if ((FLASH->OPTR & FLASH_OPTR_NRST_MODE) == OB_RESET_MODE_RESET) {
// it is but shouldn't be, so let's configure it as GPIO.
// per datasheet, we must unlock FLASH->CR and then unlock OPTLOCK
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
if (FLASH->CR & FLASH_CR_LOCK) return; // somehow, flash is still locked
FLASH->OPTKEYR = FLASH_OPTKEY1;
FLASH->OPTKEYR = FLASH_OPTKEY2;
if (FLASH->CR & FLASH_CR_OPTLOCK) return; // somehow, OB is still locked
// write new OPTR values
FLASH->OPTR = OB_RESET_MODE_GPIO | OB_WWDG_SW | OB_IWDG_SW | OB_BOR_LEVEL_2p3_2p4 | FLASH_OPTR_RDP_LEVEL_0;
// OB_BOR_ENABLE
// enable EOPIE (per DS, EOP isn't set unless EOPIE is set)
// and signal that we want to write option bits,
// then trigger the write by writing to a random address shown in the DS
FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_OPTSTRT;
*((__IO uint32_t *)(0x40022080)) = 0x55aa55aa;
// wait for BSY to go low, then EOP to go high
while (FLASH->SR & FLASH_SR_BSY);
while (!(FLASH->SR & FLASH_SR_EOP));
// do an OBL_LAUNCH reset to load the new option bits
// this must be done while OPTLOCK is cleared
FLASH->CR |= FLASH_CR_OBL_LAUNCH;
// as the MCU should have reset, we should never get here.
while(1);
}
}

View File

@ -27,7 +27,12 @@ static inline void gpio_init()
// LL functions to save space.
// though we probably don't _need_ this space...
// set I2C outputs as open drain
// PF2=OUT(high), low speed
// unused pins are analog
GPIOF->ODR = (1 << 2);
GPIOF->MODER = 0xFFFFFCDF;
// set I2C outputs as open drain
GPIOA->OTYPER = 0x000c;
// enable pullups on I2C outputs
GPIOA->PUPDR = 0x24000050;
@ -37,6 +42,8 @@ static inline void gpio_init()
// alternate function select
// PA6=T3C1, PA5=T3C2, PA4=T3C3, PA3=I2C_SCL, PA2=I2C_SDA
GPIOA->AFR[0] = 0x01DDCC00;
// PA12=OUT(high)
GPIOA->ODR = (1 << 12);
// PA14=ALT, PA13=ALT, PA12=OUT, PA11=OUT
// PA7=AN, PA6=AF, PA5=AF, PA4=AF
@ -45,15 +52,11 @@ static inline void gpio_init()
GPIOA->MODER = 0x2900EAAF;
// PB1=OUT, PB0=AN
// PB1=OUT(HIGH), PB0=AN
// unused pins are analog, all outputs are low speed
GPIOB->OSPEEDR = 0x00000000;
GPIOB->ODR = (1 << 1);
GPIOB->MODER = 0xfffffff7;
// PF2=OUT(low), low speed
// unused pins are analog
GPIOF->ODR = (1 << 2);
GPIOF->MODER = 0xFFFFFCDF;
}
static inline void clk_init()
@ -91,7 +94,7 @@ int main()
{
// base hardware initialization
clk_init();
flash_init(); // also configures option bytes, if necessary
flash_init(); // also configures option bytes to enable PF2, if necessary
gpio_init();
// peripheral initialization
@ -119,7 +122,7 @@ int main()
* main application interrupt
*/
void SysTick_Handler(void)
__attribute__ ((long_call, section(".ramfunc"))) void SysTick_Handler(void)
{
uint16_t cs;