A while back, macros had to be put in place to avoid letting the compiler directly use the bitfields. This was necessary because the compiler used strb instruction which only write bytes. On the AHB bus, byte writes are transformed into word writes by repeating the byte, which caused mayhem in the registers. After a lot of research, turns out the packed attribute stops the compiler from does optimal (word) writes and isn't needed anyway. Removing them fixes the issue
53 lines
1.3 KiB
C
53 lines
1.3 KiB
C
/** @file flash.c
|
|
* Module handling flash memory interface registers.
|
|
*
|
|
* The module provides functions to configure the flash and perform read and
|
|
* writes
|
|
*/
|
|
|
|
//--includes--------------------------------------------------------------------
|
|
|
|
#include "flash.h"
|
|
#include "flash_regs.h"
|
|
|
|
|
|
//--local definitions-----------------------------------------------------------
|
|
|
|
//--local variables-------------------------------------------------------------
|
|
|
|
static volatile struct FLASH* regs = (struct FLASH*)FLASH_BASE_ADDRESS;
|
|
|
|
|
|
//--public functions------------------------------------------------------------
|
|
|
|
/**
|
|
* Sets the correct latency to compensate the core's clock speed. Latency must
|
|
* never be too low or the system will crash due to errors when accessing the
|
|
* flash, hence the warning in the header
|
|
*/
|
|
void flash_configure(enum FlashPreset preset)
|
|
{
|
|
//restore default configuration
|
|
regs->ACR.word &= ~0x3f;
|
|
regs->ACR.word |= 0x30;
|
|
|
|
//apply new configuration
|
|
switch (preset) {
|
|
case FLASH_PRESET_LOW_CLOCK_SPEED:
|
|
regs->ACR.HLFCYA = 1; //half cycle for power saving
|
|
break;
|
|
case FLASH_PRESET_MEDIUM_CLOCK_SPEED:
|
|
regs->ACR.LATENCY = 0x1;
|
|
break;
|
|
case FLASH_PRESET_HIGH_CLOCK_SPEED:
|
|
regs->ACR.LATENCY = 0x2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//--local functions-------------------------------------------------------------
|
|
|