P2 One-Pin boot from small MCU
jmg
Posts: 15,173
Test results from some code to check into the One-Pin mode. Test MCU EFM8BB1, clock dropped to 12.25MHz to reduce power.
This is virtual Terminal Serial Capture of code, running with the test example
Measured time for dump : Sending 20 Char header and 863 code bytes as B64
101.412ms From MCU reset, at 12.25MHz
PredictTime = 101.298ms Char-times alone. at 115566 Baud.
Predicted time for a 2048 byte image, is 238.016ms, which is starting to climb.
Code sizes:
Size_Total_P2_OnePin 0x8c = 140 bytes total
Modules :
Size_MCU_Init EQU 0x26 = 38 bytes
Size_Repack EQU 0x15 = 21 Bytes
Size_EncP2_64 0x1e = 30 bytes
P2 uses a slightly strange Enc64 scheme, more complex than a simple 64Byte slice in ASCII, so that bumps that Size_EncP2_64
Speeds at possible higher Baud (340278) : PredictTime = 34.403ms, Measure 34.500ms from Reset 20+863
Reset delay to Tx is 87.1us
Assumptions: B64 will have some fractional left-overs, but it is assumed the BOOT loader only loads whole 32b pieces.
Code can be slightly simpler, if Send is 3-byte quantized, & assumes trailing fractions are simply discarded.
Outstanding questions and possible issues, from the other thread.
~10ms from what ? From the end of a valid IP string, start bit, or any edge ?
What about any error messages - are they also 10ms from last-RX activity ?
With a 100ms upper limit, and a 10ms+ lower limit, plus add in reset-cap effects, and this all starts to narrow down....
How long from reset pin (rapid) rise, until the P2 can sense RX ?
What happens if a 20h char is partway through, when the P2 exits Reset ?
With two low regions, which one is used for AutoBaud ?
If the P2 sends its verbose CR+LF+”FAIL”+CR+LF in One-Pin mode, that's going to scramble the Rx and cause more fails... ?
"If an external pull-up resistor is sensed on P60 (SPI_CK):"
How is that external pull-up resistor sensed - does it drive P60 low, briefly, then read after release to see Floating ?
Typical One-Pin use would be to have the MCU pulse the P2 reset, but then it needs to wait for any RST cap to RAMP, so is unsure when to start.
If it starts wrong, the load will fail, and speed is quite important here.
Improvements :
If P2 sent 0xFF, or 0xFE, (at the uncal 115200?) on RXD(P63) when it was ready, the MCU could sense that, and start with best precision. It no longer has to hope.
This approach would also cover a Software Reset reboot.
With no Ready signal from P2, the MCU has no way to know it has just done a SW reset ?
What could the P2 Auto-baud up to ? Most small MCUs these days have CalOsc and can go well above 115200.
eg 345600 ? (22.1184M/64)
that could reduce the 2k load time from 238.016ms to around 80ms.
Addit: A variant of this, which would keep the P2 in passive mode more, would be to have the MCU use an ENQ/ACK scheme.
eg add $FF or $FE to the valid Char list, and echo a status byte like 0xFE for OK/Ready and 0xFF for error since last ACK
A 500us repeat rate ENQ polling loop can be done for `+29 bytes
This is virtual Terminal Serial Capture of code, running with the test example
Prop_Txt - 0 0 0 0 +/cj9v37I/YlJoD/KIBm/fD/n/3///////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////6
Measured time for dump : Sending 20 Char header and 863 code bytes as B64
101.412ms From MCU reset, at 12.25MHz
PredictTime = 101.298ms Char-times alone. at 115566 Baud.
Predicted time for a 2048 byte image, is 238.016ms, which is starting to climb.
Code sizes:
Size_Total_P2_OnePin 0x8c = 140 bytes total
Modules :
Size_MCU_Init EQU 0x26 = 38 bytes
Size_Repack EQU 0x15 = 21 Bytes
Size_EncP2_64 0x1e = 30 bytes
P2 uses a slightly strange Enc64 scheme, more complex than a simple 64Byte slice in ASCII, so that bumps that Size_EncP2_64
Speeds at possible higher Baud (340278) : PredictTime = 34.403ms, Measure 34.500ms from Reset 20+863
Reset delay to Tx is 87.1us
Assumptions: B64 will have some fractional left-overs, but it is assumed the BOOT loader only loads whole 32b pieces.
Code can be slightly simpler, if Send is 3-byte quantized, & assumes trailing fractions are simply discarded.
Outstanding questions and possible issues, from the other thread.
The booter waits 10ms, in any case, before responding serially.
~10ms from what ? From the end of a valid IP string, start bit, or any edge ?
What about any error messages - are they also 10ms from last-RX activity ?
With a 100ms upper limit, and a 10ms+ lower limit, plus add in reset-cap effects, and this all starts to narrow down....
How long from reset pin (rapid) rise, until the P2 can sense RX ?
What happens if a 20h char is partway through, when the P2 exits Reset ?
With two low regions, which one is used for AutoBaud ?
If the P2 sends its verbose CR+LF+”FAIL”+CR+LF in One-Pin mode, that's going to scramble the Rx and cause more fails... ?
"If an external pull-up resistor is sensed on P60 (SPI_CK):"
How is that external pull-up resistor sensed - does it drive P60 low, briefly, then read after release to see Floating ?
Typical One-Pin use would be to have the MCU pulse the P2 reset, but then it needs to wait for any RST cap to RAMP, so is unsure when to start.
If it starts wrong, the load will fail, and speed is quite important here.
Improvements :
If P2 sent 0xFF, or 0xFE, (at the uncal 115200?) on RXD(P63) when it was ready, the MCU could sense that, and start with best precision. It no longer has to hope.
This approach would also cover a Software Reset reboot.
With no Ready signal from P2, the MCU has no way to know it has just done a SW reset ?
What could the P2 Auto-baud up to ? Most small MCUs these days have CalOsc and can go well above 115200.
eg 345600 ? (22.1184M/64)
that could reduce the 2k load time from 238.016ms to around 80ms.
Addit: A variant of this, which would keep the P2 in passive mode more, would be to have the MCU use an ENQ/ACK scheme.
eg add $FF or $FE to the valid Char list, and echo a status byte like 0xFE for OK/Ready and 0xFF for error since last ACK
A 500us repeat rate ENQ polling loop can be done for `+29 bytes
Comments
About these possibly-unscheduled error messages, like from a bad character... You are right that they are a source of trouble. The setup for headaches is that the Prop_Hex and Prop_Txt commands have unknown number of data in them. Like you said, we should log the error. Then, we can report it back as part of Prop_Chk's response. This gets responses isolated down to one command that is fixed in its data length. What do you think about that?
Yes, I think a single char ENQ char, and a single char ACK/RDY echo, is an easy way to check progress at any time.
This also allows the One-Pin MCU to sit there, pinging the P2, as it waits for Reset Caps etc to charge.
Skewed Delays in either P2, or MCU, Power-Up are also tolerated in this design.
As soon (500us) as both parties are on-line, the boot process will launch.
If the MCU idles doing this, it can also catch a P2 Soft-reset and reboot it ok.
Also, the P2 should be passive (ie not output on P62/SO) until it receives a sequence on P63(SI).
This also means the boot code should wait and verify a pulldown/start/break condition is longer (ie not like the P1 which just just a simple bit test). This would mean there would be a limit to the minimum baud detected/used.
Costs about 9 bytes at the MCU end.
Of course, I'm fine with One-Pin and i2c
Err, yes - this is exactly what ENQ / ACK does ?
Yes, Chip already has Autobaud implemented ?
Examples of ENQ variant, that reports the AutoBaud capture value. (maybe a simple 2 byte binary reply is fine ?)
This will report numbers like
For these tests MCU is run at SysCLK/2, to save power, as it is expected this will be faster than P2 can manage.
At /1, this would be 2.45MBd as a sustained update loader.
Original P2 64B rules are complex :
So I made a simpler, faster 64B that uses
This still leaves 0x20..0x2F as control chars, and also '6'..'@', so '?' is available for AutoBAUD purposes.
Using this, drops a creepage of 460 cycles at 1.225MBd to reset-region delays of d125
* SiLabs cores can reach up to close to 3MBd, doing the read and (modified) b64, module size is 66 bytes.
SiLabs Baud is 24.5M/2N
* Nuvoton 4T part can reach the fastest UART setting of 1.3824Mbd, with an unrolled loop, and 131 bytes.
Nuvoton Baud is 22.1184M/16N
b64 now "0"-"9" then "A" to "w" with "U" skipped. Still much smaller and faster than original b64.
This mapping also leaves a number of useful AutoBAUD characters available.
( eg "@" and "x" both have tFF of 8, which likely fits the new fractional Baud hardware better.)
Skip 0x55/"U" allows that special case char to be used for Autobaud-Track via the Smartpins.
In X-edge timing mode, the smart pins can simply catch the unique Highest Freq signature of 0x55, and can re-trim the Baud to allow for RC Osc drift during the download.