Forum Rule: Always post complete source code & details to reproduce any issue!
Page 124 of 151 FirstFirst ... 24 74 114 122 123 124 125 126 134 ... LastLast
Results 3,076 to 3,100 of 3771

Thread: Teensy 4.0 First Beta Test

  1. #3076
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,500
    @KurtE - thanks. Like testing with different things to check the libraries. Nice work on converting your EEPROM sketch. Figured you couldn't resist. Actually think it is useful to check the EEPROM.

  2. #3077
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    Paul: UART on Pins and Button to Bootloader T4 leaves no active sketch when repowered::

    Running sketch below on T4B2m :: NORMAL with NO UART pins powered
    1 >> While LED Blink, press 'Button' - properly goes to RedBootloader On/blink and LED_BUILTIN blink stops.
    2a >> Unplug T4 Device USB
    2b >> Press T4 POWER to OFF
    3 >> Repower T4 and the sketch runs

    Running sketch below on T4B2m :: EMPTY TEENSY with UART pins powered Serial 2 and 4 by two T_3.x's
    1 >> While LED Blink, press 'Button' - properly goes to RedBootloader ON/blink and LED_BUILTIN blink stops.
    or: 2a >> Unplug T4 Device USB
    or: 2b >> Press T4 POWER to OFF
    3 >> Repower T4 and the Teensy seems 'BLANK" - does not SerMon Connect - no RedBootloader LED
    4 >> Press button and T4 enters RedBootloader blink mode
    5 >> Repower T4 and the Teensy seems 'BLANK" - does not SerMon Connect - no RedBootloader LED
    6 >> Remove power from UART PINS
    7 >> Repower T4 and the sketch runs

    Code:
    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);
    }
    Last edited by defragster; 05-31-2019 at 06:22 PM. Reason: EDITED - Sketch still present w/no UART

  3. #3078
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    Updated Post #3077 above with added steps 6 and 7 returning to expected behavior! T4 was not blanked - but UART power held the

    I accidentally pushed Bootloader Button when intended POWER button and discovered this - while writing EEPROM test merging simple Put and Get examples - thought the EEprom code killed it … back to that code.

  4. #3079
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,500
    @defragster

    Merging put and get sketches - that's pretty much what I did in my EEPROM sketch along with Calculating CRC sketch.

    I just hooked up the exact same ORICO USB/Drive adapter that have to the Teensy and with nothing on the any of the Serial Pins with the Hub powered I am seeing about 1.25 volts on the Vin pin. This is with the T4B2m board. With T4B2m on with the hub attached and powered on/off works and little green lite goes off and stays off. With sermon open when I turn it back on the sketch resets and no problem and prints to the sermon

    EDIT: Take back what I just said. Just noticed if I have everything powered and disconnect the UBS cord the power stays on and the on/off switch works fine. Yet if I power up the hub without the USB cable connected the voltage on Vin stays at 1.26v or so and everything is off. Really strange. If you want the exact steps I used I will post them. Oh, the solder blob is still on the bottom of the chip, I didn't remove it.

  5. #3080
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    Mine is really convoluted of course - and it seems to work ...

    Run it and hit 'z' on first stop or this line is can be 'uncommented' to start, then comment and rerun :: // EEPROM.write( 0 , (uint32_t)sizeof(uint32_t) ); while(1); // USE THIS FOR FIRST RUN

    Then it runs a loop and waits for ENTER to increment and repeat … { or 'z' to reset to zero start }

    What is printed should only ever be ONE iteration behind on restarting - because it doesn't update the index entry until after keyboard input - then loop() re-runs and advances and prints.

    The MyObject struct was extended to hold the Address used in that iteration. It writes the float and the Object incrementing 24 bytes at a time.

    <edit> WORKS when Updated to allow 28 byte Struct to pack to 27, also the start point adjustable from byte 4 to 5,6,7.
    Code:
    #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 );
    }
    ** Note - results seem good on Beta 2 units - though some times it seems to go off the rails? More so when put on the B1 1052. Perhaps code is bad and I have an code errors from expanded the changing boundary edits.
    Last edited by defragster; 06-01-2019 at 12:22 AM.

  6. #3081
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    Paul: I'm seeing odd things that don't seem to be in my EEPROM test Loop() code … that I've seen yet.

    I have a Global variable not presenting an expected value?

    Is there any chance the CACHE / FIFO / (?) manipulations for the EEPROM operations are affecting Global or other sketch variable values?

    @mjs513 - can you post or github your eeprom sample - maybe I can see my trouble - or modify yours to the same point.

  7. #3082
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,500
    @defragster

    The sketch I used is in post #3062. If you are taking about one of the global variables in your structure are you sure you are moving the block sufficiently that when you do your get you are not overwriting it with a strange value from EEPROM?

  8. #3083
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    I'll look for your posting ...

    It seems as if … this variable P#3080 is showing strange numbers - it is used for EEPROM indexing:
    Code:
    unsigned int GeeAddress = ZeroOffset + sizeof(uint32_t); //EEPROM address to start reading from
    
    void setup() {
    It ends up in the MyObject.address and EEPROM[0] for restating where it left off.

  9. #3084
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,500
    @defragster

    Isn't that what you are telling it to do.

    Initially you have
    Code:
    ZeroOffset + sizeof(uint32_t);
    which would make the first address in the struct 4 which is what I am seeing. Now about line 60 you have
    Code:
    GeeAddress = ZeroOffset + sizeof(float);
    which is again 4 bytes - the same as sizeof(float) = 4 bytes. Unless you mean this is what you are getting:
    Code:
    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
    which actually confuses me more

    EDIT: Zeroed out eeprom at beginning of test just to avoid confusing it with test data. Now if I hit say 1 after Full eeprom:
    Code:
    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
    Which is correct to your sketch

    UPDATE: Played a little more but it looks like its working to me.

  10. #3085
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    Quote Originally Posted by mjs513 View Post
    @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.
    That is where the confusion lies … it is doing exactly what I tell it to do … and looks like it is working - and doing as expected … until … you hit Enter a couple more times.



    Per p# 3083 - The PACKED pragma is confusing something …
    Code:
    //#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
    Somehow - that plays size games dropping the 24 to 23 and perhaps the EEPROM code doesn't get the notice … it is overwriting the end of the GLOBAL Struct and trashing the GLOBAL things right after.

    I'm tied up a bit more - but if the value of "ZeroOffset " were printed when PACKED I think it will go a bit nuts? Unless the order has it trashing the GeeAddress - but that is already printed and looks good?

    I added the Zero Offset to allow the whole set of blocks to shift 0,1,2,3 bytes and force whatever boundaries I could in this test.

    Okay I tried that and it worked and worked a few loops through with altered ZeroOffsets - then it finally dies and it is not that value:
    Code:
    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
    _____- 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!
    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

  11. #3086
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    @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" ...

    @mjs513 - arrgH … after posted fail above I cam back and hit enter at least 200 times - used offsets 0,1,2 and 3 and did a couple reset restarts - and it is working perfectly again.

    I'm wondering if this is hitting an edge condition in EEPROM wrapping moving relocating page data ?

    Or if perhaps the earlier thought Post #3081 was right - but printing the variables for debug - is keeping them current across the EEPROM calls now?
    >> Is there any chance the CACHE / FIFO / (?) manipulations for the EEPROM operations are affecting Global or other sketch variable values?

    This was geared to be automated run through the bins and swap the offsets … but when I added packed and other things I kept manually testing and seeing issues …

    If only I hadn't hacked and broken debug_tt and not yet gotten back to it … I could put in asserts and logging for testing and trust it to stop

    I'll add a user key to dump the vars after the crash shows rather than continuously ...
    Last edited by defragster; 06-01-2019 at 07:09 AM.

  12. #3087
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    EEPROM seems good with this testing now? Not sure why the prior errors - maybe I accidentally cleaned up something?

    I reordered the output to use fewer lines and make status/errors stand out - status is great and errors are NONE :: on T4B2m, and seems the same good on T4B2
    _____- 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
    Same code uploads and back to Bootloader on T4B1 - then a reset runs only a couple before same error shows. Giving up that is okay.

    This has AUTORUN at top that counts down full passes through EEPROM, you can hit RESET on TyComm and it runs okay. It change 'Zero Offset' on each pass.

    Here is the code - one pass per 'Enter', 'd' to dump debug the index vars on error, 'r' restarts at first EEPROM location, when it is "FULL EEPROM" can also change offset [ 0,1,2,3 ]
    {input can be touchy - it dumps incoming before taking a key}
    Should work with reset/restart/Power Off/On - but only picks up right when left with '0' offset as I don't record what was in use.
    Code:
    #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 );
    }
    Last edited by defragster; 06-01-2019 at 08:24 AM.

  13. #3088
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,171
    Quote Originally Posted by defragster View Post
    Paul: UART on Pins and Button to Bootloader T4 leaves no active sketch when repowered::
    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?

  14. #3089
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,171
    Quote Originally Posted by defragster View Post
    >> Is there any chance the CACHE / FIFO / (?) manipulations for the EEPROM operations are affecting Global or other sketch variable values?.
    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.

  15. #3090
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    Quote Originally Posted by PaulStoffregen View Post
    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?
    Not only from Power OFF - same with USB cable pulled not touching Power button … It is parasitic VamPower from UART pins.

    {{ Note when I first saw it before I got it fixed I was sure that the CODE was somehow gone - when I found that workaround I added the final RED steps }}

    Once Program Button pressed the MCU enters 'that' state, and won't allow normal function until the unit fully powers down.

    T4 is not responsive to Upload after plugged back in - when UART power is maintained. And Windows doesn't like the device. But a Button Hold Plug in DOES return to Normal Red Light Bootloader RAWHID state.

    It will take Upload with another Program Button press, and returns to normal after program - or when all power is removed the prior code still runs.

    In this case the Button press was not intended to program.


    BTW: The Automated EEPROM code p#3087 is seeing the return of the failures where the Struct MyObject is corrupted. Will post better version that detects and stops better when caught … in some hours …
    What is printed shows it failed - Only clue to failure is 3 chars before 'W' in Working suggest it is using : ZeroOffset value = 0 where data is stored at ZeroOffset value = 3. But it writes before read and only changes that value at the start of a pass, not between write/read.
    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

  16. #3091
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    Quote Originally Posted by PaulStoffregen View Post
    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.
    Okay. These are normal - Globals - no attempt to cache or move elsewhere from DTCM. Just wanted to know there was no 'expectation' that the efforts to get proper data to EEPROM could be behind what it showing up.

    It is repro'ing more with the automated runs - so a pattern might point me to the issue in sketch. I have an idea but already late for Zzz's

  17. #3092
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,002
    Quote Originally Posted by mjs513 View Post
    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?
    Yes, I've been running with 1.8.8/1.47 beta2 and latest github cores. propshield with T3.2 and T3.6 are good with MotionCal on windows and macos, but i get no green check mark or EEPROM update with T4B2.
    So my latest try to find out what's going on is this mod to setup() in CalibrateSensors
    Code:
    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();
    }
    setup() turns LED on and then writes first 100 byte of EEPROM with the first byte of EEPROM + 1 and then turns the LED off and proceeds.

    1) if i have serial monitor hooked up, i see T4B2 LED on then off and then it starts streaming sensor data. if I then run sketch to examine EEPROM I see that first 100 bytes are +1 of their previous value. All is good.

    2) but if I have Serial monitor off and build CalibrateSensor for T4B2 and then I run MotionCal, I see LED on and then off after selecting port, and then i wiggle prop shield til MotionCal allows me to send calibration. I see fast flash LED, no green check. if i then run sketch to examine EEPROM, there has been no change to the EEPROM -- no new calibration data and the first 100 bytes weren't +1. ??? the EEPROM.write's are not happening when T4B2 is hooked to MotionCal

    Next is try building on another machine?

    EDIT: on linux64 1.8.9 with 1.47 beta 2 and latest github cores. problem still exists on T4B2 (T3.2 ok)
    Last edited by manitou; 06-01-2019 at 11:30 AM.

  18. #3093
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,500
    @manitou

    Thought of a test that you could do. Haven't tried it yet. Use a T3.2 to write values to the T4 EEPROM and/or try to enter values in through the serial monitor directly to the eeprom.

    EDIT: Was trying to use parseInt and parseFloat but didn't seem like they were working so here is something really crude and ugly for a quick test of writing from serial to EEPROM:
    Code:
    #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;
            }
        }
    }
    Last edited by mjs513; 06-01-2019 at 01:40 PM.

  19. #3094
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    4,898
    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)...
    Code:
    #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();
      }
    }
    Here is an output after I ran combination of commands to the point where the first page was almost full.

    Code:
    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
    And here is after I did an increment command which filled page and then rewrote it...
    Code:
    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
    Again maybe not very interesting, but does look like the code is probably working for erasing the page and condensing out the previous values.

  20. #3095
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    Quote Originally Posted by PaulStoffregen View Post


    I see lots of mention of the bootloader, but without the hardware here
    ...
    Paul - that one mention of 'Bootloader' was saying I have a sketch way of getting to bootloader. I was asking if there is a sketch way of doing a T4 Software Reset/Restart to get a clean entry to setup() ?

    @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" ...

  21. #3096
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,500
    @manitou
    I just did a modification of calibrateSensors.ino that writes the EEPROM from the calibrate sketch as well as output the results of get calibration from the nxpmotionsense library. This is what I get from the calibration sketch:
    Code:
    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
    This is what I get from running the PrintCalibration sketch:
    Code:
    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
    Definitely not the same. So now the problem is why?

    Anyway - put it together in case you wanted to play with one sketch to figure out EEPROM:
    Code:
    #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);
    }
    Last edited by mjs513; 06-01-2019 at 11:06 PM. Reason: mod to sketch

  22. #3097
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,500
    @KurtE
    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)...
    Nice work on converting the sketch. Looks like it does a nice job of checking the EEPROM.

  23. #3098
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,500
    @manitou
    One thing I noticed was I had to hit send cal a couple of times before it actually saved to the EEPROM even though both times I got the check (second data set matches):
    Code:
    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

  24. #3099
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    Starting with a Fresh T4 with no UART connects and no VBat power:

    Factory blink good, initial sketch upload no trouble. Hit Program - shows bootloader RED - then disconnect USB - and T4 starts normally when USB reconnected.

    First sketch was posted T4EEPROMgetput.ino and I forgot to validate first read data and it was out of bounds - opps - then it worked. No problem outside the user code.

    >> This is related to post #3077

    T4 on breakout with 2032 on VBat and NO UART connects - just USB to PC. With valid sketch loaded and running as it should :: BlinkRTC.ino.
    > Tap T4 Button - WIN USB chimes and RED LED lights then blinks
    > Disconnect USB to PC and WIN USB chimes
    > Plug USB to T4- - WIN USB Chimes Arrival
    -- Teensy is USB connected and running - with Setup Text messages and only 1 sec Blink in Loop()
    -- No problem here or in other sketches I tried - EEPROM Get and Put and I merged both into one sketch - and moved a copy into loop() and it restarts fines after the above. Also RTC sketch and put the same Serial input code in - all worked.

    The above is GOOD news, and what is below { +++++ } is all true and interesting - but I just PULLED the Battery - NO UARTS so no debug.
    This is something with USB to be fixed ? - With how it gets in an odd mode with button then repower.
    So it is a Final_Beta breakout T4 with only USB connected:
    >> Running this code:: T4EEPROMgetput.ino
    >> Press 'Button'
    >> Pull USB cable
    >> Plug USB cable
    >> Code starts prints lines then does first EEPROM test and goes to while(!Serial.available())
    >> … Pull and replug USB and it repeats
    >> To resolve press button and reprogram _or_ press button and hit TyComm GUI Reset.
    Note: It acts the same with VBat powered - and probably UARTS so it could work with Serial4 for Debug output
    Note: Tried a half dozen other sketches and moved similar code in and around and they do not do it
    Note: As noted the 'Flexcan_sdk4_NodeA' and 'Flexcan_sdk4_NodeB' were the sketches the other week [when Beta2 board shipped with @mjs513] that showed the same USB failure waiting for input AFAIK - without steps above.

    >> Takes ONE Enter from USB - then USB is in bad state.
    This code has had thousands of 'Enter' keys processed and many dozens of restart/repower and until I ACCIDENTALLY pressed the button one time reaching for POWER it never did this.

    REPRO also with IDE 1.8.9: : TeensyDuino 1.8.7. with github Cores from recent days with fix for last USB issue.
    > Load above sketch and upload, it runs
    > Open SerMon SEND many enter and it works (state of EEProm is system dependent - hit: z, enter, r, enter and restart sketch if needed)
    > Take TeensyLoader out of AUTO mode
    > Press Button
    > Pull USB and replug USB
    > Send Enter with SerMon, Only the First works
    --- Put TeensyLoader back in Auto Mode
    > Attempt Upload from IDE - FAILS

    But adding prints and leaving 10 times each print and then it does first EEPROM pass then seems to be sticking related to this - which may be common to the CAN example - but this normally works except after pushbutton:
    Code:
      // See this code in attached sketch … I suspect.
      while ( !Serial.available() );
      while ( Serial.available() ) {
    +++++ - more details with battery - but repro above without battery.
    Though with sketch post #3087 above: T4EEPROMgetput.ino
    It has to be something unique to this sketch - but I haven't found it ...
    T4 on breakout with 2032 on VBat and NO UART connects - just USB to PC. With valid sketch loaded and running as it should :: BlinkRTC.ino.
    > Tap T4 Button - WIN USB chimes and RED LED lights then blinks
    > Disconnect USB to PC and WIN USB chimes
    > Plug USB to T4- - WIN USB Chimes Arrival
    -- Teensy connects and passes setup() then halts after setup with no sign of making it to loop().
    >> It does go to Bootloader mode on Button, And on Button hold on plugging in
    >> Unplugging and replugging USB shows the same NO LOOP() behavior on next start?
    >> Unplugging and removing battery and holding both buttons some time - same No Loop() behavior
    Workarounds found - with button press to Bootloader
    #1: Reprogram from PC
    #2: Issue TyComm GUI Reset

    NOTE:
    - this the EEPROM test code - and what it is doing seems to have something to do with it.
    - Also note - TyComm messages: " Board '5889290-Teensy' is busy on task 'send@5889290-Teensy' " and " [send@5889290-Teensy] I/O error while writing to '\\.\COM30' "
    trying to send USB to T4 in this state - the same message that showed on the twin CAN test the other week. @mjs513 and I both saw this from TyComm
    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.
    It halts before first entry to loop() as written above - is non responsive to USB Serial input - and doing that makes TyComm complain about the USB device.
    But adding prints and leaving 10 times each print and then it does first EEPROM pass then seems to be sticking related to this - which may be common to the CAN example - but this normally works except after pushbutton:
    Code:
      while ( !Serial.available() );
      while ( Serial.available() ) {
    Code:
    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
    Last edited by defragster; 06-02-2019 at 06:20 AM. Reason: Added IDE repro notes - I was using TyComm

  25. #3100
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,825
    @Paul: TeensyDuino About shows Copyright 2018.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •