Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Pinscape_Controller by
FreescaleIAP/FreescaleIAP.cpp@15:eb8aac252eba, 2015-02-24 (annotated)
- Committer:
- lemming
- Date:
- Tue Feb 24 05:25:41 2015 +0000
- Revision:
- 15:eb8aac252eba
- Parent:
- 2:c174f9ee414a
Adjusted pinscape to work with a cheap linear potentiometer instead of a CCD array
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mjr | 2:c174f9ee414a | 1 | #include "FreescaleIAP.h" |
mjr | 2:c174f9ee414a | 2 | |
mjr | 2:c174f9ee414a | 3 | //#define IAPDEBUG |
mjr | 2:c174f9ee414a | 4 | |
mjr | 2:c174f9ee414a | 5 | enum FCMD { |
mjr | 2:c174f9ee414a | 6 | Read1s = 0x01, |
mjr | 2:c174f9ee414a | 7 | ProgramCheck = 0x02, |
mjr | 2:c174f9ee414a | 8 | ReadResource = 0x03, |
mjr | 2:c174f9ee414a | 9 | ProgramLongword = 0x06, |
mjr | 2:c174f9ee414a | 10 | EraseSector = 0x09, |
mjr | 2:c174f9ee414a | 11 | Read1sBlock = 0x40, |
mjr | 2:c174f9ee414a | 12 | ReadOnce = 0x41, |
mjr | 2:c174f9ee414a | 13 | ProgramOnce = 0x43, |
mjr | 2:c174f9ee414a | 14 | EraseAll = 0x44, |
mjr | 2:c174f9ee414a | 15 | VerifyBackdoor = 0x45 |
mjr | 2:c174f9ee414a | 16 | }; |
mjr | 2:c174f9ee414a | 17 | |
mjr | 2:c174f9ee414a | 18 | static inline void run_command(FTFA_Type *); |
mjr | 2:c174f9ee414a | 19 | bool check_boundary(int address, unsigned int length); |
mjr | 2:c174f9ee414a | 20 | bool check_align(int address); |
mjr | 2:c174f9ee414a | 21 | IAPCode check_error(void); |
mjr | 2:c174f9ee414a | 22 | |
mjr | 2:c174f9ee414a | 23 | FreescaleIAP::FreescaleIAP() |
mjr | 2:c174f9ee414a | 24 | { |
mjr | 2:c174f9ee414a | 25 | } |
mjr | 2:c174f9ee414a | 26 | |
mjr | 2:c174f9ee414a | 27 | FreescaleIAP::~FreescaleIAP() |
mjr | 2:c174f9ee414a | 28 | { |
mjr | 2:c174f9ee414a | 29 | } |
mjr | 2:c174f9ee414a | 30 | |
mjr | 2:c174f9ee414a | 31 | // execute an FTFA command |
mjr | 2:c174f9ee414a | 32 | static inline void run_command(FTFA_Type *ftfa) |
mjr | 2:c174f9ee414a | 33 | { |
mjr | 2:c174f9ee414a | 34 | // disable interupts |
mjr | 2:c174f9ee414a | 35 | __disable_irq(); |
mjr | 2:c174f9ee414a | 36 | |
mjr | 2:c174f9ee414a | 37 | // Clear possible old errors, start command, wait until done |
mjr | 2:c174f9ee414a | 38 | ftfa->FSTAT = FTFA_FSTAT_FPVIOL_MASK | FTFA_FSTAT_ACCERR_MASK | FTFA_FSTAT_RDCOLERR_MASK; |
mjr | 2:c174f9ee414a | 39 | ftfa->FSTAT = FTFA_FSTAT_CCIF_MASK; |
mjr | 2:c174f9ee414a | 40 | while (!(ftfa->FSTAT & FTFA_FSTAT_CCIF_MASK)); |
mjr | 2:c174f9ee414a | 41 | |
mjr | 2:c174f9ee414a | 42 | // re-enable interrupts |
mjr | 2:c174f9ee414a | 43 | __enable_irq(); |
mjr | 2:c174f9ee414a | 44 | } |
mjr | 2:c174f9ee414a | 45 | |
mjr | 2:c174f9ee414a | 46 | |
mjr | 2:c174f9ee414a | 47 | IAPCode FreescaleIAP::erase_sector(int address) { |
mjr | 2:c174f9ee414a | 48 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 49 | printf("IAP: Erasing at %x\r\n", address); |
mjr | 2:c174f9ee414a | 50 | #endif |
mjr | 2:c174f9ee414a | 51 | if (check_align(address)) |
mjr | 2:c174f9ee414a | 52 | return AlignError; |
mjr | 2:c174f9ee414a | 53 | |
mjr | 2:c174f9ee414a | 54 | //Setup command |
mjr | 2:c174f9ee414a | 55 | FTFA->FCCOB0 = EraseSector; |
mjr | 2:c174f9ee414a | 56 | FTFA->FCCOB1 = (address >> 16) & 0xFF; |
mjr | 2:c174f9ee414a | 57 | FTFA->FCCOB2 = (address >> 8) & 0xFF; |
mjr | 2:c174f9ee414a | 58 | FTFA->FCCOB3 = address & 0xFF; |
mjr | 2:c174f9ee414a | 59 | |
mjr | 2:c174f9ee414a | 60 | run_command(FTFA); |
mjr | 2:c174f9ee414a | 61 | |
mjr | 2:c174f9ee414a | 62 | return check_error(); |
mjr | 2:c174f9ee414a | 63 | } |
mjr | 2:c174f9ee414a | 64 | |
mjr | 2:c174f9ee414a | 65 | IAPCode FreescaleIAP::program_flash(int address, const void *vp, unsigned int length) { |
mjr | 2:c174f9ee414a | 66 | |
mjr | 2:c174f9ee414a | 67 | const char *data = (const char *)vp; |
mjr | 2:c174f9ee414a | 68 | |
mjr | 2:c174f9ee414a | 69 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 70 | printf("IAP: Programming flash at %x with length %d\r\n", address, length); |
mjr | 2:c174f9ee414a | 71 | #endif |
mjr | 2:c174f9ee414a | 72 | if (check_align(address)) |
mjr | 2:c174f9ee414a | 73 | return AlignError; |
mjr | 2:c174f9ee414a | 74 | |
mjr | 2:c174f9ee414a | 75 | IAPCode eraseCheck = verify_erased(address, length); |
mjr | 2:c174f9ee414a | 76 | if (eraseCheck != Success) |
mjr | 2:c174f9ee414a | 77 | return eraseCheck; |
mjr | 2:c174f9ee414a | 78 | |
mjr | 2:c174f9ee414a | 79 | IAPCode progResult; |
mjr | 2:c174f9ee414a | 80 | for (int i = 0; i < length; i+=4) { |
mjr | 2:c174f9ee414a | 81 | progResult = program_word(address + i, data + i); |
mjr | 2:c174f9ee414a | 82 | if (progResult != Success) |
mjr | 2:c174f9ee414a | 83 | return progResult; |
mjr | 2:c174f9ee414a | 84 | } |
mjr | 2:c174f9ee414a | 85 | |
mjr | 2:c174f9ee414a | 86 | return Success; |
mjr | 2:c174f9ee414a | 87 | } |
mjr | 2:c174f9ee414a | 88 | |
mjr | 2:c174f9ee414a | 89 | uint32_t FreescaleIAP::flash_size(void) { |
mjr | 2:c174f9ee414a | 90 | uint32_t retval = (SIM->FCFG2 & 0x7F000000u) >> (24-13); |
mjr | 2:c174f9ee414a | 91 | if (SIM->FCFG2 & (1<<23)) //Possible second flash bank |
mjr | 2:c174f9ee414a | 92 | retval += (SIM->FCFG2 & 0x007F0000u) >> (16-13); |
mjr | 2:c174f9ee414a | 93 | return retval; |
mjr | 2:c174f9ee414a | 94 | } |
mjr | 2:c174f9ee414a | 95 | |
mjr | 2:c174f9ee414a | 96 | IAPCode FreescaleIAP::program_word(int address, const char *data) { |
mjr | 2:c174f9ee414a | 97 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 98 | printf("IAP: Programming word at %x, %d - %d - %d - %d\r\n", address, data[0], data[1], data[2], data[3]); |
mjr | 2:c174f9ee414a | 99 | #endif |
mjr | 2:c174f9ee414a | 100 | if (check_align(address)) |
mjr | 2:c174f9ee414a | 101 | return AlignError; |
mjr | 2:c174f9ee414a | 102 | |
mjr | 2:c174f9ee414a | 103 | //Setup command |
mjr | 2:c174f9ee414a | 104 | FTFA->FCCOB0 = ProgramLongword; |
mjr | 2:c174f9ee414a | 105 | FTFA->FCCOB1 = (address >> 16) & 0xFF; |
mjr | 2:c174f9ee414a | 106 | FTFA->FCCOB2 = (address >> 8) & 0xFF; |
mjr | 2:c174f9ee414a | 107 | FTFA->FCCOB3 = address & 0xFF; |
mjr | 2:c174f9ee414a | 108 | FTFA->FCCOB4 = data[3]; |
mjr | 2:c174f9ee414a | 109 | FTFA->FCCOB5 = data[2]; |
mjr | 2:c174f9ee414a | 110 | FTFA->FCCOB6 = data[1]; |
mjr | 2:c174f9ee414a | 111 | FTFA->FCCOB7 = data[0]; |
mjr | 2:c174f9ee414a | 112 | |
mjr | 2:c174f9ee414a | 113 | run_command(FTFA); |
mjr | 2:c174f9ee414a | 114 | |
mjr | 2:c174f9ee414a | 115 | return check_error(); |
mjr | 2:c174f9ee414a | 116 | } |
mjr | 2:c174f9ee414a | 117 | |
mjr | 2:c174f9ee414a | 118 | /* Check if no flash boundary is violated |
mjr | 2:c174f9ee414a | 119 | Returns true on violation */ |
mjr | 2:c174f9ee414a | 120 | bool check_boundary(int address, unsigned int length) { |
mjr | 2:c174f9ee414a | 121 | int temp = (address+length - 1) / SECTOR_SIZE; |
mjr | 2:c174f9ee414a | 122 | address /= SECTOR_SIZE; |
mjr | 2:c174f9ee414a | 123 | bool retval = (address != temp); |
mjr | 2:c174f9ee414a | 124 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 125 | if (retval) |
mjr | 2:c174f9ee414a | 126 | printf("IAP: Boundary violation\r\n"); |
mjr | 2:c174f9ee414a | 127 | #endif |
mjr | 2:c174f9ee414a | 128 | return retval; |
mjr | 2:c174f9ee414a | 129 | } |
mjr | 2:c174f9ee414a | 130 | |
mjr | 2:c174f9ee414a | 131 | /* Check if address is correctly aligned |
mjr | 2:c174f9ee414a | 132 | Returns true on violation */ |
mjr | 2:c174f9ee414a | 133 | bool check_align(int address) { |
mjr | 2:c174f9ee414a | 134 | bool retval = address & 0x03; |
mjr | 2:c174f9ee414a | 135 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 136 | if (retval) |
mjr | 2:c174f9ee414a | 137 | printf("IAP: Alignment violation\r\n"); |
mjr | 2:c174f9ee414a | 138 | #endif |
mjr | 2:c174f9ee414a | 139 | return retval; |
mjr | 2:c174f9ee414a | 140 | } |
mjr | 2:c174f9ee414a | 141 | |
mjr | 2:c174f9ee414a | 142 | /* Check if an area of flash memory is erased |
mjr | 2:c174f9ee414a | 143 | Returns error code or Success (in case of fully erased) */ |
mjr | 2:c174f9ee414a | 144 | IAPCode FreescaleIAP::verify_erased(int address, unsigned int length) { |
mjr | 2:c174f9ee414a | 145 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 146 | printf("IAP: Verify erased at %x with length %d\r\n", address, length); |
mjr | 2:c174f9ee414a | 147 | #endif |
mjr | 2:c174f9ee414a | 148 | |
mjr | 2:c174f9ee414a | 149 | if (check_align(address)) |
mjr | 2:c174f9ee414a | 150 | return AlignError; |
mjr | 2:c174f9ee414a | 151 | |
mjr | 2:c174f9ee414a | 152 | //Setup command |
mjr | 2:c174f9ee414a | 153 | FTFA->FCCOB0 = Read1s; |
mjr | 2:c174f9ee414a | 154 | FTFA->FCCOB1 = (address >> 16) & 0xFF; |
mjr | 2:c174f9ee414a | 155 | FTFA->FCCOB2 = (address >> 8) & 0xFF; |
mjr | 2:c174f9ee414a | 156 | FTFA->FCCOB3 = address & 0xFF; |
mjr | 2:c174f9ee414a | 157 | FTFA->FCCOB4 = (length >> 10) & 0xFF; |
mjr | 2:c174f9ee414a | 158 | FTFA->FCCOB5 = (length >> 2) & 0xFF; |
mjr | 2:c174f9ee414a | 159 | FTFA->FCCOB6 = 0; |
mjr | 2:c174f9ee414a | 160 | |
mjr | 2:c174f9ee414a | 161 | run_command(FTFA); |
mjr | 2:c174f9ee414a | 162 | |
mjr | 2:c174f9ee414a | 163 | IAPCode retval = check_error(); |
mjr | 2:c174f9ee414a | 164 | if (retval == RuntimeError) { |
mjr | 2:c174f9ee414a | 165 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 166 | printf("IAP: Flash was not erased\r\n"); |
mjr | 2:c174f9ee414a | 167 | #endif |
mjr | 2:c174f9ee414a | 168 | return EraseError; |
mjr | 2:c174f9ee414a | 169 | } |
mjr | 2:c174f9ee414a | 170 | return retval; |
mjr | 2:c174f9ee414a | 171 | |
mjr | 2:c174f9ee414a | 172 | } |
mjr | 2:c174f9ee414a | 173 | |
mjr | 2:c174f9ee414a | 174 | /* Check if an error occured |
mjr | 2:c174f9ee414a | 175 | Returns error code or Success*/ |
mjr | 2:c174f9ee414a | 176 | IAPCode check_error(void) { |
mjr | 2:c174f9ee414a | 177 | if (FTFA->FSTAT & FTFA_FSTAT_FPVIOL_MASK) { |
mjr | 2:c174f9ee414a | 178 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 179 | printf("IAP: Protection violation\r\n"); |
mjr | 2:c174f9ee414a | 180 | #endif |
mjr | 2:c174f9ee414a | 181 | return ProtectionError; |
mjr | 2:c174f9ee414a | 182 | } |
mjr | 2:c174f9ee414a | 183 | if (FTFA->FSTAT & FTFA_FSTAT_ACCERR_MASK) { |
mjr | 2:c174f9ee414a | 184 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 185 | printf("IAP: Flash access error\r\n"); |
mjr | 2:c174f9ee414a | 186 | #endif |
mjr | 2:c174f9ee414a | 187 | return AccessError; |
mjr | 2:c174f9ee414a | 188 | } |
mjr | 2:c174f9ee414a | 189 | if (FTFA->FSTAT & FTFA_FSTAT_RDCOLERR_MASK) { |
mjr | 2:c174f9ee414a | 190 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 191 | printf("IAP: Collision error\r\n"); |
mjr | 2:c174f9ee414a | 192 | #endif |
mjr | 2:c174f9ee414a | 193 | return CollisionError; |
mjr | 2:c174f9ee414a | 194 | } |
mjr | 2:c174f9ee414a | 195 | if (FTFA->FSTAT & FTFA_FSTAT_MGSTAT0_MASK) { |
mjr | 2:c174f9ee414a | 196 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 197 | printf("IAP: Runtime error\r\n"); |
mjr | 2:c174f9ee414a | 198 | #endif |
mjr | 2:c174f9ee414a | 199 | return RuntimeError; |
mjr | 2:c174f9ee414a | 200 | } |
mjr | 2:c174f9ee414a | 201 | #ifdef IAPDEBUG |
mjr | 2:c174f9ee414a | 202 | printf("IAP: No error reported\r\n"); |
mjr | 2:c174f9ee414a | 203 | #endif |
mjr | 2:c174f9ee414a | 204 | return Success; |
mjr | 2:c174f9ee414a | 205 | } |