void setup() {
// put your setup code here, to run once:
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
while (!Serial && millis() < 4000 );
Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWriteFast( LED_BUILTIN, !digitalReadFast( LED_BUILTIN ) );
delay(1000);
}
#include <EEPROM.h>
#define print2ln( a, b ) { Serial.print( a ), Serial.println( b ); }
#pragma pack(push, 1)
struct MyObject {
float field1;
byte field2;
char name[10];
unsigned int address;
};
#pragma pack(pop)
#define WRITE_BLOCK_SIZE (sizeof( float ) + sizeof( MyObject ))
unsigned int ZeroOffset = 0;
unsigned int GeeAddress = ZeroOffset + sizeof(uint32_t); //EEPROM address to start reading from
void setup() {
Serial.begin(9600);
while (!Serial) ; // wait for serial port to connect. Needed for Leonardo only
Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
// EEPROM.write( 0 , (uint32_t)sizeof(uint32_t) ); while(1); // USE THIS FOR FIRST RUN
uint32_t lastWrote;
EEPROM.get(0, lastWrote);
print2ln( "\nEEPROM size EEPROM.length()=", EEPROM.length() );
print2ln( "\nlastWrote EEPROM address=", lastWrote );
float ff; //Variable to store in EEPROM.
unsigned int eeAddress = GeeAddress; //EEPROM address to start reading from
do {
EEPROM.get( eeAddress, ff );
eeAddress += WRITE_BLOCK_SIZE;
Serial.print( "+ " );
} while ( 123.456f == ff && eeAddress < EEPROM.length() ); // && eeAddress < lastWrote );
print2ln( "\nPRIOR EEPROM address = ", eeAddress - WRITE_BLOCK_SIZE );
if ( eeAddress > EEPROM.length()) {
print2ln( "\nPAST END EEPROM address!", GeeAddress );
GeeAddress = ZeroOffset + sizeof(uint32_t);
}
else {
print2ln( "\nUsing lastWrote EEPROM address=", lastWrote );
GeeAddress = lastWrote;
}
}
void loop() {
print2ln( "_____- loop() :: EEPROM address = ", GeeAddress );
doPut( GeeAddress );
doGet( GeeAddress );
secondTest( GeeAddress + sizeof(float) );
while ( !Serial.available() );
while ( Serial.available() ) {
char ch = Serial.read();
if ( 'z' == ch ) {
GeeAddress = ZeroOffset + sizeof(float);
EEPROM.put( 0, GeeAddress );
Serial.print( "_____- loop() RESET EEPROM address" );
return;
}
}
EEPROM.put( 0, GeeAddress );
if ( (GeeAddress + WRITE_BLOCK_SIZE + ZeroOffset) < EEPROM.length()) GeeAddress += WRITE_BLOCK_SIZE;
if ( GeeAddress + WRITE_BLOCK_SIZE + ZeroOffset >= (EEPROM.length() - WRITE_BLOCK_SIZE) ) {
if ( GeeAddress + WRITE_BLOCK_SIZE >= EEPROM.length() ) GeeAddress -= WRITE_BLOCK_SIZE;
print2ln( "FULL EEPROM :: EEPROM address = ", GeeAddress );
while ( !Serial.available() )
while ( Serial.available() ) {
char ch = Serial.read();
if ( '0' == ch || '1' == ch || '2' == ch || '3' == ch ) {
ZeroOffset = ch - '0';
GeeAddress = ZeroOffset + sizeof(float);
EEPROM.put( 0, GeeAddress );
return;
}
}
}
}
void doPut( unsigned int eeAddress ) {
float f = 123.456f; //Variable to store in EEPROM.
EEPROM.put( eeAddress, f );
MyObject customVar = {
3.14f,
0xEE,
"Working!",
eeAddress
};
eeAddress += sizeof(float); //Move address to the next byte after float 'f'.
EEPROM.put( eeAddress, customVar );
}
void doGet( unsigned int eeAddress ) {
float f = 0.00f; //Variable to store data read from EEPROM.
Serial.print( "\nRead float from EEPROM: " );
EEPROM.get( eeAddress, f );
Serial.println( f, 3 ); //This may print 'ovf, nan' if the data inside the EEPROM is not a valid float.
}
void secondTest( unsigned int eeAddress ) {
MyObject customVar; //Variable to store custom object read from EEPROM.
EEPROM.get( eeAddress, customVar );
Serial.println( "Read custom object from EEPROM: " );
Serial.println( customVar.field1 );
Serial.println( customVar.field2, HEX );
Serial.println( customVar.name );
Serial.println( customVar.address );
}
[B]unsigned int GeeAddress [/B]= ZeroOffset + sizeof(uint32_t); //EEPROM address to start reading from
void setup() {
ZeroOffset + sizeof(uint32_t);
GeeAddress = ZeroOffset + sizeof(float);
D:\Users\Merli\Documents\Arduino\T4\post3080EEPROM\post3080EEPROM.ino May 31 2019 22:42:35
size of float:: 4
size of uint32_t:: 4
EEPROM size EEPROM.length()=1080
lastWrote EEPROM address=142
+ + + + + + + + +
PRIOR EEPROM address = 188
Using lastWrote EEPROM address=142
_____- loop() :: EEPROM address = 142
Read float from EEPROM: 123.456
Read custom object from EEPROM:
3.14
EE
Working!
142
_____- loop() :: EEPROM address = 165
Read float from EEPROM: 123.456
Read custom object from EEPROM:
3.14
EE
Working!
165
_____- loop() :: EEPROM address = 188
Read float from EEPROM: 3.140
Read custom object from EEPROM:
ovf
6B
ing!
1123477881
_____- loop() :: EEPROM address = 211
Read float from EEPROM: 3.140
Read custom object from EEPROM:
ovf
6B
ing!
1123477881
_____- loop() :: EEPROM address = 234
FULL EEPROM :: EEPROM address = 1035
Zero offset: 1
_____- loop() :: EEPROM address = 5
Read float from EEPROM: 123.456
Read custom object from EEPROM:
3.14
EE
Working!
5
_____- loop() :: EEPROM address = 28
@defragster
Isn't that what you are telling it to do.
…
Which is correct to your sketch
UPDATE: Played a little more but it looks like its working to me.
//#pragma pack(push, 1)
struct MyObject {
float field1;
byte field2;
char name[10];
unsigned int address;
};
//#pragma pack(pop)
#define WRITE_BLOCK_SIZE (sizeof( float ) + sizeof( MyObject ))
unsigned int ZeroOffset = 0;
unsigned int GeeAddress = ZeroOffset + sizeof(uint32_t); //EEPROM address to start reading from
T:\tCode\T4\T4EEPROMgetput\T4EEPROMgetput.ino May 31 2019 21:24:34
EEPROM size EEPROM.length()=1080
lastWrote EEPROM address=556
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PRIOR EEPROM address = 602
Using lastWrote EEPROM address=556
_____- loop() :: ZeroOffset value = 0
_____- loop() :: EEPROM address = 556
_____- loop() :: PRE GET ZeroOffset value = 0
Read float from EEPROM: 123.456
_____- loop() :: post GET ZeroOffset value = 0
Read custom object from EEPROM:
3.14
EE
Working!
556
_____- loop() :: ZeroOffset value = 0
_____- loop() :: EEPROM address = 579
_____- loop() :: PRE GET ZeroOffset value = 0
Read float from EEPROM: 123.456
_____- loop() :: post GET ZeroOffset value = 0
Read custom object from EEPROM:
3.14
EE
Working!
579
_____- loop() :: ZeroOffset value = 0
_____- loop() :: EEPROM address = 602
[COLOR="#FF0000"]_____- loop() :: PRE GET ZeroOffset value = 0
Read float from EEPROM: ovf
_____- loop() :: post GET ZeroOffset value = 0[/COLOR]
Read custom object from EEPROM:
503322.06
40
�Working!
154368
_____- loop() :: ZeroOffset value = 0
_____- loop() :: EEPROM address = 625
_____- loop() :: PRE GET ZeroOffset value = 0
Read float from EEPROM: ovf
_____- loop() :: post GET ZeroOffset value = 0
Read custom object from EEPROM:
503322.06
40
�Working!
160256
_____- loop() :: ZeroOffset value = 0
_____- loop() :: EEPROM address = 648
_____- loop() :: PRE GET ZeroOffset value = 0
Read float from EEPROM: ovf
_____- loop() :: post GET ZeroOffset value = 0
Read custom object from EEPROM:
503322.06
40
�Working!
166144
_____- loop() :: EEPROM address = 995
123.456<Float :: Read custom object from EEPROM: 3.14 EE Working! 995
_____- loop() :: EEPROM address = 1018
123.456<Float :: Read custom object from EEPROM: 3.14 EE Working! 1018
FULL EEPROM :: EEPROM address = 1041
#include <EEPROM.h>
#define print2ln( a, b ) { Serial.print( a ), Serial.println( b ); }
#define print2( a, b ) { Serial.print( a ), Serial.print( b ); }
int AutoRun = 0; // NUMBER of FULL passes through EEPROM
#pragma pack(push, 1)
struct MyObject {
float field1;
byte field2;
char name[10];
unsigned int address;
};
#pragma pack(pop)
#define WRITE_BLOCK_SIZE (sizeof( float ) + sizeof( MyObject ))
unsigned int ZeroOffset = 0;
unsigned int GeeAddress = ZeroOffset + sizeof(uint32_t); //EEPROM address to start reading from
void setup() {
Serial.begin(9600);
while (!Serial) ; // wait for serial port to connect. Needed for Leonardo only
Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
// EEPROM.write( 0 , (uint32_t)sizeof(uint32_t) ); while(1); // USE THIS FOR FIRST RUN
uint32_t lastWrote;
EEPROM.get(0, lastWrote);
print2ln( "\nEEPROM size EEPROM.length()=", EEPROM.length() );
print2ln( "\nlastWrote EEPROM address=", lastWrote );
float ff; //Variable to store in EEPROM.
unsigned int eeAddress = GeeAddress; //EEPROM address to start reading from
do {
EEPROM.get( eeAddress, ff );
eeAddress += WRITE_BLOCK_SIZE;
Serial.print( "+ " );
} while ( 123.456f == ff && eeAddress < EEPROM.length() ); // && eeAddress < lastWrote );
print2ln( "\nPRIOR EEPROM address = ", eeAddress - WRITE_BLOCK_SIZE );
if ( eeAddress > EEPROM.length()) {
print2ln( "\nPAST END EEPROM address!", GeeAddress );
GeeAddress = ZeroOffset + sizeof(uint32_t);
}
else {
print2ln( "\nUsing lastWrote EEPROM address=", lastWrote );
GeeAddress = lastWrote;
}
}
void loop() {
print2ln( "\n_____- loop() :: EEPROM address = ", GeeAddress );
doPut( GeeAddress );
doGet( GeeAddress );
secondTest( GeeAddress + sizeof(float) );
if ( 0 == AutoRun ) {
while ( !Serial.available() );
while ( Serial.available() ) {
char ch = Serial.read();
if ( 'z' == ch ) {
GeeAddress = ZeroOffset + sizeof(float);
EEPROM.put( 0, GeeAddress );
Serial.print( "_____- loop() RESET EEPROM address" );
return;
}
if ( 'd' == ch ) { // debug
print2ln( "_____- loop() :: ZeroOffset value = ", ZeroOffset );
print2ln( "_____- loop() :: EEPROM address = ", GeeAddress );
}
if ( 'r' == ch ) { // restart
GeeAddress = ZeroOffset + sizeof(float);
EEPROM.put( 0, GeeAddress );
print2ln( "FULL EEPROM :: EEPROM address = ", GeeAddress );
Serial.print( "_____- loop() ____RESTART " );
return;
}
}
}
EEPROM.put( 0, GeeAddress );
if ( (GeeAddress + WRITE_BLOCK_SIZE + ZeroOffset) < EEPROM.length()) GeeAddress += WRITE_BLOCK_SIZE;
if ( GeeAddress + WRITE_BLOCK_SIZE + ZeroOffset >= (EEPROM.length() - WRITE_BLOCK_SIZE) ) {
if ( GeeAddress + WRITE_BLOCK_SIZE >= EEPROM.length() ) GeeAddress -= WRITE_BLOCK_SIZE;
print2ln( "\n\nFULL EEPROM :: EEPROM address = ", GeeAddress );
if ( AutoRun ) {
AutoRun--;
ZeroOffset++;
ZeroOffset &= 3;
print2ln( "_____- loop() :: ZeroOffset value = ", ZeroOffset );
GeeAddress = ZeroOffset + sizeof(float);
EEPROM.put( 0, GeeAddress );
return;
}
while ( !Serial.available() )
while ( Serial.available() ) {
char ch = Serial.read();
if ( 'd' == ch ) { // debug
print2ln( "_____- loop() :: ZeroOffset value = ", ZeroOffset );
print2ln( "_____- loop() :: EEPROM address = ", GeeAddress );
}
if ( '0' == ch || '1' == ch || '2' == ch || '3' == ch ) {
ZeroOffset = ch - '0';
GeeAddress = ZeroOffset + sizeof(float);
EEPROM.put( 0, GeeAddress );
print2( "\n_____- loop() :: ZeroOffset value = ", ZeroOffset );
return;
}
}
}
}
void doPut( unsigned int eeAddress ) {
float f = 123.456f; //Variable to store in EEPROM.
EEPROM.put( eeAddress, f );
MyObject customVar = {
3.14f,
0xEE,
"Working!",
eeAddress
};
eeAddress += sizeof(float); //Move address to the next byte after float 'f'.
EEPROM.put( eeAddress, customVar );
}
void doGet( unsigned int eeAddress ) {
float f = 0.00f; //Variable to store data read from EEPROM.
EEPROM.get( eeAddress, f );
if ( f != 123.456f ) {
Serial.print( "\n\n>> ERROR :: Read float from EEPROM: " );
}
Serial.print( f, 3 ); //This may print 'ovf, nan' if the data inside the EEPROM is not a valid float.
if ( f != 123.456f ) {
Serial.println( "\t >> ERROR :: Read float from EEPROM: " );
}
}
void secondTest( unsigned int eeAddress ) {
MyObject customVar; //Variable to store custom object read from EEPROM.
EEPROM.get( eeAddress, customVar );
Serial.print( "<Float :: Read custom object from EEPROM: " );
Serial.print( '\t' );
Serial.print( customVar.field1 );
Serial.print( '\t' );
Serial.print( customVar.field2, HEX );
Serial.print( '\t' );
Serial.print( customVar.name );
Serial.print( '\t' );
Serial.println( customVar.address );
}
Paul: UART on Pins and Button to Bootloader T4 leaves no active sketch when repowered::
>> Is there any chance the CACHE / FIFO / (?) manipulations for the EEPROM operations are affecting Global or other sketch variable values?.
I am traveling this weekend. Don’t have access to my workbench until Monday.
But quick question, is this anything more than a case of the power management being put into the OFF state, and then remaining off when you power cycled the board, due to parasite power through the GPIO pins? I see lots of mention of the bootloader, but without the hardware here (just by reading your message) this looks like the hardware was simply turned OFF and remained that way because you didn’t fully power down, or push the On/Off button to turn it back on. Is it something more than just that?
Using lastWrote EEPROM address=4
_____- loop() :: EEPROM address = 4
123.456<Float :: Read custom object from EEPROM: 3.14 EE Working! 4
_____- loop() :: EEPROM address = 27
>> ERROR :: Read float from EEPROM: ovf >> ERROR :: Read float from EEPROM:
_____- doGet() :: ZeroOffset value = 0
_____- doGet() :: EEPROM address = 27
<Float :: Read custom object from EEPROM: -194.96 F5 H@�Working! 503316513
_____- loop() :: EEPROM address = 50
Well, how remote of a chance is “any chance”?
Those operations are only supposed to delete (or “invalidate”) stuff from the cache. So if you have a variable in cacheable memory, which does not apply to ordinary global or local variables, and if you’ve written to it so the cache is holding the recently written new value that’s not yet stored in the actual memory, and if there’s some sort of serious bug where eeprom code (or any other code) is deleting the wrong memory range from the cache, then maybe it’s possible.
By default, all normal variables are allocated in DTCM. The stack is in DTCM too, so all non-static local vars (it they are in memory at all, often the compiler keeps some or all in CPU registers). To get variables in cachable memory, you would need to use malloc() or C++ new, or DMAMEM, or something terrible like directly assigning numbers to pointers. If you’re not doing any of that stuff, if the variable is an ordinary global or local variable, then it should be located in the DTCM memory which is never accessed through the cache or anything like the FlexSPI FIFOs. No matter what is done to the cache, DTCM and ITCM that are never cached should not be affected.
That's strange. When I downloaded the EEPROM updates I updated the entire core at the same time. I am running Arduino 1.8.9 with Teensyduino 1.47 beta2 and the latest Teensy 4 core on a Win10x64 PC just for reference. The latest core has all the USB updates as well. Maybe that is whats needed?
void setup() {
Serial.begin(115200);
while (!Serial) ; // wait for serial port open
pinMode(ledPin, OUTPUT);
digitalWrite(13,HIGH);
delay(2000);
uint8_t c = EEPROM.read(0);
for (int i=0;i<100;i++) EEPROM.write(i,c+1);
delay(3000);
digitalWrite(13,LOW);
imu.begin();
}
#include <EEPROM.h>
#define print2ln( a, b ) { Serial.print( a ), Serial.println( b ); }
#define print2( a, b ) { Serial.print( a ), Serial.print( b ); }
int val;
int c, ff;
unsigned int eeAddress, eeOffset;
void setup() {
Serial.begin(115200);
while (!Serial) ; // wait for serial port to connect. Needed for Leonardo only
Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
eeOffset = sizeof(int);
eeAddress = 0;
for(int ii = 0; ii < 128; ii++){
Serial.print(EEPROM.read(ii));
Serial.print(", ");
} Serial.println();
for(int ii = 0; ii < 128; ii++){
EEPROM.write(ii,0);
}
}
void loop() {
if (Serial.available() > 0) {
c = Serial.read();
switch (c) {
case 0: // An ascii '0'
break;
default:
print2ln("Input value: ", c);
EEPROM.write( eeAddress , c);
//val = EEPROM.read(eeAddress);
//print2ln("eeProm value: ", val);
eeAddress = eeAddress + eeOffset;
break; // Do nothing;
}
}
}
#define MAX_INDEX 256
uint8_t inc_value = 0; // default to just index...
#include <EEPROM.h>
void setup() {
// put your setup code here, to run once:
while (!Serial) ;
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
Serial.println("EEPROM Test");
}
void loop() {
int ch;
// lets try writing to EEPROM
uint16_t max_index = EEPROM.length();
if (max_index > MAX_INDEX) max_index = MAX_INDEX;
Serial.printf("EEPROM length: %d Max Test: %d Inc: %d\n", EEPROM.length(), max_index, inc_value);
Serial.flush(); // Make sure the output is out
uint32_t start_time = micros();
for (uint16_t i = 0; i < max_index; i++) {
EEPROM.write(i, (i + inc_value) & 0xff);
}
Serial.printf("Write time: %d\n", micros() - start_time);
Serial.println("Start read back");
start_time = micros();
for (uint16_t i = 0; i < max_index; i++) {
uint8_t b = EEPROM.read(i);
if (b != ((i + inc_value) & 0xff)) {
Serial.printf("Read mismatch: %d %x!=%x\n", i, b, (i + inc_value) & 0xff);
}
}
Serial.printf("Read time: %d\n", micros() - start_time);
uint8_t still_waiting = false;
do {
Serial.println("Press anykey to run again");
still_waiting = false;
while (!Serial.available()) {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
delay(250);
}
if ((ch = Serial.read()) == 'i') inc_value++; // setup so we can increment all values...
if (ch == 'd') {
dump_eeprom();
still_waiting = true;
}
if (ch == 'b') {
Serial.print("Writing block 300-303 with 25 values each, start: ");
uint8_t values[4];
for (int i = 0; i < 4; i++) {
values[i] = EEPROM.read(300+i);
Serial.printf(" %2lx", values[i]);
}
Serial.println();
for (int loop_count = 0; loop_count < 25; loop_count++) {
for (int i = 0; i < 4; i++) {
EEPROM.write(300+i, ++values[i]); }
}
still_waiting = true;
}
while (Serial.available()) {
Serial.read(); // discard everything
}
} while (still_waiting);
}
/* EEPROM start address in Flash */
#define FLASH_BASEADDR 0x601F0000
#define FLASH_SECTORS 15
void dump_eeprom() {
// Lets print out all of the Possible EEPROM values.
uint16_t eeprom_size = EEPROM.length();
Serial.printf("EEPROM length: %d\nContents:\n", eeprom_size);
for (uint16_t i = 0; i < eeprom_size; i++) {
Serial.printf("%x:%x ", i, EEPROM.read(i));
if ((i & 0xf) == 0xf) Serial.println();
}
Serial.println("\nRaw Data");
// Now lets see if we can dump the flash sectors:
uint32_t sector;
uint16_t *last_indexes[256];
for (sector = 0; sector < FLASH_SECTORS; sector++) {
for (uint16_t i = 0; i < 256; i++) last_indexes[i] = nullptr; // out of range...
const uint16_t *p_start = (uint16_t *)(FLASH_BASEADDR + sector * 4096);
const uint16_t *p_end = (uint16_t *)(FLASH_BASEADDR + (sector + 1) * 4096);
uint16_t *p;
for (p = p_start; p < p_end; p++) {
if (*p == 0xFFFF) break;
last_indexes[*p & 0xff] = p;
}
Serial.printf("EEprom Page:%d addresses(%lx - %lx): first free: %x\n", sector, p_start, p_end, p);
uint8_t count = 0;
for (p = p_start; p < p_end; p++) {
if (*p == 0xFFFF) break;
uint8_t value_offset = *p & 0xff;
uint8_t value = *p >> 8;
uint16_t eeprom_index = (((value_offset >> 2)*FLASH_SECTORS) << 2) + (sector << 2) + (value_offset & 0x3);
Serial.printf(" %c%03d(%02x)=%02x", last_indexes[value_offset]== p? '*' : ' ',
eeprom_index, value_offset, value);
count++;
if (count == 16) {
Serial.println();
count = 0;
}
}
Serial.println();
}
}
EEprom Page:0 addresses(601f0000 - 601f1000): first free: 601f0f8c
000(00)=02 001(01)=03 002(02)=04 003(03)=05 060(04)=3e 061(05)=3f 062(06)=40 063(07)=41 120(08)=7a 121(09)=7b 122(0a)=7c 123(0b)=7d 180(0c)=b6 181(0d)=b7 182(0e)=b8 183(0f)=b9
240(10)=f2 241(11)=f3 242(12)=f4 243(13)=f5 300(14)=d7 301(15)=d7 302(16)=d6 303(17)=d6 302(16)=d7 303(17)=d7 300(14)=d8 301(15)=d8 302(16)=d8 303(17)=d8 300(14)=d9 301(15)=d9
302(16)=d9 303(17)=d9 300(14)=da 301(15)=da 302(16)=da 303(17)=da 300(14)=db 301(15)=db 302(16)=db 303(17)=db 300(14)=dc 301(15)=dc 302(16)=dc 303(17)=dc 300(14)=dd 301(15)=dd
302(16)=dd 303(17)=dd 300(14)=de 301(15)=de 302(16)=de 303(17)=de 300(14)=df 301(15)=df 302(16)=df 303(17)=df 300(14)=e0 301(15)=e0 302(16)=e0 303(17)=e0 300(14)=e1 301(15)=e1
302(16)=e1 303(17)=e1 300(14)=e2 301(15)=e2 302(16)=e2 303(17)=e2 300(14)=e3 301(15)=e3 302(16)=e3 303(17)=e3 300(14)=e4 301(15)=e4 302(16)=e4 303(17)=e4 300(14)=e5 301(15)=e5
302(16)=e5 303(17)=e5 300(14)=e6 301(15)=e6 302(16)=e6 303(17)=e6 300(14)=e7 301(15)=e7 302(16)=e7 303(17)=e7 300(14)=e8 301(15)=e8 302(16)=e8 303(17)=e8 300(14)=e9 301(15)=e9
302(16)=e9 303(17)=e9 300(14)=ea 301(15)=ea 302(16)=ea 303(17)=ea 300(14)=eb 301(15)=eb 302(16)=eb 303(17)=eb 300(14)=ec 301(15)=ec 302(16)=ec 303(17)=ec 300(14)=ed 301(15)=ed
302(16)=ed 303(17)=ed 300(14)=ee 301(15)=ee 302(16)=ee 303(17)=ee 300(14)=ef 301(15)=ef 302(16)=ef 303(17)=ef 300(14)=f0 301(15)=f0 302(16)=f0 303(17)=f0 300(14)=f1 301(15)=f1
302(16)=f1 303(17)=f1 000(00)=03 001(01)=04 002(02)=05 003(03)=06 060(04)=3f 061(05)=40 062(06)=41 063(07)=42 120(08)=7b 121(09)=7c 122(0a)=7d 123(0b)=7e 180(0c)=b7 181(0d)=b8
182(0e)=b9 183(0f)=ba 240(10)=f3 241(11)=f4 242(12)=f5 243(13)=f6 300(14)=f2 301(15)=f2 302(16)=f2 303(17)=f2 300(14)=f3 301(15)=f3 302(16)=f3 303(17)=f3 300(14)=f4 301(15)=f4
302(16)=f4 303(17)=f4 300(14)=f5 301(15)=f5 302(16)=f5 303(17)=f5 300(14)=f6 301(15)=f6 302(16)=f6 303(17)=f6 300(14)=f7 301(15)=f7 302(16)=f7 303(17)=f7 300(14)=f8 301(15)=f8
302(16)=f8 303(17)=f8 300(14)=f9 301(15)=f9 302(16)=f9 303(17)=f9 300(14)=fa 301(15)=fa 302(16)=fa 303(17)=fa 300(14)=fb 301(15)=fb 302(16)=fb 303(17)=fb 300(14)=fc 301(15)=fc
302(16)=fc 303(17)=fc 300(14)=fd 301(15)=fd 302(16)=fd 303(17)=fd 300(14)=fe 301(15)=fe 302(16)=fe 303(17)=fe 300(14)=ff 301(15)=ff 302(16)=ff 303(17)=ff 300(14)=00 301(15)=00
302(16)=00 303(17)=00 300(14)=01 301(15)=01 302(16)=01 303(17)=01 300(14)=02 301(15)=02 302(16)=02 303(17)=02 300(14)=03 301(15)=03 302(16)=03 303(17)=03 300(14)=04 301(15)=04
302(16)=04 303(17)=04 300(14)=05 301(15)=05 302(16)=05 303(17)=05 300(14)=06 301(15)=06 302(16)=06 303(17)=06 300(14)=07 301(15)=07 302(16)=07 303(17)=07 300(14)=08 301(15)=08
302(16)=08 303(17)=08 300(14)=09 301(15)=09 302(16)=09 303(17)=09 300(14)=0a 301(15)=0a 302(16)=0a 303(17)=0a 300(14)=0b 301(15)=0b 302(16)=0b 303(17)=0b 300(14)=0c 301(15)=0c
302(16)=0c 303(17)=0c 300(14)=0d 301(15)=0d 302(16)=0d 303(17)=0d 300(14)=0e 301(15)=0e 302(16)=0e 303(17)=0e 300(14)=0f 301(15)=0f 302(16)=0f 303(17)=0f 300(14)=10 301(15)=10
302(16)=10 303(17)=10 300(14)=11 301(15)=11 302(16)=11 303(17)=11 300(14)=12 301(15)=12 302(16)=12 303(17)=12 300(14)=13 301(15)=13 302(16)=13 303(17)=13 300(14)=14 301(15)=14
302(16)=14 303(17)=14 300(14)=15 301(15)=15 302(16)=15 303(17)=15 300(14)=16 301(15)=16 302(16)=16 303(17)=16 300(14)=17 301(15)=17 302(16)=17 303(17)=17 300(14)=18 301(15)=18
302(16)=18 303(17)=18 300(14)=19 301(15)=19 302(16)=19 303(17)=19 300(14)=1a 301(15)=1a 302(16)=1a 303(17)=1a 300(14)=1b 301(15)=1b 302(16)=1b 303(17)=1b 300(14)=1c 301(15)=1c
302(16)=1c 303(17)=1c 300(14)=1d 301(15)=1d 302(16)=1d 303(17)=1d 300(14)=1e 301(15)=1e 302(16)=1e 303(17)=1e 300(14)=1f 301(15)=1f 302(16)=1f 303(17)=1f 300(14)=20 301(15)=20
302(16)=20 303(17)=20 300(14)=21 301(15)=21 302(16)=21 303(17)=21 300(14)=22 301(15)=22 302(16)=22 303(17)=22 300(14)=23 301(15)=23 302(16)=23 303(17)=23 300(14)=24 301(15)=24
302(16)=24 303(17)=24 300(14)=25 301(15)=25 302(16)=25 303(17)=25 300(14)=26 301(15)=26 302(16)=26 303(17)=26 300(14)=27 301(15)=27 302(16)=27 303(17)=27 300(14)=28 301(15)=28
302(16)=28 303(17)=28 300(14)=29 301(15)=29 302(16)=29 303(17)=29 300(14)=2a 301(15)=2a 302(16)=2a 303(17)=2a 300(14)=2b 301(15)=2b 302(16)=2b 303(17)=2b 300(14)=2c 301(15)=2c
302(16)=2c 303(17)=2c 300(14)=2d 301(15)=2d 302(16)=2d 303(17)=2d 300(14)=2e 301(15)=2e 302(16)=2e 303(17)=2e 300(14)=2f 301(15)=2f 302(16)=2f 303(17)=2f 300(14)=30 301(15)=30
302(16)=30 303(17)=30 300(14)=31 301(15)=31 302(16)=31 303(17)=31 300(14)=32 301(15)=32 302(16)=32 303(17)=32 300(14)=33 301(15)=33 302(16)=33 303(17)=33 300(14)=34 301(15)=34
302(16)=34 303(17)=34 300(14)=35 301(15)=35 302(16)=35 303(17)=35 300(14)=36 301(15)=36 302(16)=36 303(17)=36 300(14)=37 301(15)=37 302(16)=37 303(17)=37 300(14)=38 301(15)=38
302(16)=38 303(17)=38 300(14)=39 301(15)=39 302(16)=39 303(17)=39 300(14)=3a 301(15)=3a 302(16)=3a 303(17)=3a 300(14)=3b 301(15)=3b 302(16)=3b 303(17)=3b 300(14)=3c 301(15)=3c
302(16)=3c 303(17)=3c 300(14)=3d 301(15)=3d 302(16)=3d 303(17)=3d 300(14)=3e 301(15)=3e 302(16)=3e 303(17)=3e 300(14)=3f 301(15)=3f 302(16)=3f 303(17)=3f 300(14)=40 301(15)=40
302(16)=40 303(17)=40 300(14)=41 301(15)=41 302(16)=41 303(17)=41 300(14)=42 301(15)=42 302(16)=42 303(17)=42 300(14)=43 301(15)=43 302(16)=43 303(17)=43 300(14)=44 301(15)=44
302(16)=44 303(17)=44 300(14)=45 301(15)=45 302(16)=45 303(17)=45 300(14)=46 301(15)=46 302(16)=46 303(17)=46 300(14)=47 301(15)=47 302(16)=47 303(17)=47 300(14)=48 301(15)=48
302(16)=48 303(17)=48 300(14)=49 301(15)=49 302(16)=49 303(17)=49 300(14)=4a 301(15)=4a 302(16)=4a 303(17)=4a 300(14)=4b 301(15)=4b 302(16)=4b 303(17)=4b 300(14)=4c 301(15)=4c
302(16)=4c 303(17)=4c 300(14)=4d 301(15)=4d 302(16)=4d 303(17)=4d 300(14)=4e 301(15)=4e 302(16)=4e 303(17)=4e 300(14)=4f 301(15)=4f 302(16)=4f 303(17)=4f 300(14)=50 301(15)=50
302(16)=50 303(17)=50 300(14)=51 301(15)=51 302(16)=51 303(17)=51 300(14)=52 301(15)=52 302(16)=52 303(17)=52 300(14)=53 301(15)=53 302(16)=53 303(17)=53 300(14)=54 301(15)=54
302(16)=54 303(17)=54 300(14)=55 301(15)=55 302(16)=55 303(17)=55 300(14)=56 301(15)=56 302(16)=56 303(17)=56 300(14)=57 301(15)=57 302(16)=57 303(17)=57 300(14)=58 301(15)=58
302(16)=58 303(17)=58 300(14)=59 301(15)=59 302(16)=59 303(17)=59 300(14)=5a 301(15)=5a 302(16)=5a 303(17)=5a 300(14)=5b 301(15)=5b 302(16)=5b 303(17)=5b 300(14)=5c 301(15)=5c
302(16)=5c 303(17)=5c 300(14)=5d 301(15)=5d 302(16)=5d 303(17)=5d 300(14)=5e 301(15)=5e 302(16)=5e 303(17)=5e 300(14)=5f 301(15)=5f 302(16)=5f 303(17)=5f 300(14)=60 301(15)=60
302(16)=60 303(17)=60 300(14)=61 301(15)=61 302(16)=61 303(17)=61 300(14)=62 301(15)=62 302(16)=62 303(17)=62 300(14)=63 301(15)=63 302(16)=63 303(17)=63 300(14)=64 301(15)=64
302(16)=64 303(17)=64 300(14)=65 301(15)=65 302(16)=65 303(17)=65 300(14)=66 301(15)=66 302(16)=66 303(17)=66 300(14)=67 301(15)=67 302(16)=67 303(17)=67 300(14)=68 301(15)=68
302(16)=68 303(17)=68 300(14)=69 301(15)=69 302(16)=69 303(17)=69 300(14)=6a 301(15)=6a 302(16)=6a 303(17)=6a 300(14)=6b 301(15)=6b 302(16)=6b 303(17)=6b 300(14)=6c 301(15)=6c
302(16)=6c 303(17)=6c 300(14)=6d 301(15)=6d 302(16)=6d 303(17)=6d 300(14)=6e 301(15)=6e 302(16)=6e 303(17)=6e 300(14)=6f 301(15)=6f 302(16)=6f 303(17)=6f 300(14)=70 301(15)=70
302(16)=70 303(17)=70 300(14)=71 301(15)=71 302(16)=71 303(17)=71 300(14)=72 301(15)=72 302(16)=72 303(17)=72 300(14)=73 301(15)=73 302(16)=73 303(17)=73 300(14)=74 301(15)=74
302(16)=74 303(17)=74 300(14)=75 301(15)=75 302(16)=75 303(17)=75 300(14)=76 301(15)=76 302(16)=76 303(17)=76 300(14)=77 301(15)=77 302(16)=77 303(17)=77 300(14)=78 301(15)=78
302(16)=78 303(17)=78 300(14)=79 301(15)=79 302(16)=79 303(17)=79 300(14)=7a 301(15)=7a 302(16)=7a 303(17)=7a 300(14)=7b 301(15)=7b 302(16)=7b 303(17)=7b 300(14)=7c 301(15)=7c
302(16)=7c 303(17)=7c 300(14)=7d 301(15)=7d 302(16)=7d 303(17)=7d 300(14)=7e 301(15)=7e 302(16)=7e 303(17)=7e 300(14)=7f 301(15)=7f 302(16)=7f 303(17)=7f 300(14)=80 301(15)=80
302(16)=80 303(17)=80 300(14)=81 301(15)=81 302(16)=81 303(17)=81 300(14)=82 301(15)=82 302(16)=82 303(17)=82 300(14)=83 301(15)=83 302(16)=83 303(17)=83 300(14)=84 301(15)=84
302(16)=84 303(17)=84 300(14)=85 301(15)=85 302(16)=85 303(17)=85 300(14)=86 301(15)=86 302(16)=86 303(17)=86 300(14)=87 301(15)=87 302(16)=87 303(17)=87 300(14)=88 301(15)=88
302(16)=88 303(17)=88 300(14)=89 301(15)=89 302(16)=89 303(17)=89 300(14)=8a 301(15)=8a 302(16)=8a 303(17)=8a 300(14)=8b 301(15)=8b 302(16)=8b 303(17)=8b 300(14)=8c 301(15)=8c
302(16)=8c 303(17)=8c 300(14)=8d 301(15)=8d 302(16)=8d 303(17)=8d 300(14)=8e 301(15)=8e 302(16)=8e 303(17)=8e 300(14)=8f 301(15)=8f 302(16)=8f 303(17)=8f 300(14)=90 301(15)=90
302(16)=90 303(17)=90 300(14)=91 301(15)=91 302(16)=91 303(17)=91 300(14)=92 301(15)=92 302(16)=92 303(17)=92 300(14)=93 301(15)=93 302(16)=93 303(17)=93 300(14)=94 301(15)=94
302(16)=94 303(17)=94 300(14)=95 301(15)=95 302(16)=95 303(17)=95 300(14)=96 301(15)=96 302(16)=96 303(17)=96 300(14)=97 301(15)=97 302(16)=97 303(17)=97 300(14)=98 301(15)=98
302(16)=98 303(17)=98 300(14)=99 301(15)=99 302(16)=99 303(17)=99 300(14)=9a 301(15)=9a 302(16)=9a 303(17)=9a 300(14)=9b 301(15)=9b 302(16)=9b 303(17)=9b 300(14)=9c 301(15)=9c
302(16)=9c 303(17)=9c 300(14)=9d 301(15)=9d 302(16)=9d 303(17)=9d 300(14)=9e 301(15)=9e 302(16)=9e 303(17)=9e 300(14)=9f 301(15)=9f 302(16)=9f 303(17)=9f 300(14)=a0 301(15)=a0
302(16)=a0 303(17)=a0 300(14)=a1 301(15)=a1 302(16)=a1 303(17)=a1 300(14)=a2 301(15)=a2 302(16)=a2 303(17)=a2 300(14)=a3 301(15)=a3 302(16)=a3 303(17)=a3 300(14)=a4 301(15)=a4
302(16)=a4 303(17)=a4 300(14)=a5 301(15)=a5 302(16)=a5 303(17)=a5 300(14)=a6 301(15)=a6 302(16)=a6 303(17)=a6 300(14)=a7 301(15)=a7 302(16)=a7 303(17)=a7 300(14)=a8 301(15)=a8
302(16)=a8 303(17)=a8 300(14)=a9 301(15)=a9 302(16)=a9 303(17)=a9 300(14)=aa 301(15)=aa 302(16)=aa 303(17)=aa 300(14)=ab 301(15)=ab 302(16)=ab 303(17)=ab 300(14)=ac 301(15)=ac
302(16)=ac 303(17)=ac 300(14)=ad 301(15)=ad 302(16)=ad 303(17)=ad 300(14)=ae 301(15)=ae 302(16)=ae 303(17)=ae 300(14)=af 301(15)=af 302(16)=af 303(17)=af 300(14)=b0 301(15)=b0
302(16)=b0 303(17)=b0 300(14)=b1 301(15)=b1 302(16)=b1 303(17)=b1 300(14)=b2 301(15)=b2 302(16)=b2 303(17)=b2 300(14)=b3 301(15)=b3 302(16)=b3 303(17)=b3 300(14)=b4 301(15)=b4
302(16)=b4 303(17)=b4 300(14)=b5 301(15)=b5 302(16)=b5 303(17)=b5 300(14)=b6 301(15)=b6 302(16)=b6 303(17)=b6 300(14)=b7 301(15)=b7 302(16)=b7 303(17)=b7 300(14)=b8 301(15)=b8
302(16)=b8 303(17)=b8 300(14)=b9 301(15)=b9 302(16)=b9 303(17)=b9 300(14)=ba 301(15)=ba 302(16)=ba 303(17)=ba 300(14)=bb 301(15)=bb 302(16)=bb 303(17)=bb 300(14)=bc 301(15)=bc
302(16)=bc 303(17)=bc 300(14)=bd 301(15)=bd 302(16)=bd 303(17)=bd 300(14)=be 301(15)=be 302(16)=be 303(17)=be 300(14)=bf 301(15)=bf 302(16)=bf 303(17)=bf 300(14)=c0 301(15)=c0
302(16)=c0 303(17)=c0 300(14)=c1 301(15)=c1 302(16)=c1 303(17)=c1 300(14)=c2 301(15)=c2 302(16)=c2 303(17)=c2 300(14)=c3 301(15)=c3 302(16)=c3 303(17)=c3 300(14)=c4 301(15)=c4
302(16)=c4 303(17)=c4 300(14)=c5 301(15)=c5 302(16)=c5 303(17)=c5 300(14)=c6 301(15)=c6 302(16)=c6 303(17)=c6 300(14)=c7 301(15)=c7 302(16)=c7 303(17)=c7 300(14)=c8 301(15)=c8
302(16)=c8 303(17)=c8 300(14)=c9 301(15)=c9 302(16)=c9 303(17)=c9 300(14)=ca 301(15)=ca 302(16)=ca 303(17)=ca 300(14)=cb 301(15)=cb 302(16)=cb 303(17)=cb 300(14)=cc 301(15)=cc
302(16)=cc 303(17)=cc 300(14)=cd 301(15)=cd 302(16)=cd 303(17)=cd 300(14)=ce 301(15)=ce 302(16)=ce 303(17)=ce 300(14)=cf 301(15)=cf 302(16)=cf 303(17)=cf 300(14)=d0 301(15)=d0
302(16)=d0 303(17)=d0 300(14)=d1 301(15)=d1 302(16)=d1 303(17)=d1 300(14)=d2 301(15)=d2 302(16)=d2 303(17)=d2 300(14)=d3 301(15)=d3 302(16)=d3 303(17)=d3 300(14)=d4 301(15)=d4
302(16)=d4 303(17)=d4 300(14)=d5 301(15)=d5 302(16)=d5 303(17)=d5 300(14)=d6 301(15)=d6 302(16)=d6 303(17)=d6 300(14)=d7 301(15)=d7 302(16)=d7 303(17)=d7 300(14)=d8 301(15)=d8
302(16)=d8 303(17)=d8 300(14)=d9 301(15)=d9 302(16)=d9 303(17)=d9 300(14)=da 301(15)=da 302(16)=da 303(17)=da 300(14)=db 301(15)=db 302(16)=db 303(17)=db 300(14)=dc 301(15)=dc
302(16)=dc 303(17)=dc 300(14)=dd 301(15)=dd 302(16)=dd 303(17)=dd 300(14)=de 301(15)=de 302(16)=de 303(17)=de 300(14)=df 301(15)=df 302(16)=df 303(17)=df 300(14)=e0 301(15)=e0
302(16)=e0 303(17)=e0 300(14)=e1 301(15)=e1 302(16)=e1 303(17)=e1 300(14)=e2 301(15)=e2 302(16)=e2 303(17)=e2 300(14)=e3 301(15)=e3 302(16)=e3 303(17)=e3 300(14)=e4 301(15)=e4
302(16)=e4 303(17)=e4 300(14)=e5 301(15)=e5 302(16)=e5 303(17)=e5 300(14)=e6 301(15)=e6 302(16)=e6 303(17)=e6 300(14)=e7 301(15)=e7 302(16)=e7 303(17)=e7 300(14)=e8 301(15)=e8
302(16)=e8 303(17)=e8 300(14)=e9 301(15)=e9 302(16)=e9 303(17)=e9 300(14)=ea 301(15)=ea 302(16)=ea 303(17)=ea 300(14)=eb 301(15)=eb 302(16)=eb 303(17)=eb 300(14)=ec 301(15)=ec
302(16)=ec 303(17)=ec 300(14)=ed 301(15)=ed 302(16)=ed 303(17)=ed 300(14)=ee 301(15)=ee 302(16)=ee 303(17)=ee 300(14)=ef 301(15)=ef 302(16)=ef 303(17)=ef 300(14)=f0 301(15)=f0
302(16)=f0 303(17)=f0 300(14)=f1 301(15)=f1 302(16)=f1 303(17)=f1 300(14)=f2 301(15)=f2 302(16)=f2 303(17)=f2 300(14)=f3 301(15)=f3 302(16)=f3 303(17)=f3 300(14)=f4 301(15)=f4
302(16)=f4 303(17)=f4 300(14)=f5 301(15)=f5 302(16)=f5 303(17)=f5 300(14)=f6 301(15)=f6 302(16)=f6 303(17)=f6 300(14)=f7 301(15)=f7 302(16)=f7 303(17)=f7 300(14)=f8 301(15)=f8
302(16)=f8 303(17)=f8 300(14)=f9 301(15)=f9 302(16)=f9 303(17)=f9 300(14)=fa 301(15)=fa 302(16)=fa 303(17)=fa 300(14)=fb 301(15)=fb 302(16)=fb 303(17)=fb 300(14)=fc 301(15)=fc
302(16)=fc 303(17)=fc 300(14)=fd 301(15)=fd 302(16)=fd 303(17)=fd 300(14)=fe 301(15)=fe 302(16)=fe 303(17)=fe 300(14)=ff 301(15)=ff 302(16)=ff 303(17)=ff 300(14)=00 301(15)=00
302(16)=00 303(17)=00 300(14)=01 301(15)=01 302(16)=01 303(17)=01 300(14)=02 301(15)=02 302(16)=02 303(17)=02 300(14)=03 301(15)=03 302(16)=03 303(17)=03 300(14)=04 301(15)=04
302(16)=04 303(17)=04 300(14)=05 301(15)=05 302(16)=05 303(17)=05 300(14)=06 301(15)=06 302(16)=06 303(17)=06 300(14)=07 301(15)=07 302(16)=07 303(17)=07 300(14)=08 301(15)=08
302(16)=08 303(17)=08 300(14)=09 301(15)=09 302(16)=09 303(17)=09 300(14)=0a 301(15)=0a 302(16)=0a 303(17)=0a 300(14)=0b 301(15)=0b 302(16)=0b 303(17)=0b 300(14)=0c 301(15)=0c
302(16)=0c 303(17)=0c 300(14)=0d 301(15)=0d 302(16)=0d 303(17)=0d 300(14)=0e 301(15)=0e 302(16)=0e 303(17)=0e 300(14)=0f 301(15)=0f 302(16)=0f 303(17)=0f 300(14)=10 301(15)=10
302(16)=10 303(17)=10 300(14)=11 301(15)=11 302(16)=11 303(17)=11 300(14)=12 301(15)=12 302(16)=12 303(17)=12 300(14)=13 301(15)=13 302(16)=13 303(17)=13 300(14)=14 301(15)=14
302(16)=14 303(17)=14 300(14)=15 301(15)=15 302(16)=15 303(17)=15 300(14)=16 301(15)=16 302(16)=16 303(17)=16 300(14)=17 301(15)=17 302(16)=17 303(17)=17 300(14)=18 301(15)=18
302(16)=18 303(17)=18 300(14)=19 301(15)=19 302(16)=19 303(17)=19 300(14)=1a 301(15)=1a 302(16)=1a 303(17)=1a 300(14)=1b 301(15)=1b 302(16)=1b 303(17)=1b 300(14)=1c 301(15)=1c
302(16)=1c 303(17)=1c 300(14)=1d 301(15)=1d 302(16)=1d 303(17)=1d 300(14)=1e 301(15)=1e 302(16)=1e 303(17)=1e 300(14)=1f 301(15)=1f 302(16)=1f 303(17)=1f 300(14)=20 301(15)=20
302(16)=20 303(17)=20 300(14)=21 301(15)=21 302(16)=21 303(17)=21 300(14)=22 301(15)=22 302(16)=22 303(17)=22 300(14)=23 301(15)=23 302(16)=23 303(17)=23 300(14)=24 301(15)=24
302(16)=24 303(17)=24 300(14)=25 301(15)=25 302(16)=25 303(17)=25 300(14)=26 301(15)=26 302(16)=26 303(17)=26 300(14)=27 301(15)=27 302(16)=27 303(17)=27 300(14)=28 301(15)=28
302(16)=28 303(17)=28 300(14)=29 301(15)=29 302(16)=29 303(17)=29 300(14)=2a 301(15)=2a 302(16)=2a 303(17)=2a 300(14)=2b 301(15)=2b 302(16)=2b 303(17)=2b 300(14)=2c 301(15)=2c
302(16)=2c 303(17)=2c 300(14)=2d 301(15)=2d 302(16)=2d 303(17)=2d 300(14)=2e 301(15)=2e 302(16)=2e 303(17)=2e 300(14)=2f 301(15)=2f 302(16)=2f 303(17)=2f 300(14)=30 301(15)=30
302(16)=30 303(17)=30 300(14)=31 301(15)=31 302(16)=31 303(17)=31 300(14)=32 301(15)=32 302(16)=32 303(17)=32 300(14)=33 301(15)=33 302(16)=33 303(17)=33 300(14)=34 301(15)=34
302(16)=34 303(17)=34 300(14)=35 301(15)=35 302(16)=35 303(17)=35 300(14)=36 301(15)=36 302(16)=36 303(17)=36 300(14)=37 301(15)=37 302(16)=37 303(17)=37 300(14)=38 301(15)=38
302(16)=38 303(17)=38 300(14)=39 301(15)=39 302(16)=39 303(17)=39 300(14)=3a 301(15)=3a 302(16)=3a 303(17)=3a 300(14)=3b 301(15)=3b 302(16)=3b 303(17)=3b 300(14)=3c 301(15)=3c
302(16)=3c 303(17)=3c 300(14)=3d 301(15)=3d 302(16)=3d 303(17)=3d 300(14)=3e 301(15)=3e 302(16)=3e 303(17)=3e 300(14)=3f 301(15)=3f 302(16)=3f 303(17)=3f 300(14)=40 301(15)=40
302(16)=40 303(17)=40 300(14)=41 301(15)=41 302(16)=41 303(17)=41 300(14)=42 301(15)=42 302(16)=42 303(17)=42 300(14)=43 301(15)=43 302(16)=43 303(17)=43 300(14)=44 301(15)=44
302(16)=44 303(17)=44 300(14)=45 301(15)=45 302(16)=45 303(17)=45 300(14)=46 301(15)=46 302(16)=46 303(17)=46 300(14)=47 301(15)=47 302(16)=47 303(17)=47 300(14)=48 301(15)=48
302(16)=48 303(17)=48 300(14)=49 301(15)=49 302(16)=49 303(17)=49 300(14)=4a 301(15)=4a 302(16)=4a 303(17)=4a 300(14)=4b 301(15)=4b 302(16)=4b 303(17)=4b 300(14)=4c 301(15)=4c
302(16)=4c 303(17)=4c 300(14)=4d 301(15)=4d 302(16)=4d 303(17)=4d 300(14)=4e 301(15)=4e 302(16)=4e 303(17)=4e 300(14)=4f 301(15)=4f 302(16)=4f 303(17)=4f 300(14)=50 301(15)=50
302(16)=50 303(17)=50 300(14)=51 301(15)=51 302(16)=51 303(17)=51 300(14)=52 301(15)=52 302(16)=52 303(17)=52 300(14)=53 301(15)=53 302(16)=53 303(17)=53 300(14)=54 301(15)=54
302(16)=54 303(17)=54 300(14)=55 301(15)=55 302(16)=55 303(17)=55 300(14)=56 301(15)=56 302(16)=56 303(17)=56 300(14)=57 301(15)=57 302(16)=57 303(17)=57 300(14)=58 301(15)=58
302(16)=58 303(17)=58 300(14)=59 301(15)=59 302(16)=59 303(17)=59 300(14)=5a 301(15)=5a 302(16)=5a 303(17)=5a 300(14)=5b 301(15)=5b 302(16)=5b 303(17)=5b 300(14)=5c 301(15)=5c
302(16)=5c 303(17)=5c 300(14)=5d 301(15)=5d 302(16)=5d 303(17)=5d 300(14)=5e 301(15)=5e 302(16)=5e 303(17)=5e 300(14)=5f 301(15)=5f 302(16)=5f 303(17)=5f 300(14)=60 301(15)=60
302(16)=60 303(17)=60 300(14)=61 301(15)=61 302(16)=61 303(17)=61 300(14)=62 301(15)=62 302(16)=62 303(17)=62 300(14)=63 301(15)=63 302(16)=63 303(17)=63 300(14)=64 301(15)=64
302(16)=64 303(17)=64 300(14)=65 301(15)=65 302(16)=65 303(17)=65 300(14)=66 301(15)=66 302(16)=66 303(17)=66 300(14)=67 301(15)=67 302(16)=67 303(17)=67 300(14)=68 301(15)=68
302(16)=68 303(17)=68 000(00)=04 001(01)=05 002(02)=06 003(03)=07 060(04)=40 061(05)=41 062(06)=42 063(07)=43 120(08)=7c 121(09)=7d 122(0a)=7e 123(0b)=7f 180(0c)=b8 181(0d)=b9
182(0e)=ba 183(0f)=bb 240(10)=f4 241(11)=f5 242(12)=f6 243(13)=f7 300(14)=69 301(15)=69 302(16)=69 303(17)=69 300(14)=6a 301(15)=6a 302(16)=6a 303(17)=6a 300(14)=6b 301(15)=6b
302(16)=6b 303(17)=6b 300(14)=6c 301(15)=6c 302(16)=6c 303(17)=6c 300(14)=6d 301(15)=6d 302(16)=6d 303(17)=6d 300(14)=6e 301(15)=6e 302(16)=6e 303(17)=6e 300(14)=6f 301(15)=6f
302(16)=6f 303(17)=6f 300(14)=70 301(15)=70 302(16)=70 303(17)=70 300(14)=71 301(15)=71 302(16)=71 303(17)=71 300(14)=72 301(15)=72 302(16)=72 303(17)=72 300(14)=73 301(15)=73
302(16)=73 303(17)=73 300(14)=74 301(15)=74 302(16)=74 303(17)=74 300(14)=75 301(15)=75 302(16)=75 303(17)=75 300(14)=76 301(15)=76 302(16)=76 303(17)=76 300(14)=77 301(15)=77
302(16)=77 303(17)=77 300(14)=78 301(15)=78 302(16)=78 303(17)=78 300(14)=79 301(15)=79 302(16)=79 303(17)=79 300(14)=7a 301(15)=7a 302(16)=7a 303(17)=7a 300(14)=7b 301(15)=7b
302(16)=7b 303(17)=7b 300(14)=7c 301(15)=7c 302(16)=7c 303(17)=7c 300(14)=7d 301(15)=7d 302(16)=7d 303(17)=7d 300(14)=7e 301(15)=7e 302(16)=7e 303(17)=7e 300(14)=7f 301(15)=7f
302(16)=7f 303(17)=7f 300(14)=80 301(15)=80 302(16)=80 303(17)=80 300(14)=81 301(15)=81 302(16)=81 303(17)=81 300(14)=82 301(15)=82 302(16)=82 303(17)=82 300(14)=83 301(15)=83
302(16)=83 303(17)=83 300(14)=84 301(15)=84 302(16)=84 303(17)=84 300(14)=85 301(15)=85 302(16)=85 303(17)=85 300(14)=86 301(15)=86 302(16)=86 303(17)=86 300(14)=87 301(15)=87
302(16)=87 303(17)=87 300(14)=88 301(15)=88 302(16)=88 303(17)=88 300(14)=89 301(15)=89 302(16)=89 303(17)=89 300(14)=8a 301(15)=8a 302(16)=8a 303(17)=8a 300(14)=8b 301(15)=8b
302(16)=8b 303(17)=8b 300(14)=8c 301(15)=8c 302(16)=8c 303(17)=8c 300(14)=8d 301(15)=8d 302(16)=8d 303(17)=8d 300(14)=8e 301(15)=8e 302(16)=8e 303(17)=8e 300(14)=8f 301(15)=8f
302(16)=8f 303(17)=8f 300(14)=90 301(15)=90 302(16)=90 303(17)=90 300(14)=91 301(15)=91 302(16)=91 303(17)=91 300(14)=92 301(15)=92 302(16)=92 303(17)=92 300(14)=93 301(15)=93
302(16)=93 303(17)=93 300(14)=94 301(15)=94 302(16)=94 303(17)=94 300(14)=95 301(15)=95 302(16)=95 303(17)=95 300(14)=96 301(15)=96 302(16)=96 303(17)=96 300(14)=97 301(15)=97
302(16)=97 303(17)=97 300(14)=98 301(15)=98 302(16)=98 303(17)=98 300(14)=99 301(15)=99 302(16)=99 303(17)=99 300(14)=9a 301(15)=9a 302(16)=9a 303(17)=9a 300(14)=9b 301(15)=9b
302(16)=9b 303(17)=9b 300(14)=9c 301(15)=9c 302(16)=9c 303(17)=9c 300(14)=9d 301(15)=9d 302(16)=9d 303(17)=9d 300(14)=9e 301(15)=9e 302(16)=9e 303(17)=9e 300(14)=9f 301(15)=9f
302(16)=9f 303(17)=9f 300(14)=a0 301(15)=a0 302(16)=a0 303(17)=a0 300(14)=a1 301(15)=a1 302(16)=a1 303(17)=a1 300(14)=a2 301(15)=a2 302(16)=a2 303(17)=a2 300(14)=a3 301(15)=a3
302(16)=a3 303(17)=a3 300(14)=a4 301(15)=a4 302(16)=a4 303(17)=a4 300(14)=a5 301(15)=a5 302(16)=a5 303(17)=a5 300(14)=a6 301(15)=a6 302(16)=a6 303(17)=a6 300(14)=a7 301(15)=a7
302(16)=a7 303(17)=a7 300(14)=a8 301(15)=a8 302(16)=a8 303(17)=a8 300(14)=a9 301(15)=a9 302(16)=a9 303(17)=a9 300(14)=aa 301(15)=aa 302(16)=aa 303(17)=aa 300(14)=ab 301(15)=ab
302(16)=ab 303(17)=ab 300(14)=ac 301(15)=ac 302(16)=ac 303(17)=ac 300(14)=ad 301(15)=ad 302(16)=ad 303(17)=ad 300(14)=ae 301(15)=ae 302(16)=ae 303(17)=ae 300(14)=af 301(15)=af
302(16)=af 303(17)=af 300(14)=b0 301(15)=b0 302(16)=b0 303(17)=b0 300(14)=b1 301(15)=b1 302(16)=b1 303(17)=b1 300(14)=b2 301(15)=b2 302(16)=b2 303(17)=b2 *300(14)=b3 *301(15)=b3
*302(16)=b3 *303(17)=b3 *000(00)=05 *001(01)=06 *002(02)=07 *003(03)=08 *060(04)=41 *061(05)=42 *062(06)=43 *063(07)=44 *120(08)=7d *121(09)=7e *122(0a)=7f *123(0b)=80 *180(0c)=b9 *181(0d)=ba
*182(0e)=bb *183(0f)=bc *240(10)=f5 *241(11)=f6 *242(12)=f7 *243(13)=f8
EEprom Page:0 addresses(601f0000 - 601f1000): first free: 601f0032
*000(00)=08 *001(01)=09 *002(02)=0a *003(03)=0b *060(04)=44 *061(05)=45 *062(06)=46 *063(07)=47 *120(08)=80 *121(09)=81 *122(0a)=82 *123(0b)=83 *180(0c)=bc *181(0d)=bd *182(0e)=be *183(0f)=bf
*240(10)=f8 *241(11)=f9 *242(12)=fa 243(13)=fa *300(14)=b3 *301(15)=b3 *302(16)=b3 *303(17)=b3 *243(13)=fb
…
I see lots of mention of the bootloader, but without the hardware here
...
@Paul / ??? - there is a way for T4 to enter BOOTLOADER { that "asm("bkpt #251");" code that works with complain outside the IDE - but breaks build in the IDE } - but I don't think I've seen a SOFTWARE RESET/RESTART command? There is '__NVIC_SystemReset' in core_cm7.h - but that is missing other needed header "cmsis_version.h" ...
D:\Users\Merli\Documents\Arduino\EchoBoth\EchoBoth.ino May 23 2019 18:18:04
PORT Serial1 and BAUD=115200
Running Calibration
Calibratrion Data CRC (s/b 0): 0
Calibration Data
Magnetic (Hard Iron) Offsets
9.53 uT
-13.52 uT
68.23 uT
Magnetic Soft Iron Mapping
0.9768 -0.0127 -0.0129
-0.0127 1.0053 -0.0015
-0.0129 -0.0015 1.0187
Expected Magnetic Field Strength
40.36 uT
Magnetic (Hard Iron) Offsets
8.88 uT
-13.45 uT
68.48 uT
Magnetic Soft Iron Mapping
0.9780 -0.0199 -0.0077
-0.0199 0.9953 -0.0034
-0.0077 -0.0034 1.0278
Expected Magnetic Field Strength
40.54 uT
#include <NXPMotionSense.h>
#include <Wire.h>
#include <EEPROM.h>
#include <util/crc16.h>
#define NXP_MOTION_CAL_EEADDR 60
#define NXP_MOTION_CAL_SIZE 68
float cal[16]; // 0-8=offsets, 9=field strength, 10-15=soft iron map
NXPMotionSense imu;
const int ledPin = 13;
int ledState = LOW;
int ledFastblinks = 0;
elapsedMillis ledMillis = 0;
int loopcount = 0;
void receiveCalibration();
void setup() {
Serial.begin(115200);
Serial1.begin(115200);
while (!Serial) ; // wait for serial port open
imu.begin();
Serial1.println("Running Calibration");
pinMode(ledPin, OUTPUT);
}
void loop() {
int ax, ay, az;
int gx, gy, gz;
int mx, my, mz;
// get and print uncalibrated data
if (imu.available()) {
imu.readMotionSensor(ax, ay, az, gx, gy, gz, mx, my, mz);
Serial.print("Raw:");
Serial.print(ax);
Serial.print(',');
Serial.print(ay);
Serial.print(',');
Serial.print(az);
Serial.print(',');
Serial.print(gx);
Serial.print(',');
Serial.print(gy);
Serial.print(',');
Serial.print(gz);
Serial.print(',');
Serial.print(mx);
Serial.print(',');
Serial.print(my);
Serial.print(',');
Serial.print(mz);
Serial.println();
loopcount = loopcount + 1;
}
// check for incoming calibration
receiveCalibration();
// occasionally print calibration
if (loopcount == 50 || loopcount > 100) {
Serial.print("Cal1:");
float caloffsets[9], calmag;
imu.getCalibration(caloffsets, NULL, &calmag);
for (int i=0; i<9; i++) {
Serial.print(caloffsets[i], 3);
Serial.print(',');
}
Serial.println(calmag, 3);
loopcount = loopcount + 1;
}
if (loopcount >= 100) {
Serial.print("Cal2:");
float calsoftiron[9];
imu.getCalibration(NULL, calsoftiron, NULL);
for (int i=0; i<9; i++) {
Serial.print(calsoftiron[i], 4);
if (i < 8) Serial.print(',');
}
Serial.println();
loopcount = 0;
}
// blink LED, slow normally, fast when calibration written
if (ledMillis >= 1000) {
if (ledFastblinks > 0) {
ledFastblinks = ledFastblinks - 1;
ledMillis -= 125;
} else {
ledMillis -= 1000;
}
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(ledPin, ledState);
}
}
byte caldata[68]; // buffer to receive magnetic calibration data
byte calcount=0;
void receiveCalibration() {
uint16_t crc;
byte b, i;
if (Serial.available()) {
b = Serial.read();
if (calcount == 0 && b != 117) {
// first byte must be 117
return;
}
if (calcount == 1 && b != 84) {
// second byte must be 84
calcount = 0;
return;
}
// store this byte
caldata[calcount++] = b;
if (calcount < 68) {
// full calibration message is 68 bytes
return;
}
// verify the crc16 check
crc = 0xFFFF;
for (i=0; i < 68; i++) {
crc = _crc16_update(crc, caldata[i]);
}
if (crc == 0) {
// data looks good, use it
writeCalibration1(caldata);
imu.writeCalibration(caldata);
calcount = 0;
loopcount = 10000;
ledFastblinks = 16; // Toggle LED faster the next 16 times
return;
}
// look for the 117,84 in the data, before discarding
for (i=2; i < 67; i++) {
if (caldata[i] == 117 && caldata[i+1] == 84) {
// found possible start within data
calcount = 68 - i;
memmove(caldata, caldata + i, calcount);
return;
}
}
// look for 117 in last byte
if (caldata[67] == 117) {
caldata[0] = 117;
calcount = 1;
} else {
calcount = 0;
}
}
}
bool writeCalibration1(const void *data)
{
const uint8_t *p = (const uint8_t *)data;
uint16_t crc;
uint8_t i;
if (p[0] != 117 || p[1] != 84) return false;
crc = 0xFFFF;
for (i=0; i < NXP_MOTION_CAL_SIZE; i++) {
crc = _crc16_update(crc, p[i]);
}
Serial1.print("Calibratrion Data CRC (s/b 0): ");
Serial1.println(crc);
if (crc != 0) return false;
for (i=0; i < NXP_MOTION_CAL_SIZE; i++) {
EEPROM.write(NXP_MOTION_CAL_EEADDR + i, p[i]);
}
for (i=0; i < NXP_MOTION_CAL_SIZE; i++) {
if (EEPROM.read(NXP_MOTION_CAL_EEADDR + i) != p[i]) return false;
}
//memcpy(cal, ((const uint8_t *)data)+2, sizeof(cal));
printCalibration();
return true;
}
void printCalibration(){
float offsets[9];
float softIron[9];
float fieldStrength;
int i, j;
Serial1.println("Calibration Data");
imu.getCalibration(offsets, softIron, &fieldStrength);
Serial1.println("Magnetic (Hard Iron) Offsets");
for (i=0; i<3; i++) {
printnum(offsets[i + 6], 2);
Serial1.println(" uT");
}
Serial1.println();
Serial1.println("Magnetic Soft Iron Mapping");
for (i=0; i<3; i++) {
for (j=0; j<3; j++) {
printnum(softIron[i*3+j], 4);
}
Serial1.println();
}
Serial1.println();
Serial1.println("Expected Magnetic Field Strength");
printnum(fieldStrength, 2);
Serial1.println(" uT");
Serial1.println();
Serial1.println("Accelerometer Offsets");
for (i=0; i<3; i++) {
printnum(offsets[i], 3);
Serial1.println(" g");
}
Serial1.println();
Serial1.println("Gyroscope Offsets");
for (i=0; i<3; i++) {
printnum(offsets[i + 3], 3);
Serial1.println(" degrees/sec");
}
Serial.println();
}
void printnum(float num, int digits) {
Serial1.print(" ");
if (num >= 0.0f) Serial.print(' ');
Serial1.print(num, digits);
}
Nice work on converting the sketch. Looks like it does a nice job of checking the EEPROM.I have been playing around a little more with the EEPROM mucking with and dump program to get an idea to make sure that pages are being properly redone when full...
Also added some reasonably simple code to mark in the dump which of the actual entries are the ones being used when you do a read * ...
Added a stupid loop that incremented 300-303 values looping 25 times (so 100 updates)...
Calibratrion Data CRC (s/b 0): 0
EEPROM READ:
Calibration Data
Magnetic (Hard Iron) Offsets
9.06 uT
-12.78 uT
67.74 uT
Magnetic Soft Iron Mapping
0.9668 -0.0200 0.0042
-0.0200 0.9961 -0.0084
0.0042 -0.0084 1.0388
Expected Magnetic Field Strength
39.45 uT
Calibratrion Data CRC (s/b 0): 0
EEPROM READ:
Data
Magnetic (Hard Iron) Offsets
8.87 uT
-13.62 uT
68.33 uT
Magnetic Soft Iron Mapping
0.9793 -0.0206 -0.0099
-0.0206 0.9955 0.0005
-0.0099 0.0005 1.0263
Expected Magnetic Field Strength
40.18 uT
// See this code in attached sketch … I suspect.
while ( !Serial.available() );
while ( Serial.available() ) {
Edit: Went back to those CAN NODE examples noted - they run fine between the T4B2m and final T4B3(?) ! Good thing. One has 120 ohm the new one does not - using a foot of cat5
I don't see the USB comm error with the IDE SerMon sending the chars - maybe it eats/ignore them or doesn't detect/trigger them the same - but err and disconnect does recur using TyComm as @mjs513 also reported IIRC.
while ( !Serial.available() );
while ( Serial.available() ) {
T:\tCode\T4\T4EEPROMgetput\T4EEPROMgetput.ino Jun 1 2019 15:37:11
EEPROM size EEPROM.length()=1080
lastWrote EEPROM address=6
+
PRIOR EEPROM address = 4
Using lastWrote EEPROM address=6
setup() sizeof( MyObject ) =19
_____- setup():: ZeroOffset value = 0