Sample IAP test code for Nucleo_F091RC

Committer:
narasimma23
Date:
Sat Jun 17 07:00:41 2017 +0000
Revision:
0:de2687a62a94
Sample IAP test code for Nucleo_F091RC

Who changed what in which revision?

UserRevisionLine numberNew contents of line
narasimma23 0:de2687a62a94 1 /**
narasimma23 0:de2687a62a94 2 * Author: Narasimma DLN
narasimma23 0:de2687a62a94 3 * Email: narasimma23@gmail.com
narasimma23 0:de2687a62a94 4 */
narasimma23 0:de2687a62a94 5
narasimma23 0:de2687a62a94 6 #include "stm_iap.h"
narasimma23 0:de2687a62a94 7
narasimma23 0:de2687a62a94 8 static uint32_t flash_sectors[FLASH_SECTORS];
narasimma23 0:de2687a62a94 9 static uint16_t *flash_size_addr = (uint16_t *)FLASH_SIZE_ADDR;
narasimma23 0:de2687a62a94 10
narasimma23 0:de2687a62a94 11 static IAPCode check_error(void);
narasimma23 0:de2687a62a94 12 static void unlock_flash(bool unlock);
narasimma23 0:de2687a62a94 13
narasimma23 0:de2687a62a94 14 // Get Flash Sectors
narasimma23 0:de2687a62a94 15 void get_flash_sectors(void)
narasimma23 0:de2687a62a94 16 {
narasimma23 0:de2687a62a94 17 uint8_t i;
narasimma23 0:de2687a62a94 18 uint32_t _addr = FLASH_START_ADDR;
narasimma23 0:de2687a62a94 19
narasimma23 0:de2687a62a94 20 for (i=0; i<FLASH_SECTORS; i++) {
narasimma23 0:de2687a62a94 21 flash_sectors[i] = _addr;
narasimma23 0:de2687a62a94 22 _addr += FLASH_SECTOR_SIZE;
narasimma23 0:de2687a62a94 23 }
narasimma23 0:de2687a62a94 24 }
narasimma23 0:de2687a62a94 25
narasimma23 0:de2687a62a94 26 // Get Flash Size
narasimma23 0:de2687a62a94 27 uint32_t get_flash_size(void) {
narasimma23 0:de2687a62a94 28 return *flash_size_addr * 1024;
narasimma23 0:de2687a62a94 29 }
narasimma23 0:de2687a62a94 30
narasimma23 0:de2687a62a94 31
narasimma23 0:de2687a62a94 32 // Get Sector Number
narasimma23 0:de2687a62a94 33 uint8_t get_sector_number(uint32_t _addr) {
narasimma23 0:de2687a62a94 34 uint8_t retval = 0;
narasimma23 0:de2687a62a94 35 while(1) {
narasimma23 0:de2687a62a94 36 //If start address of next sector is higher than wanted address, return current value
narasimma23 0:de2687a62a94 37 if (_addr < flash_sectors[retval + 1])
narasimma23 0:de2687a62a94 38 return retval;
narasimma23 0:de2687a62a94 39
narasimma23 0:de2687a62a94 40 retval++;
narasimma23 0:de2687a62a94 41 }
narasimma23 0:de2687a62a94 42 }
narasimma23 0:de2687a62a94 43
narasimma23 0:de2687a62a94 44 // Get Sector Size
narasimma23 0:de2687a62a94 45 uint32_t get_sector_size(uint32_t _addr)
narasimma23 0:de2687a62a94 46 {
narasimma23 0:de2687a62a94 47 uint8_t sector = get_sector_number(_addr);
narasimma23 0:de2687a62a94 48 return flash_sectors[sector+1] - flash_sectors[sector];
narasimma23 0:de2687a62a94 49 }
narasimma23 0:de2687a62a94 50
narasimma23 0:de2687a62a94 51 static IAPCode check_error(void)
narasimma23 0:de2687a62a94 52 {
narasimma23 0:de2687a62a94 53 //Wait until done
narasimma23 0:de2687a62a94 54 while (FLASH->SR & FLASH_SR_BSY);
narasimma23 0:de2687a62a94 55
narasimma23 0:de2687a62a94 56 //Check for errors
narasimma23 0:de2687a62a94 57 if (FLASH->SR & FLASH_SR_WRPERR)
narasimma23 0:de2687a62a94 58 return WriteProtError;
narasimma23 0:de2687a62a94 59 if (FLASH->SR & FLASH_SR_PGERR)
narasimma23 0:de2687a62a94 60 return ProgrammingError;
narasimma23 0:de2687a62a94 61
narasimma23 0:de2687a62a94 62 return Success;
narasimma23 0:de2687a62a94 63 }
narasimma23 0:de2687a62a94 64
narasimma23 0:de2687a62a94 65 // Erase a Flash Sector
narasimma23 0:de2687a62a94 66 IAPCode erase_sector(int address)
narasimma23 0:de2687a62a94 67 {
narasimma23 0:de2687a62a94 68 uint8_t sec_num = get_sector_number(address);
narasimma23 0:de2687a62a94 69
narasimma23 0:de2687a62a94 70 unlock_flash(true);
narasimma23 0:de2687a62a94 71
narasimma23 0:de2687a62a94 72 //Clear current errors
narasimma23 0:de2687a62a94 73 FLASH->SR = FLASH_SR_WRPERR | FLASH_SR_PGERR;
narasimma23 0:de2687a62a94 74
narasimma23 0:de2687a62a94 75 //Run command
narasimma23 0:de2687a62a94 76 // Page 1
narasimma23 0:de2687a62a94 77 FLASH->CR |= FLASH_CR_PER;
narasimma23 0:de2687a62a94 78 FLASH->AR = flash_sectors[sec_num];
narasimma23 0:de2687a62a94 79 FLASH->CR |= FLASH_CR_STRT;
narasimma23 0:de2687a62a94 80 while (FLASH->SR & FLASH_SR_BSY);
narasimma23 0:de2687a62a94 81
narasimma23 0:de2687a62a94 82 // Page 2
narasimma23 0:de2687a62a94 83 FLASH->CR |= FLASH_CR_PER;
narasimma23 0:de2687a62a94 84 FLASH->AR = flash_sectors[sec_num] + FLASH_PAGE_SIZE;
narasimma23 0:de2687a62a94 85 FLASH->CR |= FLASH_CR_STRT;
narasimma23 0:de2687a62a94 86 while (FLASH->SR & FLASH_SR_BSY);
narasimma23 0:de2687a62a94 87
narasimma23 0:de2687a62a94 88 if ((FLASH->SR & FLASH_SR_EOP) != 0)
narasimma23 0:de2687a62a94 89 FLASH->SR = FLASH_SR_EOP;
narasimma23 0:de2687a62a94 90
narasimma23 0:de2687a62a94 91 FLASH->CR &= ~FLASH_CR_PER;
narasimma23 0:de2687a62a94 92
narasimma23 0:de2687a62a94 93 unlock_flash(false);
narasimma23 0:de2687a62a94 94 IAPCode retval = check_error();
narasimma23 0:de2687a62a94 95
narasimma23 0:de2687a62a94 96 return retval;
narasimma23 0:de2687a62a94 97 }
narasimma23 0:de2687a62a94 98
narasimma23 0:de2687a62a94 99 // Unlocking Flash
narasimma23 0:de2687a62a94 100 static void unlock_flash(bool unlock)
narasimma23 0:de2687a62a94 101 {
narasimma23 0:de2687a62a94 102 if (unlock) {
narasimma23 0:de2687a62a94 103 __disable_irq();
narasimma23 0:de2687a62a94 104 //Wait until not busy
narasimma23 0:de2687a62a94 105 while (FLASH->SR & FLASH_SR_BSY);
narasimma23 0:de2687a62a94 106 if ((FLASH->CR & FLASH_CR_LOCK) != 0) {
narasimma23 0:de2687a62a94 107 FLASH->KEYR = 0x45670123;
narasimma23 0:de2687a62a94 108 FLASH->KEYR = 0xCDEF89AB;
narasimma23 0:de2687a62a94 109 }
narasimma23 0:de2687a62a94 110 } else {
narasimma23 0:de2687a62a94 111 FLASH->CR |= FLASH_CR_LOCK;
narasimma23 0:de2687a62a94 112 __enable_irq();
narasimma23 0:de2687a62a94 113 }
narasimma23 0:de2687a62a94 114 }
narasimma23 0:de2687a62a94 115
narasimma23 0:de2687a62a94 116 // Programming Flash Memory
narasimma23 0:de2687a62a94 117 IAPCode program_flash(uint32_t address, uint16_t *data, unsigned int length)
narasimma23 0:de2687a62a94 118 {
narasimma23 0:de2687a62a94 119 unlock_flash(true);
narasimma23 0:de2687a62a94 120
narasimma23 0:de2687a62a94 121 FLASH->CR |= FLASH_CR_PG;
narasimma23 0:de2687a62a94 122
narasimma23 0:de2687a62a94 123 uint16_t* write_addr = (uint16_t*)address;
narasimma23 0:de2687a62a94 124 for (int i = 0; i<length/2; i++) {
narasimma23 0:de2687a62a94 125 write_addr[i] = data[i];
narasimma23 0:de2687a62a94 126 while (FLASH->SR & FLASH_SR_BSY);
narasimma23 0:de2687a62a94 127 }
narasimma23 0:de2687a62a94 128
narasimma23 0:de2687a62a94 129 if ((FLASH->SR & FLASH_SR_EOP) != 0)
narasimma23 0:de2687a62a94 130 FLASH->SR = FLASH_SR_EOP;
narasimma23 0:de2687a62a94 131
narasimma23 0:de2687a62a94 132 IAPCode retval = check_error();
narasimma23 0:de2687a62a94 133 FLASH->CR &= ~FLASH_CR_PG;
narasimma23 0:de2687a62a94 134
narasimma23 0:de2687a62a94 135 unlock_flash(false);
narasimma23 0:de2687a62a94 136
narasimma23 0:de2687a62a94 137 return retval;
narasimma23 0:de2687a62a94 138 }