An input/output controller for virtual pinball machines, with plunger position tracking, accelerometer-based nudge sensing, button input encoding, and feedback device control.
Dependencies: USBDevice mbed FastAnalogIn FastIO FastPWM SimpleDMA
FreescaleIAP.cpp
00001 #include "FreescaleIAP.h" 00002 00003 //#define IAPDEBUG 00004 00005 enum FCMD { 00006 Read1s = 0x01, 00007 ProgramCheck = 0x02, 00008 ReadResource = 0x03, 00009 ProgramLongword = 0x06, 00010 EraseSector = 0x09, 00011 Read1sBlock = 0x40, 00012 ReadOnce = 0x41, 00013 ProgramOnce = 0x43, 00014 EraseAll = 0x44, 00015 VerifyBackdoor = 0x45 00016 }; 00017 00018 static inline void run_command(FTFA_Type *); 00019 bool check_boundary(int address, unsigned int length); 00020 bool check_align(int address); 00021 IAPCode check_error(void); 00022 00023 FreescaleIAP::FreescaleIAP() 00024 { 00025 } 00026 00027 FreescaleIAP::~FreescaleIAP() 00028 { 00029 } 00030 00031 // execute an FTFA command 00032 static inline void run_command(FTFA_Type *ftfa) 00033 { 00034 // disable interupts 00035 __disable_irq(); 00036 00037 // Clear possible old errors, start command, wait until done 00038 ftfa->FSTAT = FTFA_FSTAT_FPVIOL_MASK | FTFA_FSTAT_ACCERR_MASK | FTFA_FSTAT_RDCOLERR_MASK; 00039 ftfa->FSTAT = FTFA_FSTAT_CCIF_MASK; 00040 while (!(ftfa->FSTAT & FTFA_FSTAT_CCIF_MASK)); 00041 00042 // re-enable interrupts 00043 __enable_irq(); 00044 } 00045 00046 00047 IAPCode FreescaleIAP::erase_sector(int address) { 00048 #ifdef IAPDEBUG 00049 printf("IAP: Erasing at %x\r\n", address); 00050 #endif 00051 if (check_align(address)) 00052 return AlignError; 00053 00054 //Setup command 00055 FTFA->FCCOB0 = EraseSector; 00056 FTFA->FCCOB1 = (address >> 16) & 0xFF; 00057 FTFA->FCCOB2 = (address >> 8) & 0xFF; 00058 FTFA->FCCOB3 = address & 0xFF; 00059 00060 run_command(FTFA); 00061 00062 return check_error(); 00063 } 00064 00065 IAPCode FreescaleIAP::program_flash(int address, const void *vp, unsigned int length) { 00066 00067 const char *data = (const char *)vp; 00068 00069 #ifdef IAPDEBUG 00070 printf("IAP: Programming flash at %x with length %d\r\n", address, length); 00071 #endif 00072 if (check_align(address)) 00073 return AlignError; 00074 00075 IAPCode eraseCheck = verify_erased(address, length); 00076 if (eraseCheck != Success) 00077 return eraseCheck; 00078 00079 IAPCode progResult; 00080 for (int i = 0; i < length; i+=4) { 00081 progResult = program_word(address + i, data + i); 00082 if (progResult != Success) 00083 return progResult; 00084 } 00085 00086 return Success; 00087 } 00088 00089 uint32_t FreescaleIAP::flash_size(void) { 00090 uint32_t retval = (SIM->FCFG2 & 0x7F000000u) >> (24-13); 00091 if (SIM->FCFG2 & (1<<23)) //Possible second flash bank 00092 retval += (SIM->FCFG2 & 0x007F0000u) >> (16-13); 00093 return retval; 00094 } 00095 00096 IAPCode FreescaleIAP::program_word(int address, const char *data) { 00097 #ifdef IAPDEBUG 00098 printf("IAP: Programming word at %x, %d - %d - %d - %d\r\n", address, data[0], data[1], data[2], data[3]); 00099 #endif 00100 if (check_align(address)) 00101 return AlignError; 00102 00103 //Setup command 00104 FTFA->FCCOB0 = ProgramLongword; 00105 FTFA->FCCOB1 = (address >> 16) & 0xFF; 00106 FTFA->FCCOB2 = (address >> 8) & 0xFF; 00107 FTFA->FCCOB3 = address & 0xFF; 00108 FTFA->FCCOB4 = data[3]; 00109 FTFA->FCCOB5 = data[2]; 00110 FTFA->FCCOB6 = data[1]; 00111 FTFA->FCCOB7 = data[0]; 00112 00113 run_command(FTFA); 00114 00115 return check_error(); 00116 } 00117 00118 /* Check if no flash boundary is violated 00119 Returns true on violation */ 00120 bool check_boundary(int address, unsigned int length) { 00121 int temp = (address+length - 1) / SECTOR_SIZE; 00122 address /= SECTOR_SIZE; 00123 bool retval = (address != temp); 00124 #ifdef IAPDEBUG 00125 if (retval) 00126 printf("IAP: Boundary violation\r\n"); 00127 #endif 00128 return retval; 00129 } 00130 00131 /* Check if address is correctly aligned 00132 Returns true on violation */ 00133 bool check_align(int address) { 00134 bool retval = address & 0x03; 00135 #ifdef IAPDEBUG 00136 if (retval) 00137 printf("IAP: Alignment violation\r\n"); 00138 #endif 00139 return retval; 00140 } 00141 00142 /* Check if an area of flash memory is erased 00143 Returns error code or Success (in case of fully erased) */ 00144 IAPCode FreescaleIAP::verify_erased(int address, unsigned int length) { 00145 #ifdef IAPDEBUG 00146 printf("IAP: Verify erased at %x with length %d\r\n", address, length); 00147 #endif 00148 00149 if (check_align(address)) 00150 return AlignError; 00151 00152 //Setup command 00153 FTFA->FCCOB0 = Read1s; 00154 FTFA->FCCOB1 = (address >> 16) & 0xFF; 00155 FTFA->FCCOB2 = (address >> 8) & 0xFF; 00156 FTFA->FCCOB3 = address & 0xFF; 00157 FTFA->FCCOB4 = (length >> 10) & 0xFF; 00158 FTFA->FCCOB5 = (length >> 2) & 0xFF; 00159 FTFA->FCCOB6 = 0; 00160 00161 run_command(FTFA); 00162 00163 IAPCode retval = check_error(); 00164 if (retval == RuntimeError) { 00165 #ifdef IAPDEBUG 00166 printf("IAP: Flash was not erased\r\n"); 00167 #endif 00168 return EraseError; 00169 } 00170 return retval; 00171 00172 } 00173 00174 /* Check if an error occured 00175 Returns error code or Success*/ 00176 IAPCode check_error(void) { 00177 if (FTFA->FSTAT & FTFA_FSTAT_FPVIOL_MASK) { 00178 #ifdef IAPDEBUG 00179 printf("IAP: Protection violation\r\n"); 00180 #endif 00181 return ProtectionError; 00182 } 00183 if (FTFA->FSTAT & FTFA_FSTAT_ACCERR_MASK) { 00184 #ifdef IAPDEBUG 00185 printf("IAP: Flash access error\r\n"); 00186 #endif 00187 return AccessError; 00188 } 00189 if (FTFA->FSTAT & FTFA_FSTAT_RDCOLERR_MASK) { 00190 #ifdef IAPDEBUG 00191 printf("IAP: Collision error\r\n"); 00192 #endif 00193 return CollisionError; 00194 } 00195 if (FTFA->FSTAT & FTFA_FSTAT_MGSTAT0_MASK) { 00196 #ifdef IAPDEBUG 00197 printf("IAP: Runtime error\r\n"); 00198 #endif 00199 return RuntimeError; 00200 } 00201 #ifdef IAPDEBUG 00202 printf("IAP: No error reported\r\n"); 00203 #endif 00204 return Success; 00205 }
Generated on Fri Jul 15 2022 08:43:32 by 1.7.2