/* READ_ONCE on the PROGRAM_ONCE area of the Teensy 3.0's mk20dx128 FLASH IFR
Following http://forum.pjrc.com/threads/91-teensy-3-MAC-address
K20 Sub-Family Reference Manual, Rev. 2, Feb 2012 section 28.4.11.10
Kinetis Quick Reference User Guide, Rev. 2, 08/2012 page 85
Also, look at the SIM_UIDH SIM_UIDMH SIM_UIDML SIM_UIDL registers
*/
#include <Arduino.h>
#define LENGTH_ONCE_AREA 64
uint8_t buff[LENGTH_ONCE_AREA];
uint8_t base;
void read_once(uint8_t word, uint8_t buf[], uint8_t offset) {
while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)){Serial.println('.');}
// return;
FTFL_FCCOB0 = 0x41; // Selects the READONCE command
// Serial.print("FTFL_FCCOB0:");Serial.println(FTFL_FCCOB0,HEX);
// return;
FTFL_FCCOB1 = word; // read the given word of read once area
// Serial.println(FTFL_FCCOB1,HEX);
// Serial.print("FTFL_FCCOB1:");Serial.println(FTFL_FCCOB1,HEX);
// Serial.print("FTFL_FCCOB2:");Serial.println(FTFL_FCCOB2,HEX);
// Serial.print("FTFL_FCCOB3:");Serial.println(FTFL_FCCOB3,HEX);
// Serial.print("STAT:");Serial.println(FTFL_FSTAT,HEX);
// return;
while(!( FTFL_FCNFG & FTFL_FCNFG)) ; // wait for flash
// Serial.print("FTLFL_FCNFG:");Serial.println(FTFL_FCNFG,HEX);
//return;
// launch command and wait until complete
FTFL_FSTAT = FTFL_FSTAT_CCIF;
// Serial.print("STAT:");Serial.println(FTFL_FSTAT,HEX);
return;
while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)){
// Serial.print("STATwait:");Serial.println(FTFL_FSTAT,HEX);
}
//return;
if (FTFL_FSTAT & FTFL_FSTAT_ACCERR){
// Serial.print("ReadOnce FTFL_FSTAT_ACCERR at record ");
// Serial.print(word);
// Serial.println("Recorded data may not be reliable");
}
if (FTFL_FSTAT & FTFL_FSTAT_FPVIOL){
// Serial.print("ReadOnce FTFL_FSTAT_FPVIO at record ");
// Serial.print(word);
// Serial.println("Recorded data may not be reliable");
}
// Serial.print("STAT:");Serial.println(FTFL_FSTAT,HEX);
// Serial.print("offset:");Serial.println(offset);
buf[offset+0] = FTFL_FCCOB4;
*(buf+offset+1) = FTFL_FCCOB5;
*(buf+offset+2) = FTFL_FCCOB6;
*(buf+offset+3) = FTFL_FCCOB7;
}
// http://forum.pjrc.com/threads/91-teensy-3-MAC-address
void read(uint8_t word, uint8_t* mac, uint8_t offset) {
FTFL_FCCOB0 = 0x41; // Selects the READONCE command
FTFL_FCCOB1 = word; // read the given word of read once area
// launch command and wait until complete
FTFL_FSTAT = FTFL_FSTAT_CCIF;
// FTFL_FSTAT = FTFL_FSTAT_CCIF | 0xf0;
// FTFL_FSTAT = 0xf0;
while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) FTFL_FSTAT = 0x70;
*(mac+offset) = FTFL_FCCOB5; // collect only the top three bytes,
*(mac+offset+1) = FTFL_FCCOB6; // in the right orientation (big endian).
*(mac+offset+2) = FTFL_FCCOB7; // Skip FTFL_FCCOB4 as it's always 0.
}
void setup(void){
Serial.begin(9600);
while(!Serial);
Serial.println("Waiting 2s...");
delay(1000);
Serial.println("Reading...");
for (base = 0x0f << 2 ; base < LENGTH_ONCE_AREA ; base -=4){
Serial.print(base>>2);
Serial.print("w ");
Serial.flush();
// read_once((uint8_t)(base >> 2), buffer,base);
}
read(0xe,buff,0);
read(0xf,buff+3,0);
}
void loop(void){
for (base = 0 ; base < LENGTH_ONCE_AREA ; base++){
if (! base & 0x3) {
Serial.print("\nONCE_PROGRAM record ");
Serial.print(base >> 2, HEX);
Serial.print(" : ");
}
Serial.print(buff[base],HEX);
Serial.print(" ");
}
Serial.print("\n");
delay(1000);
}