Narasimma DLN
/
NUCLEO_F091RC_IAP_UART
Sample IAP test code for Nucleo_F091RC
stm_iap.cpp
- Committer:
- narasimma23
- Date:
- 2017-06-17
- Revision:
- 0:de2687a62a94
File content as of revision 0:de2687a62a94:
/** * Author: Narasimma DLN * Email: narasimma23@gmail.com */ #include "stm_iap.h" static uint32_t flash_sectors[FLASH_SECTORS]; static uint16_t *flash_size_addr = (uint16_t *)FLASH_SIZE_ADDR; static IAPCode check_error(void); static void unlock_flash(bool unlock); // Get Flash Sectors void get_flash_sectors(void) { uint8_t i; uint32_t _addr = FLASH_START_ADDR; for (i=0; i<FLASH_SECTORS; i++) { flash_sectors[i] = _addr; _addr += FLASH_SECTOR_SIZE; } } // Get Flash Size uint32_t get_flash_size(void) { return *flash_size_addr * 1024; } // Get Sector Number uint8_t get_sector_number(uint32_t _addr) { uint8_t retval = 0; while(1) { //If start address of next sector is higher than wanted address, return current value if (_addr < flash_sectors[retval + 1]) return retval; retval++; } } // Get Sector Size uint32_t get_sector_size(uint32_t _addr) { uint8_t sector = get_sector_number(_addr); return flash_sectors[sector+1] - flash_sectors[sector]; } static IAPCode check_error(void) { //Wait until done while (FLASH->SR & FLASH_SR_BSY); //Check for errors if (FLASH->SR & FLASH_SR_WRPERR) return WriteProtError; if (FLASH->SR & FLASH_SR_PGERR) return ProgrammingError; return Success; } // Erase a Flash Sector IAPCode erase_sector(int address) { uint8_t sec_num = get_sector_number(address); unlock_flash(true); //Clear current errors FLASH->SR = FLASH_SR_WRPERR | FLASH_SR_PGERR; //Run command // Page 1 FLASH->CR |= FLASH_CR_PER; FLASH->AR = flash_sectors[sec_num]; FLASH->CR |= FLASH_CR_STRT; while (FLASH->SR & FLASH_SR_BSY); // Page 2 FLASH->CR |= FLASH_CR_PER; FLASH->AR = flash_sectors[sec_num] + FLASH_PAGE_SIZE; FLASH->CR |= FLASH_CR_STRT; while (FLASH->SR & FLASH_SR_BSY); if ((FLASH->SR & FLASH_SR_EOP) != 0) FLASH->SR = FLASH_SR_EOP; FLASH->CR &= ~FLASH_CR_PER; unlock_flash(false); IAPCode retval = check_error(); return retval; } // Unlocking Flash static void unlock_flash(bool unlock) { if (unlock) { __disable_irq(); //Wait until not busy while (FLASH->SR & FLASH_SR_BSY); if ((FLASH->CR & FLASH_CR_LOCK) != 0) { FLASH->KEYR = 0x45670123; FLASH->KEYR = 0xCDEF89AB; } } else { FLASH->CR |= FLASH_CR_LOCK; __enable_irq(); } } // Programming Flash Memory IAPCode program_flash(uint32_t address, uint16_t *data, unsigned int length) { unlock_flash(true); FLASH->CR |= FLASH_CR_PG; uint16_t* write_addr = (uint16_t*)address; for (int i = 0; i<length/2; i++) { write_addr[i] = data[i]; while (FLASH->SR & FLASH_SR_BSY); } if ((FLASH->SR & FLASH_SR_EOP) != 0) FLASH->SR = FLASH_SR_EOP; IAPCode retval = check_error(); FLASH->CR &= ~FLASH_CR_PG; unlock_flash(false); return retval; }