uint32_t program( uint32_t *address, uint32_t *buffer ) // size is 256 bytes { uint32_t FlashSectorNum ; uint32_t flash_cmd = 0 ; uint32_t i ; if ( (uint32_t) address >= 0x00408000 ) { return 1 ; } // Always initialise this here, setting a default doesn't seem to work IAP_Function = (uint32_t (*)(uint32_t, uint32_t)) *(( uint32_t *)0x00800008) ; FlashSectorNum = (uint32_t) address ; FlashSectorNum >>= 8 ; // page size is 256 bytes FlashSectorNum &= 2047 ; // max page number /* Send data to the sector here */ for ( i = 0 ; i < 64 ; i += 1 ) { *address++ = *buffer++ ; } /* build the command to send to EEFC */ flash_cmd = (0x5A << 24) | (FlashSectorNum << 8) | 0x03 ; //AT91C_MC_FCMD_EWP ; __disable_irq() ; /* Call the IAP function with appropriate command */ i = IAP_Function( 0, flash_cmd ) ; __enable_irq() ; return i ; }
/**************************************************************************//** \brief Unlocks page in Flash \param[in] page - page number to unlock ******************************************************************************/ void flashUnlockPage(uint16_t page) { uint32_t cmd; cmd = FLASH_WRITE_ENABLE_MAGIC | FLASH_CMD_CLB | ((uint32_t)page << 8); IAP_Function = (uint32_t (*)(uint32_t, uint32_t)) *((uint32_t *)IAP_ADDRESS); IAP_Function(0, cmd); }
uint32_t readLockBits() { // Always initialise this here, setting a default doesn't seem to work IAP_Function = (uint32_t (*)(uint32_t, uint32_t)) *(( uint32_t *)0x00800008); uint32_t flash_cmd = (0x5A << 24) | 0x0A;//AT91C_MC_FCMD_GLB ; __disable_irq(); (void) IAP_Function( 0, flash_cmd ); __enable_irq(); return EFC->EEFC_FRR; }
/**************************************************************************//** \brief Writes page to flash optionally locking Flash after write \param[in] page - page number to write to \param[in] lock - true if locking is required after write ******************************************************************************/ void flashWritePage(uint16_t page, bool lock) { uint32_t cmd; if (lock) cmd = FLASH_WRITE_ENABLE_MAGIC | FLASH_CMD_EWPL | ((uint32_t)page << 8); else cmd = FLASH_WRITE_ENABLE_MAGIC | FLASH_CMD_EWP | ((uint32_t)page << 8); IAP_Function = (uint32_t (*)(uint32_t, uint32_t)) *((uint32_t *)IAP_ADDRESS); IAP_Function(0, cmd); }
void clearLockBits() { uint32_t i; uint32_t flash_cmd = 0; // Always initialise this here, setting a default doesn't seem to work IAP_Function = (uint32_t (*)(uint32_t, uint32_t)) *(( uint32_t *)0x00800008); for ( i = 0; i < 16; i += 1 ) { flash_cmd = (0x5A << 24) | ((128*i) << 8) | 0x09; //AT91C_MC_FCMD_CLB ; __disable_irq(); /* Call the IAP function with appropriate command */ (void) IAP_Function( 0, flash_cmd ); __enable_irq(); } }