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