Skip to content

Commit

Permalink
EEPROM emulation STM32F0
Browse files Browse the repository at this point in the history
  • Loading branch information
Paciente8159 committed Apr 15, 2024
1 parent 21a9163 commit eab1525
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 141 deletions.
3 changes: 2 additions & 1 deletion boards/genericSTM32F0.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"jlink",
"stlink",
"blackmagic",
"serial"
"serial",
"cmsis-dap"
]
},
"url": "https://doc.riot-os.org/group__boards__bluepill-stm32f030c8.html",
Expand Down
6 changes: 3 additions & 3 deletions uCNC/src/hal/boards/stm32/stm32.ini
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ build_flags = ${common_stm32.build_flags} -D BOARD=BOARD_NUCLEO_F411RE_SHIELD_V3
[env:STM32F0-Bluepill-F030R8]
extends = common_stm32
board = genericSTM32F0
upload_protocol = stlink
debug_tool=stlink
; upload_protocol = stlink
; debug_tool=stlink
board_build.mcu = stm32f030c8t6
board_build.f_cpu = 48000000L
; board_debug.openocd_target = stm32f0x
lib_deps =
build_flags = ${common_stm32.build_flags} -D BOARD=BOARD_BLUEPILL_F0 -DFLASH_SIZE=0x10000UL -DRAM_ONLY_SETTINGS
build_flags = ${common_stm32.build_flags} -D BOARD=BOARD_BLUEPILL_F0 -DFLASH_SIZE=0x10000UL
254 changes: 117 additions & 137 deletions uCNC/src/hal/mcus/stm32f0x/mcu_stm32f0x.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,25 @@
#error "The set FLASH_SIZE is beyond the chip capability"
#endif

// set the FLASH EEPROM SIZE
#define FLASH_EEPROM_SIZE 0x400
#define FLASH_EEPROM_SIZE_WORD (FLASH_EEPROM_SIZE >> 2)
#define FLASH_EEPROM_SIZE_WORD_ALIGNED (FLASH_EEPROM_SIZE_WORD << 2)

#define FLASH_SECTOR_SIZE 0x20000UL
#define FLASH_SECTORS (FLASH_SIZE / FLASH_SECTOR_SIZE) + 4

#define FLASH_EEPROM_START (FLASH_LIMIT - FLASH_SECTOR_SIZE + 1)
#define FLASH_EEPROM_PER_SECTION (FLASH_SECTOR_SIZE / FLASH_EEPROM_SIZE_WORD_ALIGNED)
#define FLASH_EEPROM_END (FLASH_EEPROM_START + (FLASH_EEPROM_PER_SECTION * FLASH_EEPROM_SIZE_WORD_ALIGNED) - 1)
// read and write invert
#if (FLASH_BANK1_END <= 0x0801FFFFUL)
#define FLASH_PAGE_SIZE (1 << 10)
#define FLASH_EEPROM_PAGES (((NVM_STORAGE_SIZE - 1) >> 10) + 1)
#define FLASH_EEPROM (FLASH_LIMIT - ((FLASH_EEPROM_PAGES << 10) - 1))
#define FLASH_PAGE_MASK (0xFFFF - (1 << 10) + 1)
#define FLASH_PAGE_OFFSET_MASK (0xFFFF & ~FLASH_PAGE_MASK)
#else
#define FLASH_PAGE_SIZE 0x800
#define FLASH_EEPROM_PAGES (((NVM_STORAGE_SIZE - 1) >> 11) + 1)
#define FLASH_EEPROM (FLASH_LIMIT - ((FLASH_EEPROM_PAGES << 11) - 1))
#define FLASH_PAGE_MASK (0xFFFF - (1 << 11) + 1)
#define FLASH_PAGE_OFFSET_MASK (0xFFFF & ~FLASH_PAGE_MASK)
#endif

#define READ_FLASH(ram_ptr, flash_ptr) (*ram_ptr = ~(*flash_ptr))
#define WRITE_FLASH(flash_ptr, ram_ptr) (*flash_ptr = ~(*ram_ptr))
#define EEPROM_CLEAN 0
#define EEPROM_DIRTY 1
#define EEPROM_NEEDS_NEWPAGE 2

static uint8_t stm32_eeprom_buffer[FLASH_EEPROM_SIZE_WORD_ALIGNED];
static uint32_t stm32_flash_current_offset;
static uint8_t stm32_flash_modified;
static void FORCEINLINE mcu_eeprom_init(void);
static uint8_t stm32_flash_page[FLASH_PAGE_SIZE];
static uint16_t stm32_flash_current_page;
static bool stm32_flash_modified;

