#include "flash.h" #include "usb.h" #include "ownership.h" MODULE_OWNS_PERIPHERAL(FLASH); static inline void Flash_Unlock(void) { FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2; } static inline void Flash_Lock(void) { FLASH->CR = FLASH_CR_LOCK; } Flash_Status_t Flash_ErasePage(unsigned int page) { if(page >= FLASH_PAGES) { return FLASH_PROHIBITED; } uint32_t page_start = FLASH_BASE + page * FLASH_PAGE_BYTES; Flash_Unlock(); while(FLASH->SR & FLASH_SR_BSY); FLASH->CR = FLASH_CR_PER; FLASH->AR = page_start; FLASH->CR = FLASH_CR_STRT | FLASH_CR_PER; while(FLASH->SR & FLASH_SR_BSY); // Flash_Lock() clears the PER bit, so we don't have to reset that Flash_Lock(); // Verify for(uint32_t i = page_start; i < page_start + FLASH_PAGE_BYTES; i += 4) { if(*(uint32_t*)i != 0xffffffff) { return FLASH_VERIFY_FAILED; } } return FLASH_SUCCESS; } void Flash_ProgramFromPMA(uint32_t flash_adress, uint16_t pma_offset, uint32_t length) { Flash_Unlock(); uint16_t *pma = (uint16_t*)(USB_PMA_ADDR + 2 * pma_offset); volatile uint16_t *flash = (uint16_t*)flash_adress; FLASH->CR = FLASH_CR_PG; for(unsigned int i = 0; i < (length + 1) / 2; i++) { *flash++ = *pma++; pma++; while(FLASH->SR & FLASH_SR_BSY); } // Flash_Lock() clears the PG bit, so we don't have to reset that Flash_Lock(); }