Pinscape Controller version 1 fork. This is a fork to allow for ongoing bug fixes to the original controller version, from before the major changes for the expansion board project.

Dependencies:   FastIO FastPWM SimpleDMA mbed

Fork of Pinscape_Controller by Mike R

Committer:
mjr
Date:
Mon Feb 15 23:03:55 2016 +0000
Revision:
68:edfecf67a931
Parent:
2:c174f9ee414a
Finalize USB library updates to fix compatibility problems introduced in USBHAL_KL25Z overhaul.

Who changed what in which revision?

UserRevisionLine numberNew 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 }