/**
* The internal clock counter
Expand Down Expand Up @@ -631,10 +628,10 @@ void mcu_init(void)
mcu_config_af(SPI_CS, SPI_CS_AFIO);
#endif
// initialize the SPI configuration register
SPI_REG->CR1 = SPI_CR1_SSM // software slave management enabled
| SPI_CR1_SSI // internal slave select
| SPI_CR1_MSTR; // SPI master mode
// | (SPI_SPEED << 3) | SPI_MODE;
SPI_REG->CR1 = SPI_CR1_SSM // software slave management enabled
| SPI_CR1_SSI // internal slave select
| SPI_CR1_MSTR; // SPI master mode
// | (SPI_SPEED << 3) | SPI_MODE;
mcu_spi_config(SPI_MODE, SPI_FREQ);

SPI_REG->CR1 |= SPI_CR1_SPE;
Expand All @@ -660,9 +657,8 @@ void mcu_init(void)
#endif

mcu_disable_probe_isr();
stm32_flash_current_offset = 0;
stm32_flash_current_page = -1;
stm32_global_isr_enabled = false;
mcu_eeprom_init();
mcu_enable_global_isr();
}

Expand Down Expand Up @@ -809,137 +805,121 @@ void mcu_dotasks()
#endif
}

// gets were the first copy of the eeprom is
static void mcu_eeprom_init(void)
// checks if the current page is loaded to ram
// if not loads it
static uint16_t mcu_access_flash_page(uint16_t address)
{
// uint32_t eeprom_offset = 0;
// for (eeprom_offset = 0; eeprom_offset < FLASH_SECTOR_SIZE; eeprom_offset += FLASH_EEPROM_SIZE_WORD_ALIGNED)
// {
// if (*((volatile uint32_t *)(FLASH_EEPROM_START + eeprom_offset)) == 0xFFFFFFFF)
// {
// break;
// }
// }

// // if not found at start then it's not initialized
// if (eeprom_offset)
// {
// // one step back
// eeprom_offset -= FLASH_EEPROM_SIZE_WORD_ALIGNED;
// stm32_flash_current_offset = eeprom_offset;
// }
// else
// {
// stm32_flash_current_offset = 0;
// stm32_flash_modified = EEPROM_CLEAN;
// memset(stm32_eeprom_buffer, 0, FLASH_EEPROM_SIZE_WORD_ALIGNED);
// return;
// }
uint16_t address_page = address & FLASH_PAGE_MASK;
uint16_t address_offset = address & FLASH_PAGE_OFFSET_MASK;
if (stm32_flash_current_page != address_page)
{
mcu_eeprom_flush();
stm32_flash_modified = false;
stm32_flash_current_page = address_page;
uint16_t counter = (uint16_t)(FLASH_PAGE_SIZE >> 2);
uint32_t *ptr = ((uint32_t *)&stm32_flash_page[0]);
volatile uint32_t *eeprom = ((volatile uint32_t *)(FLASH_EEPROM + address_page));
while (counter--)
{
READ_FLASH(ptr, eeprom);
eeprom++;
ptr++;
}
}

// uint32_t counter = (uint32_t)FLASH_EEPROM_SIZE_WORD;
// uint32_t *ptr = ((uint32_t *)&stm32_eeprom_buffer[0]);
// volatile uint32_t *eeprom = ((volatile uint32_t *)(FLASH_EEPROM_START + eeprom_offset));
// while (counter--)
// {
// READ_FLASH(ptr, eeprom);
// eeprom++;
// ptr++;
// }
return address_offset;
}

// Non volatile memory
uint8_t mcu_eeprom_getc(uint16_t address)
{
return stm32_eeprom_buffer[address];
if (NVM_STORAGE_SIZE <= address)
{
DEBUG_STR("EEPROM invalid address @ ");
DEBUG_INT(address);
DEBUG_PUTC('\n');
return 0;
}
uint16_t offset = mcu_access_flash_page(address);
return stm32_flash_page[offset];
}

static void mcu_eeprom_erase(void)
static void mcu_eeprom_erase(uint16_t address)
{
// while (FLASH->SR & FLASH_SR_BSY)
// ; // wait while busy
// // unlock flash if locked
// if (FLASH->CR & FLASH_CR_LOCK)
// {
// FLASH->KEYR = 0x45670123;
// FLASH->KEYR = 0xCDEF89AB;
// }
// FLASH->CR = 0; // Ensure PG bit is low
// FLASH->CR |= FLASH_CR_SER | (((FLASH_SECTORS - 1) << FLASH_CR_SNB_Pos) & FLASH_CR_MER_Msk); // set the SER bit
// FLASH->CR |= FLASH_CR_STRT; // set the start bit
// while (FLASH->SR & FLASH_SR_BSY)
// ; // wait while busy
// FLASH->CR = 0;
while (FLASH->SR & FLASH_SR_BSY)
; // wait while busy
// unlock flash if locked
if (FLASH->CR & FLASH_CR_LOCK)
{
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
}
FLASH->CR = 0; // Ensure PG bit is low
FLASH->CR |= FLASH_CR_PER; // set the PER bit
FLASH->AR = (FLASH_EEPROM + address);
FLASH->CR |= FLASH_CR_STRT; // set the start bit
while (FLASH->SR & FLASH_SR_BSY)
; // wait while busy
FLASH->CR = 0;
}

void mcu_eeprom_putc(uint16_t address, uint8_t value)
{
// // if the value of the eeprom is modified then it will be marked as dirty
// // flash default value is 0xFF. If programming can change value from 1 to 0 but not the other way around
// // if a bit is changed from 0 back to 1 then it will need to rewrite values in a new page
// // flash read and writing is done in negated form
// if (stm32_eeprom_buffer[address] != value)
// {
// stm32_flash_modified |= EEPROM_DIRTY;
// if ((value ^ stm32_eeprom_buffer[address]) & ~value)
// {
// stm32_flash_modified |= EEPROM_NEEDS_NEWPAGE;
// }
// }
if (NVM_STORAGE_SIZE <= address)
{
DEBUG_STR("EEPROM invalid address @ ");
DEBUG_INT(address);
DEBUG_PUTC('\n');
}

uint16_t offset = mcu_access_flash_page(address);

if (stm32_flash_page[offset] != value)
{
stm32_flash_modified = true;
}

// stm32_eeprom_buffer[address] = value;
stm32_flash_page[offset] = value;
}

void mcu_eeprom_flush()
{
// if (stm32_flash_modified)
// {
// if (CHECKFLAG(stm32_flash_modified, EEPROM_NEEDS_NEWPAGE))
// {
// stm32_flash_current_offset += FLASH_EEPROM_SIZE_WORD_ALIGNED;
// }

// if (stm32_flash_current_offset >= FLASH_EEPROM_END)
// {
// mcu_eeprom_erase();
// stm32_flash_current_offset = 0;
// }

// volatile uint32_t *eeprom = ((volatile uint32_t *)(FLASH_EEPROM_START + stm32_flash_current_offset));
// uint32_t *ptr = ((uint32_t *)&stm32_eeprom_buffer[0]);
// uint32_t counter = (uint32_t)FLASH_EEPROM_SIZE_WORD;
// while (counter--)
// {
// while (FLASH->SR & FLASH_SR_BSY)
// ; // wait while busy
// mcu_disable_global_isr();
// // unlock flash if locked
// if (FLASH->CR & FLASH_CR_LOCK)
// {
// FLASH->KEYR = 0x45670123;
// FLASH->KEYR = 0xCDEF89AB;
// }
// FLASH->CR = 0;
// FLASH->CR |= FLASH_CR_PSIZE_1;
// FLASH->CR |= FLASH_CR_PG; // Ensure PG bit is high
// WRITE_FLASH(eeprom, ptr);
// while (FLASH->SR & FLASH_SR_BSY)
// ; // wait while busy
// mcu_enable_global_isr();
// if (FLASH->SR & (FLASH_SR_PGAERR | FLASH_SR_PGPERR | FLASH_SR_PGSERR))
// protocol_send_error(42); // STATUS_SETTING_WRITE_FAIL
// if (FLASH->SR & FLASH_SR_WRPERR)
// protocol_send_error(43); // STATUS_SETTING_PROTECTED_FAIL
// FLASH->CR = 0; // Ensure PG bit is low
// FLASH->SR = 0;
// eeprom++;
// ptr++;
// }
// stm32_flash_modified = EEPROM_CLEAN;

// // Restore interrupt flag state.*/
// }
if (stm32_flash_modified)
{
mcu_eeprom_erase(stm32_flash_current_page);
volatile uint16_t *eeprom = ((volatile uint16_t *)(FLASH_EEPROM + stm32_flash_current_page));
uint16_t *ptr = ((uint16_t *)&stm32_flash_page[0]);
uint16_t counter = (uint16_t)(FLASH_PAGE_SIZE >> 1);
while (counter--)
{
while (FLASH->SR & FLASH_SR_BSY)
; // wait while busy
mcu_disable_global_isr();
// unlock flash if locked
if (FLASH->CR & FLASH_CR_LOCK)
{
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
}
FLASH->CR = 0;
FLASH->CR |= FLASH_CR_PG; // Ensure PG bit is high
WRITE_FLASH(eeprom, ptr);
while (FLASH->SR & FLASH_SR_BSY)
; // wait while busy
mcu_enable_global_isr();
if (FLASH->SR & FLASH_SR_PGERR)
protocol_send_error(42); // STATUS_SETTING_WRITE_FAIL
if (FLASH->SR & FLASH_SR_WRPRTERR)
protocol_send_error(43); // STATUS_SETTING_PROTECTED_FAIL
FLASH->CR = 0; // Ensure PG bit is low
FLASH->SR = 0;
eeprom++;
ptr++;
}
stm32_flash_modified = false;
// Restore interrupt flag state.*/
}
}

#ifdef MCU_HAS_SPI
void mcu_spi_config(uint8_t mode, uint32_t frequency)
{
Expand Down

0 comments on commit eab1525

Please sign in to comment.