66 lines
1.4 KiB
C
66 lines
1.4 KiB
C
#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();
|
|
}
|