PaulStoffregen
Well-known member
I was asking if there is a sketch way of doing a T4 Software Reset/Restart to get a clean entry to setup() ?
Sure. Use AIRCR, just like on all other 32 bit ARM.
I was asking if there is a sketch way of doing a T4 Software Reset/Restart to get a clean entry to setup() ?
This is going away. The replacement is one of many little things I meant to do before we started this beta, but didn't finish in time.
To answer the original question, the Arduino IDE creates this for us, so we can always get the compile time even if none of the core library files needed to be recompiled. It does into the final liner command.
For Teensy 4, I'm going to add a bootloader command to set the RTC, and add support in Teensy Loader to always do this as the final step. Then we won't need to depend on Arduino giving this special symbol, and non-Arduino build systems won't have to replicate this special feature. We can also get rid of the complicated startup code that tries to guess if the RTC setting is "fresh" vs "stale". It should also help solve the minor offset between Arduino running the linker and when the code finally boots up and sets the RTC.
#include <EEPROM.h>
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(13, OUTPUT);
Serial.printf("byte 0 %d\n", EEPROM.read(0));
}
void loop() {
uint8_t b;
if (Serial.available()) {
b = Serial.read();
EEPROM.write(0, b);
Serial.printf("input %d byte 0 %d\n", b, EEPROM.read(0));
while (!Serial.available()) {
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
delay(200);
}
}
}
Re: NXPMotionSense and EEPROM
OK, here is the simplest example. It doesn't have anything to do with CalibrateSensors and MotionalCal.
...
if you build and run this sketch and enter in a character, EEPROM byte 0 is updated for each character you enter. good
now unplug T4B2 USB cable and plug it back in. Now when you type a character, EEPROM is no longer updated!?!?
if you push reprogram button, all will work again.
(I was seeing this with MagCal, because I was building CalibrateSensors on machine different from where I was running MagCal, and was unplugging T4B2 to switch machines ...)
[reset@5889290-Teensy] Resetting board '5889290-Teensy' (Teensy 4.0)
[reset@5889290-Teensy] Sending reset command
Received removal notification for device 'HID\VID_16C0&PID_0478\7&206FFD9D&0&0000'
Remove device 'HID\VID_16C0&PID_0478\7&206FFD9D&0&0000'
Received removal notification for device 'USB\VID_16C0&PID_0478\0008FC81'
Received arrival notification for device 'USB\VID_16C0&PID_0483\5889290'
Examining device node 'USB\VID_16C0&PID_0483\5889290'
Found port number of 'USB\VID_16C0&PID_0483\5889290': 7
Found port number of 'USB\VID_1A40&PID_0201\5&38BA1A52&0&8': 8
Found controller ID for 'USB\ROOT_HUB30\4&362721B3&0&0': 1
Add serial device 'USB\VID_16C0&PID_0483\5889290' on iface 0
- USB VID/PID = 16c0:0483, USB location = usb-1-8-7
- USB manufacturer = Teensyduino, product = USB Serial, S/N = 5889290
Identified 'Teensy 4.0' with bcdDevice value 0x279
Received arrival notification for device 'USB\VID_16C0&PID_0483\5889290'
Examining device node 'USB\VID_16C0&PID_0483\5889290'
Found port number of 'USB\VID_16C0&PID_0483\5889290': 7
Found port number of 'USB\VID_1A40&PID_0201\5&38BA1A52&0&8': 8
Found controller ID for 'USB\ROOT_HUB30\4&362721B3&0&0': 1
Received removal notification for device 'USB\VID_16C0&PID_0483\5889290'
Remove device 'USB\VID_16C0&PID_0483\5889290'
Received removal notification for device 'USB\VID_16C0&PID_0483\5889290'
Received arrival notification for device 'USB\VID_16C0&PID_0483\5889290'
Examining device node 'USB\VID_16C0&PID_0483\5889290'
Found port number of 'USB\VID_16C0&PID_0483\5889290': 7
Found port number of 'USB\VID_1A40&PID_0201\5&38BA1A52&0&8': 8
Found controller ID for 'USB\ROOT_HUB30\4&362721B3&0&0': 1
Add serial device 'USB\VID_16C0&PID_0483\5889290' on iface 0
- USB VID/PID = 16c0:0483, USB location = usb-1-8-7
- USB manufacturer = Teensyduino, product = USB Serial, S/N = 5889290
Identified 'Teensy 4.0' with bcdDevice value 0x279
Received arrival notification for device 'USB\VID_16C0&PID_0483\5889290'
Examining device node 'USB\VID_16C0&PID_0483\5889290'
Found port number of 'USB\VID_16C0&PID_0483\5889290': 7
Found port number of 'USB\VID_1A40&PID_0201\5&38BA1A52&0&8': 8
Found controller ID for 'USB\ROOT_HUB30\4&362721B3&0&0': 1
[send@5889290-Teensy] Timed out while writing to '\\.\COM30'
#include <EEPROM.h>
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
pinMode(13, OUTPUT);
Serial.printf("byte 0 %d\n", EEPROM.read(0));
}
void loop() {
uint8_t b;
if (Serial.available()) {
b = Serial.read();
EEPROM.write(0, b); [COLOR="#FF0000"]// COMMENT this line and the problem does not happen[/COLOR]
Serial.printf("input %d byte 0 %d\n", b, EEPROM.read(0));
while (Serial.available())
Serial.read();
while (!Serial.available()) {
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
delay(200);
}
}
}
Sure. Use AIRCR, just like on all other 32 bit ARM.
void KIN1_SoftwareReset(void)
{
/* Generic way to request a reset from software for ARM Cortex */
/* See https://community.freescale.com/thread/99740
To write to this register, you must write 0x5FA to the VECTKEY field, otherwise the processor ignores the write.
SYSRESETREQ will cause a system reset asynchronously, so need to wait afterwards.
*/
#if KIN1_IS_USING_KINETIS_SDK
SCB_AIRCR = (0x5FA<<SCB_AIRCR_VECTKEY_Pos)|SCB_AIRCR_SYSRESETREQ_Msk;
#else
SCB_AIRCR = SCB_AIRCR_VECTKEY(0x5FA) | SCB_AIRCR_SYSRESETREQ_MASK;
#endif
for(;;) {
/* wait until reset */
}
}
Re: NXPMotionSense and EEPROM
OK, here is the simplest example. It doesn't have anything to do with CalibrateSensors and MotionalCal.
…….
if you build and run this sketch and enter in a character, EEPROM byte 0 is updated for each character you enter. good
now unplug T4B2 USB cable and plug it back in. Now when you type a character, EEPROM is no longer updated!?!?
if you push reprogram button, all will work again.
(I was seeing this with MotionCal, because I was building CalibrateSensors on machine different from where I was running MotionCal, and was unplugging T4B2 to switch machines ...)
Tested with T4B2 1.8.8/1.47 beta2 with latest github cores and with IDE serial monitor. also tested with 1.8.9
#include <EEPROM.h>
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(13, OUTPUT);
Serial.printf("byte 0 %d\n", EEPROM.read(0));
}
void loop() {
uint8_t b;
if (Serial.available()) {
b = Serial.read();
if (b == 'd') {
dump_eeprom();
} else {
EEPROM.write(0, b);
Serial.printf("input %d byte 0 %d\n", b, EEPROM.read(0));
}
while (Serial.available()) {
Serial.read();
}
while (!Serial.available()) {
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
delay(200);
}
}
}
#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);
eeprom_size = 256; // BUGBUG limit for this test.
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 < 1 /*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();
}
}
byte 0 120
input 89 byte 0 89
EEPROM length: 1080
Contents:
0:59 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 a:a b:b c:c d:d e:e f:f
10:10 11:11 12:12 13:13 14:14 15:15 16:16 17:17 18:18 19:19 1a:1a 1b:1b 1c:1c 1d:1d 1e:1e 1f:1f
20:20 21:21 22:22 23:23 24:24 25:25 26:26 27:27 28:28 29:29 2a:2a 2b:2b 2c:2c 2d:2d 2e:2e 2f:2f
30:30 31:31 32:32 33:33 34:34 35:35 36:36 37:37 38:38 39:39 3a:3a 3b:3b 3c:3c 3d:3d 3e:3e 3f:3f
40:40 41:41 42:42 43:43 44:44 45:45 46:46 47:47 48:48 49:49 4a:4a 4b:4b 4c:4c 4d:4d 4e:4e 4f:4f
50:50 51:51 52:52 53:53 54:54 55:55 56:56 57:57 58:58 59:59 5a:5a 5b:5b 5c:5c 5d:5d 5e:5e 5f:5f
60:60 61:61 62:62 63:63 64:64 65:65 66:66 67:67 68:68 69:69 6a:6a 6b:6b 6c:6c 6d:6d 6e:6e 6f:6f
70:70 71:71 72:72 73:73 74:74 75:75 76:76 77:77 78:78 79:79 7a:7a 7b:7b 7c:7c 7d:7d 7e:7e 7f:7f
80:80 81:81 82:82 83:83 84:84 85:85 86:86 87:87 88:88 89:89 8a:8a 8b:8b 8c:8c 8d:8d 8e:8e 8f:8f
90:90 91:91 92:92 93:93 94:94 95:95 96:96 97:97 98:98 99:99 9a:9a 9b:9b 9c:9c 9d:9d 9e:9e 9f:9f
a0:a0 a1:a1 a2:a2 a3:a3 a4:a4 a5:a5 a6:a6 a7:a7 a8:a8 a9:a9 aa:aa ab:ab ac:ac ad:ad ae:ae af:af
b0:b0 b1:b1 b2:b2 b3:b3 b4:b4 b5:b5 b6:b6 b7:b7 b8:b8 b9:b9 ba:ba bb:bb bc:bc bd:bd be:be bf:bf
c0:c0 c1:c1 c2:c2 c3:c3 c4:c4 c5:c5 c6:c6 c7:c7 c8:c8 c9:c9 ca:ca cb:cb cc:cc cd:cd ce:ce cf:cf
d0:d0 d1:d1 d2:d2 d3:d3 d4:d4 d5:d5 d6:d6 d7:d7 d8:d8 d9:d9 da:da db:db dc:dc dd:dd de:de df:df
e0:e0 e1:e1 e2:e2 e3:e3 e4:e4 e5:e5 e6:e6 e7:e7 e8:e8 e9:e9 ea:ea eb:eb ec:ec ed:ed ee:ee ef:ef
f0:f0 f1:f1 f2:f2 f3:f3 f4:f4 f5:f5 f6:f6 f7:f7 f8:f8 f9:f9 fa:fa fb:fb fc:fc fd:fd fe:fe ff:ff
Raw Data
EEprom Page:0 addresses(601f0000 - 601f1000): first free: 601f006e
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 000(00)=78 000(00)=0d 000(00)=79 000(00)=0d 000(00)=00 *001(01)=01 *002(02)=02
*003(03)=03 *060(04)=3c *061(05)=3d *062(06)=3e *063(07)=3f *120(08)=78 *121(09)=79 *122(0a)=7a *123(0b)=7b *180(0c)=b4 *181(0d)=b5 *182(0e)=b6 *183(0f)=b7 *240(10)=f0 *241(11)=f1 *242(12)=f2
*243(13)=f3 000(00)=78 000(00)=0d 000(00)=78 000(00)=0d 000(00)=78 *000(00)=59
CCM_CCGR6: fcff3fc3 CCM_CCGR7: ffffffff
byte 0 49
input 50 byte 0 50
EEPROM length: 1080
Contents:
0:32 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 a:a b:b c:c d:d e:e f:f
10:10 11:11 12:12 13:13 14:14 15:15 16:16 17:17 18:18 19:19 1a:1a 1b:1b 1c:1c 1d:1d 1e:1e 1f:1f
20:20 21:21 22:22 23:23 24:24 25:25 26:26 27:27 28:28 29:29 2a:2a 2b:2b 2c:2c 2d:2d 2e:2e 2f:2f
30:30 31:31 32:32 33:33 34:34 35:35 36:36 37:37 38:38 39:39 3a:3a 3b:3b 3c:3c 3d:3d 3e:3e 3f:3f
40:40 41:41 42:42 43:43 44:44 45:45 46:46 47:47 48:48 49:49 4a:4a 4b:4b 4c:4c 4d:4d 4e:4e 4f:4f
50:50 51:51 52:52 53:53 54:54 55:55 56:56 57:57 58:58 59:59 5a:5a 5b:5b 5c:5c 5d:5d 5e:5e 5f:5f
60:60 61:61 62:62 63:63 64:64 65:65 66:66 67:67 68:68 69:69 6a:6a 6b:6b 6c:6c 6d:6d 6e:6e 6f:6f
70:70 71:71 72:72 73:73 74:74 75:75 76:76 77:77 78:78 79:79 7a:7a 7b:7b 7c:7c 7d:7d 7e:7e 7f:7f
80:80 81:81 82:82 83:83 84:84 85:85 86:86 87:87 88:88 89:89 8a:8a 8b:8b 8c:8c 8d:8d 8e:8e 8f:8f
90:90 91:91 92:92 93:93 94:94 95:95 96:96 97:97 98:98 99:99 9a:9a 9b:9b 9c:9c 9d:9d 9e:9e 9f:9f
a0:a0 a1:a1 a2:a2 a3:a3 a4:a4 a5:a5 a6:a6 a7:a7 a8:a8 a9:a9 aa:aa ab:ab ac:ac ad:ad ae:ae af:af
b0:b0 b1:b1 b2:b2 b3:b3 b4:b4 b5:b5 b6:b6 b7:b7 b8:b8 b9:b9 ba:ba bb:bb bc:bc bd:bd be:be bf:bf
c0:c0 c1:c1 c2:c2 c3:c3 c4:c4 c5:c5 c6:c6 c7:c7 c8:c8 c9:c9 ca:ca cb:cb cc:cc cd:cd ce:ce cf:cf
d0:d0 d1:d1 d2:d2 d3:d3 d4:d4 d5:d5 d6:d6 d7:d7 d8:d8 d9:d9 da:da db:db dc:dc dd:dd de:de df:df
e0:e0 e1:e1 e2:e2 e3:e3 e4:e4 e5:e5 e6:e6 e7:e7 e8:e8 e9:e9 ea:ea eb:eb ec:ec ed:ed ee:ee ef:ef
f0:f0 f1:f1 f2:f2 f3:f3 f4:f4 f5:f5 f6:f6 f7:f7 f8:f8 f9:f9 fa:fa fb:fb fc:fc fd:fd fe:fe ff:ff
Raw Data
EEprom Page:0 addresses(601f0000 - 601f1000): first free: 601f0072
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 000(00)=78 000(00)=0d 000(00)=79 000(00)=0d 000(00)=00 *001(01)=01 *002(02)=02
*003(03)=03 *060(04)=3c *061(05)=3d *062(06)=3e *063(07)=3f *120(08)=78 *121(09)=79 *122(0a)=7a *123(0b)=7b *180(0c)=b4 *181(0d)=b5 *182(0e)=b6 *183(0f)=b7 *240(10)=f0 *241(11)=f1 *242(12)=f2
*243(13)=f3 000(00)=78 000(00)=0d 000(00)=78 000(00)=0d 000(00)=78 000(00)=59 000(00)=31 *000(00)=32
CCM_CCGR6: fcff3fc3 CCM_CCGR7: ffffffff
byte 0 50
EEPROM length: 1080
Contents:
0:32 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 a:a b:b c:c d:d e:e f:f
10:10 11:11 12:12 13:13 14:14 15:15 16:16 17:17 18:18 19:19 1a:1a 1b:1b 1c:1c 1d:1d 1e:1e 1f:1f
20:20 21:21 22:22 23:23 24:24 25:25 26:26 27:27 28:28 29:29 2a:2a 2b:2b 2c:2c 2d:2d 2e:2e 2f:2f
30:30 31:31 32:32 33:33 34:34 35:35 36:36 37:37 38:38 39:39 3a:3a 3b:3b 3c:3c 3d:3d 3e:3e 3f:3f
40:40 41:41 42:42 43:43 44:44 45:45 46:46 47:47 48:48 49:49 4a:4a 4b:4b 4c:4c 4d:4d 4e:4e 4f:4f
50:50 51:51 52:52 53:53 54:54 55:55 56:56 57:57 58:58 59:59 5a:5a 5b:5b 5c:5c 5d:5d 5e:5e 5f:5f
60:60 61:61 62:62 63:63 64:64 65:65 66:66 67:67 68:68 69:69 6a:6a 6b:6b 6c:6c 6d:6d 6e:6e 6f:6f
70:70 71:71 72:72 73:73 74:74 75:75 76:76 77:77 78:78 79:79 7a:7a 7b:7b 7c:7c 7d:7d 7e:7e 7f:7f
80:80 81:81 82:82 83:83 84:84 85:85 86:86 87:87 88:88 89:89 8a:8a 8b:8b 8c:8c 8d:8d 8e:8e 8f:8f
90:90 91:91 92:92 93:93 94:94 95:95 96:96 97:97 98:98 99:99 9a:9a 9b:9b 9c:9c 9d:9d 9e:9e 9f:9f
a0:a0 a1:a1 a2:a2 a3:a3 a4:a4 a5:a5 a6:a6 a7:a7 a8:a8 a9:a9 aa:aa ab:ab ac:ac ad:ad ae:ae af:af
b0:b0 b1:b1 b2:b2 b3:b3 b4:b4 b5:b5 b6:b6 b7:b7 b8:b8 b9:b9 ba:ba bb:bb bc:bc bd:bd be:be bf:bf
c0:c0 c1:c1 c2:c2 c3:c3 c4:c4 c5:c5 c6:c6 c7:c7 c8:c8 c9:c9 ca:ca cb:cb cc:cc cd:cd ce:ce cf:cf
d0:d0 d1:d1 d2:d2 d3:d3 d4:d4 d5:d5 d6:d6 d7:d7 d8:d8 d9:d9 da:da db:db dc:dc dd:dd de:de df:df
e0:e0 e1:e1 e2:e2 e3:e3 e4:e4 e5:e5 e6:e6 e7:e7 e8:e8 e9:e9 ea:ea eb:eb ec:ec ed:ed ee:ee ef:ef
f0:f0 f1:f1 f2:f2 f3:f3 f4:f4 f5:f5 f6:f6 f7:f7 f8:f8 f9:f9 fa:fa fb:fb fc:fc fd:fd fe:fe ff:ff
Raw Data
EEprom Page:0 addresses(601f0000 - 601f1000): first free: 601f0072
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 000(00)=78 000(00)=0d 000(00)=79 000(00)=0d 000(00)=00 *001(01)=01 *002(02)=02
*003(03)=03 *060(04)=3c *061(05)=3d *062(06)=3e *063(07)=3f *120(08)=78 *121(09)=79 *122(0a)=7a *123(0b)=7b *180(0c)=b4 *181(0d)=b5 *182(0e)=b6 *183(0f)=b7 *240(10)=f0 *241(11)=f1 *242(12)=f2
*243(13)=f3 000(00)=78 000(00)=0d 000(00)=78 000(00)=0d 000(00)=78 000(00)=59 000(00)=31 *000(00)=32
[COLOR="#FF0000"]input 51 byte 0 50[/COLOR]
EEPROM length: 1080
Contents:
0:32 1:1 2:2 3:3 4:4 5:5 6:6 7:7 8:8 9:9 a:a b:b c:c d:d e:e f:f
10:10 11:11 12:12 13:13 14:14 15:15 16:16 17:17 18:18 19:19 1a:1a 1b:1b 1c:1c 1d:1d 1e:1e 1f:1f
20:20 21:21 22:22 23:23 24:24 25:25 26:26 27:27 28:28 29:29 2a:2a 2b:2b 2c:2c 2d:2d 2e:2e 2f:2f
30:30 31:31 32:32 33:33 34:34 35:35 36:36 37:37 38:38 39:39 3a:3a 3b:3b 3c:3c 3d:3d 3e:3e 3f:3f
40:40 41:41 42:42 43:43 44:44 45:45 46:46 47:47 48:48 49:49 4a:4a 4b:4b 4c:4c 4d:4d 4e:4e 4f:4f
50:50 51:51 52:52 53:53 54:54 55:55 56:56 57:57 58:58 59:59 5a:5a 5b:5b 5c:5c 5d:5d 5e:5e 5f:5f
60:60 61:61 62:62 63:63 64:64 65:65 66:66 67:67 68:68 69:69 6a:6a 6b:6b 6c:6c 6d:6d 6e:6e 6f:6f
70:70 71:71 72:72 73:73 74:74 75:75 76:76 77:77 78:78 79:79 7a:7a 7b:7b 7c:7c 7d:7d 7e:7e 7f:7f
80:80 81:81 82:82 83:83 84:84 85:85 86:86 87:87 88:88 89:89 8a:8a 8b:8b 8c:8c 8d:8d 8e:8e 8f:8f
90:90 91:91 92:92 93:93 94:94 95:95 96:96 97:97 98:98 99:99 9a:9a 9b:9b 9c:9c 9d:9d 9e:9e 9f:9f
a0:a0 a1:a1 a2:a2 a3:a3 a4:a4 a5:a5 a6:a6 a7:a7 a8:a8 a9:a9 aa:aa ab:ab ac:ac ad:ad ae:ae af:af
b0:b0 b1:b1 b2:b2 b3:b3 b4:b4 b5:b5 b6:b6 b7:b7 b8:b8 b9:b9 ba:ba bb:bb bc:bc bd:bd be:be bf:bf
c0:c0 c1:c1 c2:c2 c3:c3 c4:c4 c5:c5 c6:c6 c7:c7 c8:c8 c9:c9 ca:ca cb:cb cc:cc cd:cd ce:ce cf:cf
d0:d0 d1:d1 d2:d2 d3:d3 d4:d4 d5:d5 d6:d6 d7:d7 d8:d8 d9:d9 da:da db:db dc:dc dd:dd de:de df:df
e0:e0 e1:e1 e2:e2 e3:e3 e4:e4 e5:e5 e6:e6 e7:e7 e8:e8 e9:e9 ea:ea eb:eb ec:ec ed:ed ee:ee ef:ef
f0:f0 f1:f1 f2:f2 f3:f3 f4:f4 f5:f5 f6:f6 f7:f7 f8:f8 f9:f9 fa:fa fb:fb fc:fc fd:fd fe:fe ff:ff
Raw Data
EEprom Page:0 addresses(601f0000 - 601f1000): first free: 601f0072
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 000(00)=78 000(00)=0d 000(00)=79 000(00)=0d 000(00)=00 *001(01)=01 *002(02)=02
*003(03)=03 *060(04)=3c *061(05)=3d *062(06)=3e *063(07)=3f *120(08)=78 *121(09)=79 *122(0a)=7a *123(0b)=7b *180(0c)=b4 *181(0d)=b5 *182(0e)=b6 *183(0f)=b7 *240(10)=f0 *241(11)=f1 *242(12)=f2
*243(13)=f3 000(00)=78 000(00)=0d 000(00)=78 000(00)=0d 000(00)=78 000(00)=59 000(00)=31 *000(00)=32
static void flash_wait()
{
digitalWriteFast(8, HIGH);
FLEXSPI_LUT60 = LUT0(CMD_SDR, PINS1, 0x05) | LUT1(READ_SDR, PINS1, 1); // 05 = read status
FLEXSPI_LUT61 = 0;
uint8_t status;
do {
FLEXSPI_IPRXFCR = FLEXSPI_IPRXFCR_CLRIPRXF; // clear rx fifo
FLEXSPI_IPCR0 = 0;
FLEXSPI_IPCR1 = FLEXSPI_IPCR1_ISEQID(15) | FLEXSPI_IPCR1_IDATSZ(1);
FLEXSPI_IPCMD = FLEXSPI_IPCMD_TRG;
digitalWriteFast(7, HIGH);
while (!(FLEXSPI_INTR & FLEXSPI_INTR_IPCMDDONE)) {
asm("nop");
}
digitalWriteFast(7, LOW);
FLEXSPI_INTR = FLEXSPI_INTR_IPCMDDONE;
status = *(uint8_t *)&FLEXSPI_RFDR0;
[COLOR="#FF0000"]} while (status & 1);[/COLOR]
FLEXSPI_MCR0 |= FLEXSPI_MCR0_SWRESET; // purge stale data from FlexSPI's AHB FIFO
while (FLEXSPI_MCR0 & FLEXSPI_MCR0_SWRESET) ; // wait
__enable_irq();
digitalWriteFast(8, LOW);
}
do {
if (loop_count++ > 1000) {
__enable_irq();
printf("flash_wait timeout %x %x\n", FLEXSPI_INTR, FLEXSPI_RFDR0);
__disable_irq();
break;
}
CCM_CCGR6: fcff3fc3 CCM_CCGR7: ffffffff
byte 0 97
FLEXSPI MCR0:ffff8010 MCR1:7736ffff MCR2:200001f7 AHBCR:78 INTEN:0 INTR:40 RFDR0:7772db4b
FLEXSPI MCR0:ffff8010 MCR1:7736ffff MCR2:200001f7 AHBCR:78 INTEN:0 INTR:40 RFDR0:7772db4b
input 98 byte 0 9
CCM_CCGR6: fcff3fc3 CCM_CCGR7: ffffffff
byte 0 97
FLEXSPI MCR0:ffff8010 MCR1:7736ffff MCR2:200001f7 AHBCR:78 INTEN:0 INTR:40 RFDR0:55
FLEXSPI MCR0:ffff8010 MCR1:7736ffff MCR2:200001f7 AHBCR:78 INTEN:0 INTR:40 RFDR0:44
input 99 byte 0 99
__attribute__ ((section(".flashconfig"), used))
uint32_t FlexSPI_NOR_Config[128] = {
// 448 byte common FlexSPI configuration block, 8.6.3.1 page 223 (RT1060 rev 0)
// MCU_Flashloader_Reference_Manual.pdf, 8.2.1, Table 8-2, page 72-75
0x42464346, // Tag 0x00
0x56010000, // Version
0, // reserved
0x00020101, // columnAdressWidth,dataSetupTime,dataHoldTime,readSampleClkSrc
0x00000000, // waitTimeCfgCommands,-,deviceModeCfgEnable
...
@manitou, @KurtEthis is way above my pay grade, but status = *(uint8_t *)&FLEXSPI_RFDR0; seems a strange "status" register, since manual says RFDR0 is 32-bits of data from RX FIFO ???
I have not seen a hang in my experiments.
So a program load (build or push re-program button) is going to write to the flash whereas a cycle-power won't involve a flash write. so EEPROM emulation needs something that reprogramming is doing. As Kurt suggests, studying the bootloader actions may be insightful.
SECTIONS
{
.text.progmem : {
KEEP(*(.flashconfig))
FILL(0xFF)
. = ORIGIN(FLASH) + 0x1000;
KEEP(*(.ivt))
KEEP(*(.bootdata))
KEEP(*(.vectors))
KEEP(*(.startup)) …...
#include <EEPROM.h>
void setup() {
Serial.begin(9600);
Serial4.begin(115200);
pinMode(7, OUTPUT); digitalWrite(7, LOW);
pinMode(8, OUTPUT); digitalWrite(8, LOW);
while (!Serial);
pinMode(13, OUTPUT);
delay(50);
Serial.printf("CCM_CCGR6: %x CCM_CCGR7: %x\n", CCM_CCGR6, CCM_CCGR7);
Serial.printf("byte 0 %d\n", EEPROM.read(0));
Serial.printf("FLEXSPI MCR0:%x MCR1:%x MCR2:%x AHBCR:%x INTEN:%x INTR:%x RFDR0:%x\n",
FLEXSPI_MCR0, FLEXSPI_MCR1, FLEXSPI_MCR2, FLEXSPI_AHBCR, FLEXSPI_INTEN, FLEXSPI_INTR, FLEXSPI_RFDR0);
Serial.printf(" LUT60:%x LUT61:%x LUT62:%x LUT63:%x\n", FLEXSPI_LUT60, FLEXSPI_LUT61, FLEXSPI_LUT62, FLEXSPI_LUT63);
}
void loop() {
uint8_t b;
if (Serial.available()) {
b = Serial.read();
if (b == 'd') {
dump_eeprom();
} else {
EEPROM.write(0, b);
Serial.printf("FLEXSPI MCR0:%x MCR1:%x MCR2:%x AHBCR:%x INTEN:%x INTR:%x RFDR0:%x\n",
FLEXSPI_MCR0, FLEXSPI_MCR1, FLEXSPI_MCR2, FLEXSPI_AHBCR, FLEXSPI_INTEN, FLEXSPI_INTR, FLEXSPI_RFDR0);
Serial.printf(" LUT60:%x LUT61:%x LUT62:%x LUT63:%x\n", FLEXSPI_LUT60, FLEXSPI_LUT61, FLEXSPI_LUT62, FLEXSPI_LUT63);
Serial.printf("input %d byte 0 %d\n", b, EEPROM.read(0));
}
while (Serial.available()) {
Serial.read();
}
while (!Serial.available()) {
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
delay(200);
}
}
}
#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);
eeprom_size = 256; // BUGBUG limit for this test.
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 < 1 /*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);
const 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();
}
}
CCM_CCGR6: fcff3fc3 CCM_CCGR7: ffffffff
byte 0 99
FLEXSPI MCR0:ffff8010 MCR1:7736ffff MCR2:200001f7 AHBCR:78 INTEN:0 INTR:40 RFDR0:55
LUT60:2601069f LUT61:0 LUT62:0 LUT63:0
FLEXSPI MCR0:ffff8010 MCR1:7736ffff MCR2:200001f7 AHBCR:78 INTEN:0 INTR:40 RFDR0:44
LUT60:24010405 LUT61:0 LUT62:0 LUT63:0
input 49 byte 0 49
CCM_CCGR6: fcff3fc3 CCM_CCGR7: ffffffff
byte 0 49
FLEXSPI MCR0:ffff8010 MCR1:7736ffff MCR2:200001f7 AHBCR:78 INTEN:0 INTR:40 RFDR0:7772df43
LUT60:64bd3240 LUT61:d292adfc LUT62:14f89264 LUT63:65f453b
FLEXSPI MCR0:ffff8010 MCR1:7736ffff MCR2:200001f7 AHBCR:78 INTEN:0 INTR:40 RFDR0:7772df43
LUT60:24010405 LUT61:0 LUT62:14f89264 LUT63:65f453b
input 50 byte 0 49
static void flash_wait()
{
digitalWriteFast(8, HIGH);
uint16_t loop_count = 0;
FLEXSPI_LUT60 = LUT0(CMD_SDR, PINS1, 0x05) | LUT1(READ_SDR, PINS1, 1); // 05 = read status
FLEXSPI_LUT61 = 0;
uint8_t status;
do {
if (loop_count++ > 1000) {
__enable_irq();
printf("flash_wait timeout %x %x\n", FLEXSPI_INTR, FLEXSPI_RFDR0);
__disable_irq();
break;
}
FLEXSPI_IPRXFCR = FLEXSPI_IPRXFCR_CLRIPRXF; // clear rx fifo
FLEXSPI_IPCR0 = 0;
FLEXSPI_IPCR1 = FLEXSPI_IPCR1_ISEQID(15) | FLEXSPI_IPCR1_IDATSZ(1);
FLEXSPI_IPCMD = FLEXSPI_IPCMD_TRG;
digitalWriteFast(7, HIGH);
while (!(FLEXSPI_INTR & FLEXSPI_INTR_IPCMDDONE)) {
asm("nop");
}
digitalWriteFast(7, LOW);
FLEXSPI_INTR = FLEXSPI_INTR_IPCMDDONE;
status = *(uint8_t *)&FLEXSPI_RFDR0;
} while (status & 1);
FLEXSPI_MCR0 |= FLEXSPI_MCR0_SWRESET; // purge stale data from FlexSPI's AHB FIFO
while (FLEXSPI_MCR0 & FLEXSPI_MCR0_SWRESET) ; // wait
__enable_irq();
digitalWriteFast(8, LOW);
}
One EEPROM note is:: I made a couple samples before - and other versions after - manitou posted his nice repro one - and they do not all fail this way. So this example seems to do something unique - like my original ungainly case that does repro.
I get a feeling it is related to USB - but attempts to prove that only show it didn't do it in the ones that worked while still doing EEPROM get/put/write.
All the best to Paul putting the pieces together understanding the 'stored bad state' across power outages that take a button press AND then either [ Upload or TyComm Reset ] to unwind.
#include <EEPROM.h>
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
static uint8_t b = 1, c;
static uint32_t ms = millis();
if (millis() - ms > 5000) {
EEPROM.write(0, b);
c = EEPROM.read(0);
for (int i = 0; i < c; i++) {
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
delay(400);
}
b++;
ms = millis();
}
}
I also had an EEPROM test sketch that made NO use of Serial -- it incremented EERPOM byte 0 every 5 seconds, and flashed the LED the number of times determined by the read of EEPROM byte 0. It also demonstrated that EEPROM updates were not happening after a power cycle. I guess USB could still have some background influence ?, but there was no Serial usage in the sketch.