Narasimma DLN
/
NUCLEO_F091RC_IAP_UART
Sample IAP test code for Nucleo_F091RC
stm_iap.cpp@0:de2687a62a94, 2017-06-17 (annotated)
- 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?
User | Revision | Line number | New 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 | } |