Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Urboot for ATTiny13/A #19

Closed
MCUdude opened this issue Mar 1, 2023 · 89 comments
Closed

Urboot for ATTiny13/A #19

MCUdude opened this issue Mar 1, 2023 · 89 comments
Labels
enhancement New feature or request

Comments

@MCUdude
Copy link

MCUdude commented Mar 1, 2023

Unlike other AVRs, the internal oscillator in the ATtiny13/A runs at 9.6 MHz and is dividable down to 4.8 MHz, 1.2MHz, and 600kHz.
It would be great if these existed pre-compiled bootloaders for these clock speeds!

@stefanrueger
Copy link
Owner

Would these baud rates be what you are after for these F_CPU?

if [[ /attiny13/attiny13a/ =~ /$mcu/ ]]; then                    
  baud[9600000]=250000/230400/115200/57600/38400/19200/9600
  baud[4800000]=115200/57600/38400/19200/9600
  baud[1200000]=38400/19200/9600
  baud[600000]=19200/9600
fi

@MCUdude
Copy link
Author

MCUdude commented Mar 1, 2023

That would be excellent! Is 250000 baud the fastest "standard" baudrate the ATtiny13/A can handle without too much error?

@stefanrueger
Copy link
Owner

Is 250000 baud the fastest "standard" baudrate the ATtiny13/A can handle without too much error?

Yes.

The ATtiny13 does not have a hardware UART. So, F_CPU/baud rate is the budget of clock cycles that the software has for delaying half a bit, sensing the RX bit, then delaying half a bit. 9.6 MHz/250 kbaud gives us 38.4 cycles. That should just about work, but I doubt one can do SWIO with 460800 baud (only 20 cycles for a complex task).

BTW, 38.4 cycles also means an intrinsic quantisation error of 0.4/38.4 ~ 1%, which is OK assuming the internal oscillator does not add more than about 1.5% of frequency deviation. Smaller baud rates have a better quantisation error: for example, at 115200 baud there is a budget of 83.333 cycles where the quantisation error is 0.33/83.33 = 0.4 %, so you can afford the internal oscillator to be off by max 2%.

@stefanrueger
Copy link
Owner

OK, done: see, eg, ATtiny13A bootloaders

@MCUdude
Copy link
Author

MCUdude commented Mar 3, 2023

Thanks! I'll be away for the weekend, but I'll give it a try next week when I'm back home

@stefanrueger
Copy link
Owner

stefanrueger commented Mar 3, 2023

I checked my SWIO code for the max baud rate. It is F_CPU/29 for classic parts with 16-bit PC and F_CPU/33 for classic parts with 22-bit PC (ATmega2560, eg). XMEGA parts can achieve slightly higher baud rates: F_CPU/28 and F_CPU/32, respectively. This is owing to subtle changes in the clock cycles for opcodes. So, yes, 9.6 MHZ/29 ~ 330 kbaud is the most you can hope to work here.

BTW, is there a good documentation for the timings of newer parts? Some of these have __AVR_XMEGA__ defined in the gcc-avr pre-processor: atmega1608 atmega1609 atmega3208 atmega3209 atmega4808 atmega4809 atmega808 atmega809 attiny1604 attiny1606 attiny1607 attiny1614 attiny1616 attiny1617 attiny202 attiny204 attiny212 attiny214 attiny3214 attiny3216 attiny3217 attiny402 attiny404 attiny406 attiny412 attiny414 attiny416 attiny417 attiny804 attiny806 attiny807 attiny814 attiny816 attiny817

Do these parts have XMEGA timings? @SpenceKonde @MCUdude @mcuee

@stefanrueger stefanrueger added the enhancement New feature or request label Mar 3, 2023
@mcuee
Copy link

mcuee commented Mar 5, 2023

I am not an AVR expert but I read that they have a bit better timing than the xmega timing as mentioned in Chapter 4 of the following Microchip/Atmel document AVR® Instruction Set Manual. In the end, we can say the new AVRxt core (mega0, tiny0/1/2, avr DA/DB/DD) has better timing compated to AVRxm core (xmega).

In the manual, AVR DA is said to have the same AVRxm core as the xmega but I think it is a mistake, as the chip datasheet points to AVRxt core.

Examples, I can see improvement in instructions like SBIS, some cases of LD/LDD/ST/STD.
https://ww1.microchip.com/downloads/en/DeviceDoc/AVR-Instruction-Set-Manual-DS40002198A.pdf

Screenshot 2023-03-05 104849

@mcuee
Copy link

mcuee commented Mar 5, 2023

The Urboot for ATtiny13A seems to work fine.

It does not seem to be able to write to flash in terminal mode. EEPROM writing is okay.

``` PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_issue_1262_mod -c usbasp -p t13a -qqt avrdude> dump lfuse 0000 3a |: |

avrdude> dump hfuse
0000 fb |. |

avrdude> dump lock
0000 ff |. |

avrdude> erase
erasing chip ...
avrdude> quit

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_issue_1262_mod -c usbasp -p t13a
-U flash:v:.\urboot_attiny13a_9mhz6_115200bps_swio_rxb0_txb1_ee_lednop_fr_ce_ur_vbl.hex:i -qq && echo OK
OK

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_issue_1262_mod -c urclock -P COM7
-p t13a -xshowall -q

avrdude_issue_1262_mod: AVR device initialized and ready to accept instructions
000075716854 0000-00-00 00.00 application 0 store 0 meta 0 boot 384 u7.7
weu-jpr-c vector 4 (EE_RDY) ATtiny13A

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_issue_1262_mod -c urclock -P COM7 -p t13a -qqt
avrdude> dump eeprom
0000 54 68 71 75 6b 20 6f 77 66 6f 6a 75 73 20 65 72 |Thquk owfojus er|
0010 68 65 61 7a 64 6f 54 68 71 75 6b 20 6f 77 66 6f |heazdoThquk owfo|
0020 78 20 20 6c 61 7a 79 20 64 6f 67 0a 54 68 65 20 |x lazy dog The |
0030 71 75 69 63 6b 20 62 72 6f 77 6e 20 66 6f 78 20 |quick brown fox |

avrdude> write eeprom 0 0xaa 0x55 0xaa
avrdude> flush
avrdude> dump eeprom 0x0
0000 aa 55 aa 75 6b 20 6f 77 66 6f 6a 75 73 20 65 72 |.U.uk owfojus er|
0010 68 65 61 7a 64 6f 54 68 71 75 6b 20 6f 77 66 6f |heazdoThquk owfo|
0020 78 20 20 6c 61 7a 79 20 64 6f 67 0a 54 68 65 20 |x lazy dog The |
0030 71 75 69 63 6b 20 62 72 6f 77 6e 20 66 6f 78 20 |quick brown fox |

avrdude> dump flash 0x100 0x40
0100 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0110 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0120 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0130 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|

avrdude> write flash 0x100 0xaa 0x55
avrdude> flush
avrdude_issue_1262_mod error: verification mismatch at flash page addr 0x0100

avrdude> quit
avrdude_issue_1262_mod error: verification mismatch at flash page addr 0x0100

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_issue_1262_mod -c usbasp -p t13a -qqt
avrdude> dump flash 0x100 0x40
0100 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0110 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0120 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0130 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|

avrdude> quit

</details>

@mcuee
Copy link

mcuee commented Mar 5, 2023

Same for normal mode. EEPROM writing is okay but not flash writing. Basically it does not write anything in the flash.

``` PS C:\work\avr\avrdude_test\avrdude_bin> cat .\entest_64B.eep :020000040000FA :2000000054686520717569636B2062726F776E20666F78206A756D7073206F76657220740E :200020006865206C617A7920646F670A54686520717569636B2062726F776E20666F78207C :00000001FF

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_issue_1262_mod -c urclock -P COM7
-p t13a -U eeprom:w:entest_64B.eep:i

avrdude_issue_1262_mod: AVR device initialized and ready to accept instructions
avrdude_issue_1262_mod: device signature = 0x1e9007 (probably t13a)
avrdude_issue_1262_mod: reading input file entest_64B.eep for eeprom
with 64 bytes in 1 section within [0, 0x3f]
using 16 pages and 0 pad bytes
avrdude_issue_1262_mod: writing 64 bytes eeprom ...

Writing | ################################################## | 100% 0.24 s

avrdude_issue_1262_mod: 64 bytes of eeprom written
avrdude_issue_1262_mod: verifying eeprom memory against entest_64B.eep

Reading | ################################################## | 100% 0.06 s

avrdude_issue_1262_mod: 64 bytes of eeprom verified

avrdude_issue_1262_mod done. Thank you.

PS C:\work\avr\avrdude_test\avrdude_bin> cat .\zeros_t13a_test.hex
:020000040000FA
:200100000000000000000000000000000000000000000000000000000000000000000000DF
:200120000000000000000000000000000000000000000000000000000000000000000000BF
:2001400000000000000000000000000000000000000000000000000000000000000000009F
:2001600000000000000000000000000000000000000000000000000000000000000000007F
:2001800000000000000000000000000000000000000000000000000000000000000000005F
:2001A00000000000000000000000000000000000000000000000000000000000000000003F
:2001C00000000000000000000000000000000000000000000000000000000000000000001F
:2001E0000000000000000000000000000000000000000000000000000000000000000000FF
:00000001FF

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_issue_1262_mod -c urclock
-P COM7 -p t13a -U .\zeros_t13a_test.hex

avrdude_issue_1262_mod: AVR device initialized and ready to accept instructions
avrdude_issue_1262_mod: device signature = 0x1e9007 (probably t13a)
avrdude_issue_1262_mod: Note: flash memory has been specified, an erase cycle will be performed.
To disable this feature, specify the -D option.
avrdude_issue_1262_mod: erasing chip
avrdude_issue_1262_mod: reading input file .\zeros_t13a_test.hex for flash
with 256 bytes in 1 section within [0x100, 0x1ff]
using 8 pages and 0 pad bytes
avrdude_issue_1262_mod: preparing flash input for device bootloader
avrdude_issue_1262_mod: writing 256 bytes flash ...

Writing | ################################################## | 100% 0.04 s

avrdude_issue_1262_mod: 256 bytes of flash written
avrdude_issue_1262_mod: verifying flash memory against .\zeros_t13a_test.hex

Reading | | 0%
0.00 s avrdude_issue_1262_mod: en passant forcing reset vector to point to vector bootloader
Reading | ################################################## | 100% 0.05 s

avrdude_issue_1262_mod warning: verification mismatch
device 0xff != input 0x00 at addr 0x0100 (error)
avrdude_issue_1262_mod error: verification mismatch

avrdude_issue_1262_mod done. Thank you.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_issue_1262_mod -c usbasp -p t13a -qqt
avrdude> dump flash 0x100
0100 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0110 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0120 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0130 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0140 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0150 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0160 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0170 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0180 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
0190 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
01a0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
01b0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
01c0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
01d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
01e0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
01f0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|

avrdude> quit

</details>

@stefanrueger
Copy link
Owner

@mcuee Thanks for testing! Looks like you need to enable SELFPRGEN in hfuse

avrdude> dump hfuse
0000  fb                                                |.               |

@stefanrueger
Copy link
Owner

@mcuee And thanks for the pointers to exact timings.

@mcuee
Copy link

mcuee commented Mar 6, 2023

@mcuee Thanks for testing! Looks like you need to enable SELFPRGEN in hfuse

avrdude> dump hfuse
0000  fb                                                |.               |

That is it. Thanks for pointing out this apparent mistake. Now it works well.

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c usbasp -p t13a -qqt
avrdude> dump lfuse
0000  3a                                                |:               |

avrdude> dump hfuse
0000  eb                                                |.               |

avrdude> quit

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c urclock -P COM7 -p t13a -xshowall

avrdude_pr1309: AVR device initialized and ready to accept instructions
000020656854 0000-00-00 00.00  application 0 store 0 meta 0 boot 384 u7.7 
weu-jpr-c vector 4 (EE_RDY) ATtiny13A

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c urclock -P COM7 -p t13a
 -U .\zeros_t13a_test.hex

avrdude_pr1309: AVR device initialized and ready to accept instructions
avrdude_pr1309: device signature = 0x1e9007 (probably t13a)
avrdude_pr1309: Note: flash memory has been specified, an erase cycle will be performed.
                To disable this feature, specify the -D option.
avrdude_pr1309: erasing chip
avrdude_pr1309: reading input file .\zeros_t13a_test.hex for flash
                with 256 bytes in 1 section within [0x100, 0x1ff]
                using 8 pages and 0 pad bytes
avrdude_pr1309: preparing flash input for device bootloader
avrdude_pr1309: writing 256 bytes flash ...

Writing | ################################################## | 100% 0.04 s

avrdude_pr1309: 256 bytes of flash written
avrdude_pr1309: verifying flash memory against .\zeros_t13a_test.hex

Reading | ################################################## | 100% 0.04 s

avrdude_pr1309: 256 bytes of flash verified

avrdude_pr1309 done.  Thank you.

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c urclock -P COM7 -p t13a -xshowall

avrdude_pr1309: AVR device initialized and ready to accept instructions
000020656854 2023-03-06 13.22 zeros_t13a_test.hex 512 store 97 meta 31 boot 384 u7.7 
weu-jpr-c vector 4 (EE_RDY) ATtiny13A

@mcuee
Copy link

mcuee commented Mar 6, 2023

250,000 bps is also fine.

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c usbasp -p t13a -qq
 -U .\urboot_attiny13a_9mhz6_250000bps_swio_rxb0_txb1_ee_lednop_fr_ce_ur_vbl.hex -qq && echo OK
OK

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c urclock -P COM7 -b 250000
 -p t13a -xshowall

avrdude_pr1309: AVR device initialized and ready to accept instructions
000020656854 0000-00-00 00.00  application 0 store 0 meta 0 boot 384 u7.7 
weu-jPr-c vector 4 (EE_RDY) ATtiny13A

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c urclock -P COM7 -b 250000
 -p t13a -U .\zeros_t13a_test.hex

avrdude_pr1309: AVR device initialized and ready to accept instructions
avrdude_pr1309: device signature = 0x1e9007 (probably t13a)
avrdude_pr1309: Note: flash memory has been specified, an erase cycle will be performed.
                To disable this feature, specify the -D option.
avrdude_pr1309: erasing chip
avrdude_pr1309: reading input file .\zeros_t13a_test.hex for flash
                with 256 bytes in 1 section within [0x100, 0x1ff]
                using 8 pages and 0 pad bytes
avrdude_pr1309: preparing flash input for device bootloader
avrdude_pr1309: writing 256 bytes flash ...

Writing | ################################################## | 100% 0.04 s

avrdude_pr1309: 256 bytes of flash written
avrdude_pr1309: verifying flash memory against .\zeros_t13a_test.hex

Reading | ################################################## | 100% 0.02 s

avrdude_pr1309: 256 bytes of flash verified

avrdude_pr1309 done.  Thank you.

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c urclock -P COM7 -b 250000
 -p t13a -xshowall

avrdude_pr1309: AVR device initialized and ready to accept instructions
000020656854 2023-03-06 13.22 zeros_t13a_test.hex 512 store 97 meta 31 boot 384 u7.7 
weu-jPr-c vector 4 (EE_RDY) ATtiny13A

@stefanrueger
Copy link
Owner

250,000 bps is also fine.

That's good. Thanks for testing @mcuee. Amazing that the bootloader works on such a small flash/sram. The smallest b/loader is 256 bytes so can be used for rapid prototyping...

@mcuee
Copy link

mcuee commented Mar 7, 2023

@MCUdude

Haha, now you may have a chance to add urboot to MicroCore.
https://github.com/MCUdude/MicroCore

@MCUdude
Copy link
Author

MCUdude commented Mar 7, 2023

Adding Urboot to MicroCore is definitly something I'll consider!

The only problem is that when I designed the "MicroCore hardware", I decided to keep compatibility with the existing ATtinyCore and its bootloader implementation, so that ATtiny85's could be programmed usimmg my board without modifications.

The quirk here is that ATtinyCore and MicroCore use pin PB0 for TX, and PB1 for RX. The opposite of what the pre-compiled urboot binaries does.

@mcuee
Copy link

mcuee commented Mar 7, 2023

The quirk here is that ATtinyCore and MicroCore use pin PB0 for TX, and PB1 for RX. The opposite of what the pre-compiled urboot binaries does.

That should be a easy change.

@MCUdude
Copy link
Author

MCUdude commented Mar 7, 2023

It would be awesome to have a menu in the Arduino tools menu like this. For rapid prototyping, a bootloader is very convenient

Bootloader:
  * No bootloader
  * RX = PB1, TX = PB0
  * RX = PB0, TX = PB1

@stefanrueger
Copy link
Owner

[TX/RX pin assignment] should be a easy change.

Sure.

urboot/src/mkurboots

Lines 586 to 608 in 15ced59

mcuio[attiny13]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny13a]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny15]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny22]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny24]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny24a]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny25]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny26]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny28]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny43u]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny44]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny44a]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny45]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny48]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny84]="SWIO=1 RX=AtmelPA3 TX=AtmelPA2"
mcuio[attiny84a]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny85]="SWIO=1 RX=AtmelPB4 TX=AtmelPB3"
mcuio[attiny87]="UARTNUM=0 RX=AtmelPA0 TX=AtmelPA1"
mcuio[attiny88]="SWIO=1 RX=AtmelPD7 TX=AtmelPD6"
mcuio[attiny167]="UARTNUM=0 RX=AtmelPA0 TX=AtmelPA1"
mcuio[attiny261]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny261a]="SWIO=1 RX=AtmelPB0 TX=AtmelPB1"
mcuio[attiny441]="UARTNUM=0 RX=AtmelPA2 TX=AtmelPA1|UARTNUM=0 UARTALT=1 RX=AtmelPB2 TX=AtmelPA7|UARTNUM=1 RX=AtmelPA4 TX=AtmelPA5"
can easily be changed. I've only set RX=PB0/TX=PB1 as default when nothing is known about typical boards that use this MCU. For some reason the t85 is down as RX=PB4/TX=PB3 presumably owing to the digispark board. You can add more configurations as a | separated list:

mcuio[attiny85]="SWIO=1 RX=AtmelPB1 TX=AtmelPB0|SWIO=1 RX=AtmelPB4 TX=AtmelPB3"

@stefanrueger
Copy link
Owner

stefanrueger commented Mar 7, 2023

I assume the microcore boards do not have a LED? That saves 6 bytes (choose a b/loader without _lednop and without _led[+-][a-f][0-7] in the name) . If desperate, I know two locations in urclock.c where two bytes each can be saved when needed: one lengthens the stop bits of sent bytes by 0.9 bits in SWIO (so download is marginally slower); the other is by removing wdr from setting the duration of the WDTO in watchdogConfig(). It's generally a mistake to skip wdr in the latter (because reducing the WDTO could trigger an immediate reset should the watchdog timer be progressed beyond the wanted WDTO), but I noticed optiboot does not use that wdr and that seems fine. I can only assume that a hardware reset also resets the internal WD timer to 0...

@MCUdude
Copy link
Author

MCUdude commented Mar 7, 2023

I'll look more into this tonight.
The board has an onboard LED connected to pin PB2 (active high), but it would only make sense to add support for this if the compiled binary occupies 256 bytes or less.

@stefanrueger
Copy link
Owner

stefanrueger commented Mar 7, 2023

the compiled binary occupies 256 bytes or less

You can judge this by checking out if there is a _lednop bootloader that is within 256 bytes. This has "placeholder nops" for where LED twiddling goes once you know the pin. If there are only non-_lednop bootloaders within 256 bytes, then the bootloaders can be shortened by 4 bytes if needed through the tricks above. [edit: you need 6 bytes for LEDs]

| I can only assume that a hardware reset also resets the internal WD timer to 0...

That is actually highly likely come to think of that. Most AVR will have a fuse setting that switches on the WD timer by default. In order for these to work the WD timer needs to be reset to 0 on external (hard) reset. Otherwise there would be an unknown period for the first WDTO after external reset, which isn't acceptable. I believe the function that configures the WDTO in urboot is the only aspect where optiboot has shorter code (as optoboot drops the wdr)

@MCUdude
Copy link
Author

MCUdude commented Mar 7, 2023

It looks like the lednop bootloaders for ATtiny13/A are bigger than 256 bytes, so I think it's best with a bootloader that doesn't flash the LED while programming, but can instead fit within 256 bytes.
https://github.com/stefanrueger/urboot.hex/tree/main/mcus/attiny13a/fcpu_9mhz6/115200_bps

(Ralph Doncaster actually created a 64-byte (!) sized bootloader, picoboot. I'm not sure how "safe" this is compared to Urboot, but it's still impressive in its own right!)

@stefanrueger could you add MicroCore as another "core" in the urboot repo that contains pre-compiled bootloaders for ATtiny13A with RXD=PB0/TXD=PB1 and RXD=PB1/TXD=PB0? I see no reason why not to add a bootloader option to MicroCore when a proper, failsafe bootloader can fit within 256 bytes!

@MCUdude
Copy link
Author

MCUdude commented Mar 7, 2023

I've just pushed a commit to the MicroCore repo where I've added Urboot as an option in the Arduino tools menu. Using Urboot with the 9.6 MHz internal oscillator works like a charm, but I'm having issues getting the 4.8MHz, 1.2MHz, and 600kHz options to work. @mcuee can you test it on your hardware? If you want to use Arduino IDE directly, you'll have to install MicroCore using the boards manager install, and then replace the installed core files with the one found in the repo on Github.

4.8 MHz option:

/Users/hans/Library/Arduino15/packages/MicroCore/tools/avrdude/7.1-arduino.1/bin/avrdude -C/Users/hans/Library/Arduino15/packages/MicroCore/hardware/avr/2.2.1/avrdude.conf -v -pattiny13a -curclock -b57600 -Uflash:w:/var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_151041/Blink.ino.hex:i 

avrdude: Version 7.1-arduino.1
         Copyright the AVRDUDE authors;
         see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

         System wide configuration file is /Users/hans/Library/Arduino15/packages/MicroCore/hardware/avr/2.2.1/avrdude.conf
         User configuration file is /Users/hans/.avrduderc

         Using Port                    : /dev/cu.usbserial-1410
         Using Programmer              : urclock
         Overriding Baud Rate          : 57600
avrdude urclock_getsync() warning: attempt 1 of 10: not in sync
avrdude urclock_getsync() warning: attempt 2 of 10: not in sync
avrdude urclock_getsync() warning: attempt 3 of 10: not in sync
avrdude urclock_getsync() warning: attempt 4 of 10: not in sync
avrdude urclock_getsync() warning: attempt 5 of 10: not in sync
avrdude urclock_getsync() warning: attempt 6 of 10: not in sync
avrdude urclock_getsync() warning: attempt 7 of 10: not in sync
avrdude urclock_getsync() warning: attempt 8 of 10: not in sync
avrdude urclock_getsync() warning: attempt 9 of 10: not in sync
avrdude urclock_getsync() warning: attempt 10 of 10: not in sync
avrdude urclock_recv() warning: programmer is not responding; try -xstrict and/or vary -xdelay=100
avrdude main() error: unable to open programmer urclock on port /dev/cu.usbserial-1410

avrdude done.  Thank you.

the selected serial port 
 does not exist or your board is not connected

1.2 MHz option:

/Users/hans/Library/Arduino15/packages/MicroCore/tools/avrdude/7.1-arduino.1/bin/avrdude -C/Users/hans/Library/Arduino15/packages/MicroCore/hardware/avr/2.2.1/avrdude.conf -v -pattiny13a -curclock -b19200 -Uflash:w:/var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_151041/Blink.ino.hex:i 

avrdude: Version 7.1-arduino.1
         Copyright the AVRDUDE authors;
         see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

         System wide configuration file is /Users/hans/Library/Arduino15/packages/MicroCore/hardware/avr/2.2.1/avrdude.conf
         User configuration file is /Users/hans/.avrduderc

         Using Port                    : /dev/cu.usbserial-1410
         Using Programmer              : urclock
         Overriding Baud Rate          : 19200
         AVR Part                      : ATtiny13A
         Chip Erase delay              : 4000 us
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         Serial program mode           : yes
         Parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                           Block Poll               Page                       Polled
           Memory Type Alias    Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom                 65     5     4    0 no         64    4      0  4000  4000 0xff 0xff
           flash                  65     6    32    0 yes      1024   32     32  4500  4500 0xff 0xff
           lfuse                   0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
           hfuse                   0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
           lock                    0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
           signature               0     0     0    0 no          3    1      0     0     0 0x00 0x00
           calibration             0     0     0    0 no          2    1      0     0     0 0x00 0x00

         Programmer Type : Urclock
         Description     : Urclock programmer for urboot bootloaders using urprotocol
         Urboot protocol for ATtiny13A

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9007 (probably t13a)
avrdude: Note: flash memory has been specified, an erase cycle will be performed.
         To disable this feature, specify the -D option.
avrdude: erasing chip
         delaying chip erase until first -U upload to flash
avrdude: reading input file /var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_151041/Blink.ino.hex for flash
         with 78 bytes in 1 section within [0, 0x4d]
         using 3 pages and 18 pad bytes
avrdude: preparing flash input for device bootloader
avrdude: writing 78 bytes flash ...

Writing | ################################################## | 100% 0.82s

avrdude: 78 bytes of flash written
avrdude: verifying flash memory against /var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_151041/Blink.ino.hex

Reading | #########################################An error occurred while uploading the sketch
######### | 100% 0.59s

avrdude avr_verify() warning: verification mismatch
        device 0x13 != input 0x93 at addr 0x0020 (error)
        device 0x80 != input 0xc0 at addr 0x0023 (error)
        device 0x71 != input 0x31 at addr 0x0040 (error)
avrdude do_op() error: verification mismatch

avrdude done.  Thank you

600kHz option:

/Users/hans/Library/Arduino15/packages/MicroCore/tools/avrdude/7.1-arduino.1/bin/avrdude -C/Users/hans/Library/Arduino15/packages/MicroCore/hardware/avr/2.2.1/avrdude.conf -v -pattiny13a -curclock -b9600 -Uflash:w:/var/folders/6l/ypg6qbw172v1s4vtt6g990tw0000gn/T/arduino_build_151041/Blink.ino.hex:i 

avrdude: Version 7.1-arduino.1
         Copyright the AVRDUDE authors;
         see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

         System wide configuration file is /Users/hans/Library/Arduino15/packages/MicroCore/hardware/avr/2.2.1/avrdude.conf
         User configuration file is /Users/hans/.avrduderc

         Using Port                    : /dev/cu.usbserial-1410
         Using Programmer              : urclock
         Overriding Baud Rate          : 9600
avrdude urclock_getsync() warning: attempt 1 of 10: not in sync
avrdude urclock_getsync() warning: attempt 2 of 10: not in sync
avrdude urclock_getsync() warning: attempt 3 of 10: not in sync
avrdude urclock_getsync() warning: attempt 4 of 10: not in sync
avrdude urclock_getsync() warning: attempt 5 of 10: not in sync
avrdude urclock_getsync() warning: attempt 6 of 10: not in sync
avrdude urclock_getsync() warning: attempt 7 of 10: not in sync
avrdude urclock_getsync() warning: attempt 8 of 10: not in sync
avrdude urclock_getsync() warning: attempt 9 of 10: not in sync
avrdude urclock_getsync() warning: attempt 10 of 10: not in sync
An error occurred while uploading the sketch
avrdude urclock_recv() warning: programmer is not responding; try -xstrict and/or vary -xdelay=100
avrdude main() error: unable to open programmer urclock on port /dev/cu.usbserial-1410

avrdude done.  Thank you.

@stefanrueger
Copy link
Owner

stefanrueger commented Mar 7, 2023

If 9m6 Hz @ 115200 baud works like a charm, then so should 4m8 Hz @ 57600 baud. It's even the same bootloader bit for bit, just that the entire "world" is slower. Will be the same for 1m2 Hz @ 14400 baud with exactly the same bootloader, no need to recompile or reflash. Could you try these fuse settings to effect the correct F_CPU and then set the correct -B <baud> for avrdude. Sometimes I find that certain -B ... settings are not done (haven't gone to the bottom of that) but there must be a way to verify avrdude is setting the baud rate correctly.

Ralph Doncaster actually created a 64-byte (!) sized bootloader

Yes, cool stuff. I read at the source and think I understand how it works. True, safety is all shifted to the uploader (but there is an eor check sum every 4 command bytes); there is no download; baud rate is a fixed function of F_CPU (no code left for delay loops to slow baud rate down), uploader needs to be able to create that baud rate, but yes, actually very cool stuff.

@stefanrueger
Copy link
Owner

I am unhappy with the alphabetic order of the oscillator frequency directories in the urboot.hex github so thought of

autobaud
b_F_cpu__24m_Hz
c_F_cpu__22m1184_Hz
d_F_cpu__20m_Hz
e_F_cpu__18m432_Hz
f_F_cpu__16m_Hz
g_F_cpu__14m7456_Hz
h_F_cpu__12m_Hz
i_F_cpu__11m0592_Hz
j_F_cpu___9m6_Hz
k_F_cpu___8m_Hz
l_F_cpu___7m3728_Hz
m_F_cpu___4m8_Hz
n_F_cpu___4m_Hz
o_F_cpu___3m6864_Hz
p_F_cpu___2m_Hz
q_F_cpu___1m8432_Hz
r_F_cpu___1m2_Hz
s_F_cpu___1m_Hz
t_F_cpu_600k_Hz

Similarly for the baud rates

a_1000000_bps
b__500000_bps
c__460800_bps
d__250000_bps
e__230400_bps
f__125000_bps
g__115200_bps
h___76800_bps
i___57600_bps
j___38400_bps
k___28800_bps
l___19200_bps
m___14400_bps
n____9600_bps
o____7200_bps
p____4800_bps
q____3600_bps
r____2400_bps
s____1200_bps

Do I miss some?

@stefanrueger
Copy link
Owner

Could also do

autobaud
b_F_cpu_24.0000_MHz
c_F_cpu_22.1184_MHz
d_F_cpu_20.0000_MHz
e_F_cpu_18.4320_MHz
f_F_cpu_16.0000_MHz
g_F_cpu_14.7456_MHz
h_F_cpu_12.0000_MHz
i_F_cpu_11.0592_MHz
j_F_cpu__9.6000_MHz
k_F_cpu__8.0000_MHz
l_F_cpu__7.3728_MHz
m_F_cpu__4.8000_MHz
n_F_cpu__4.0000_MHz
o_F_cpu__3.6864_MHz
p_F_cpu__2.0000_MHz
q_F_cpu__1.8432_MHz
r_F_cpu__1.2000_MHz
s_F_cpu__1.0000_MHz
t_F_cpu__0.6000_MHz

Probably even neater (thinking out loud here)

@mcuee
Copy link

mcuee commented Mar 8, 2023

If 9m6 Hz @ 115200 baud works like a charm, then so should 4m8 Hz @ 57600 baud. It's even the same bootloader bit for bit, just that the entire "world" is slower.

@MCUdude and @stefanrueger

Yes that is the case for me. I only need to change the fuse setting in this case.

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c usbasp -p t13a -qq
 -U .\urboot_attiny13a_9mhz6_115200bps_swio_rxb0_txb1_ee_lednop_fr_ce_ur_vbl.hex && echo OK
OK

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c urclock -P COM7 -p t13a -xshowall

avrdude_pr1309: AVR device initialized and ready to accept instructions
000020656854 0000-00-00 00.00  application 0 store 0 meta 0 boot 384 u7.7 
weu-jpr-c vector 4 (EE_RDY) ATtiny13A

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c usbasp -p t13a -qqt
avrdude> dump lfuse
0000  3a                                                |:               |

avrdude> write lfuse 0 0x39
avrdude> quit
C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c urclock -P COM7
 -b 57600 -p t13a -xshowall

avrdude_pr1309: AVR device initialized and ready to accept instructions
000020656854 0000-00-00 00.00  application 0 store 0 meta 0 boot 384 u7.7 
weu-jpr-c vector 4 (EE_RDY) ATtiny13A

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c urclock -P COM7 -b 57600
 -p t13a -U .\zeros_t13a_test.hex

avrdude_pr1309: AVR device initialized and ready to accept instructions
avrdude_pr1309: device signature = 0x1e9007 (probably t13a)
avrdude_pr1309: Note: flash memory has been specified, an erase cycle will be performed.
                To disable this feature, specify the -D option.
avrdude_pr1309: erasing chip
avrdude_pr1309: reading input file .\zeros_t13a_test.hex for flash
                with 256 bytes in 1 section within [0x100, 0x1ff]
                using 8 pages and 0 pad bytes
avrdude_pr1309: preparing flash input for device bootloader
avrdude_pr1309: writing 256 bytes flash ...

Writing | ################################################## | 100% 0.04 s

avrdude_pr1309: 256 bytes of flash written
avrdude_pr1309: verifying flash memory against .\zeros_t13a_test.hex

Reading | ################################################## | 100% 0.03 s

avrdude_pr1309: 256 bytes of flash verified

avrdude_pr1309 done.  Thank you.

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c urclock -P COM7 -b 57600 -p t13a -xshowall

avrdude_pr1309: AVR device initialized and ready to accept instructions
000020656854 2023-03-06 13.22 zeros_t13a_test.hex 512 store 97 meta 31 boot 384 u7.7
 weu-jpr-c vector 4 (EE_RDY) ATtiny13A

Same for 250000 bps firmware which will run at 125000bps for 4.8MHz clock.

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c usbasp -p t13a
 -U .\urboot_attiny13a_9mhz6_250000bps_swio_rxb0_txb1_ee_lednop_fr_ce_ur_vbl.hex -qq && echo OK
OK

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1309 -c urclock -P COM7 -b 125000 -p t13a
 -U .\zeros_t13a_test.hex

avrdude_pr1309: AVR device initialized and ready to accept instructions
avrdude_pr1309: device signature = 0x1e9007 (probably t13a)
avrdude_pr1309: Note: flash memory has been specified, an erase cycle will be performed.
                To disable this feature, specify the -D option.
avrdude_pr1309: erasing chip
avrdude_pr1309: reading input file .\zeros_t13a_test.hex for flash
                with 256 bytes in 1 section within [0x100, 0x1ff]
                using 8 pages and 0 pad bytes
avrdude_pr1309: preparing flash input for device bootloader
avrdude_pr1309: writing 256 bytes flash ...

Writing | ################################################## | 100% 0.05 s

avrdude_pr1309: 256 bytes of flash written
avrdude_pr1309: verifying flash memory against .\zeros_t13a_test.hex

Reading | ################################################## | 100% 0.03 s

avrdude_pr1309: 256 bytes of flash verified

avrdude_pr1309 done.  Thank you.

@MCUdude
Copy link
Author

MCUdude commented Apr 9, 2023

The new names for the files and folder in the cores folder work great with Arduino IDE!
One thing though. Could you please provide -6% and -8% bootloaders for the ATtiny13 as well?
I have a chip here that won't work with the default 4.8MHz internal oscillator bootloader unless I use a baudrate of 4500 instead of 4800.

@stefanrueger
Copy link
Owner

OK, a wider spread is needed than I imagined. How about the variation is in steps of 1.25% and has a range of 13 steps from -7.5% to 7.5%? Would that work? Coincidentally, 4500 = 4800-6.25%

@MCUdude
Copy link
Author

MCUdude commented Apr 10, 2023

I have never seen an internal oscillator being faster than it should, only slower. And since UART can handle a few percent errors, it should be fine with 1.5 or 2% steps I think.

How about:
104%, 102%, 100%, 98%, 96%, 94%, 92%, 90%

This should even cover the chips that "fell off the delivery truck" and sold on the black market.

@MCUdude
Copy link
Author

MCUdude commented Apr 10, 2023

I read on a forum that some ATtiny13 chips are as bas as 10% off sometimes. Usually, the 4.8MHz one is the worst, because the default calibration value that gets automatically is for the 9.6 MHz one.

Which means that in order get the 4.8MHz oscillator to be consistent, we'll have to read the second byte in the calibration register using Avrdude, and ideally write this to a fixed address so that the bootloader can load this value into its OSCCAL register. This isn't currently possible using Avrdude 7.1, but with the feature suggested in avrdudes/avrdude#1322, I think it should be possible. However, it's probably difficult to make ut fit within 256 bytes.

@stefanrueger
Copy link
Owner

can handle a few percent errors

TLDR; 2% stepping is too big, and 1% too conservative. 1.25% to 1.5% seem right

Back of the envelope: if the onset of a transmitted bit is 25% of its width early or late comms start getting into murky waters. Errors accumulate over the 10 start, data and stop bits, so can afford 2.5% bit error rate, which is composed of (worst case) sender quantisation error, sender frequency error, receiver quantisation error and receiver frequency error. Assuming the host PC has perfect comms we should really not go above 2.5% for bootloader. The quantisation error can be finely controlled by urboot's SWIO, and it is set to 6000 ppm (0.6%) in mkurboots. It can still be that it is -0.6% on one step and +0.6% in the next step, so two neighbouring effective frequencies can be 1.2% plus step size apart. That would be 2.45% if the step size is chosen to be 1.25%. The step size could be set bigger (max 1.9%) but going there means the internal frequency has no further leeway during operation in terms of ageing or temperature change.

@stefanrueger
Copy link
Owner

never seen an internal oscillator being faster than it should, only slower

That's interesting! Could make boundaries asymmetric. Is that documented somewhere? Is it plausible owing to the waty factory calibration and/or the workings of the OSCCAL register.

@MCUdude
Copy link
Author

MCUdude commented Apr 10, 2023

never seen an internal oscillator being faster than it should, only slower

Well, when thinking about it, I once had an ATtiny13 where the internal 4.8 MHz oscillator ran at ~5.0 MHz, but this was most likely because the 9.6MHz calibration value was automatically loaded.

Again, the 9.6MHz oscillator is usually fine, it's just a few percent off. It's the 4.8MHz that's causing problems. And I haven't been able to use the bootloader with the internal 128kHz oscillator. Probably because this way too "off". The datasheet even states that its frequency varies with voltage, temperature and batch number. In other words, not very dependable.

@mcuee
Copy link

mcuee commented Apr 10, 2023

I read on a forum that some ATtiny13 chips are as bas as 10% off sometimes. Usually, the 4.8MHz one is the worst, because the default calibration value that gets automatically is for the 9.6 MHz one.

Which means that in order get the 4.8MHz oscillator to be consistent, we'll have to read the second byte in the calibration register using Avrdude, and ideally write this to a fixed address so that the bootloader can load this value into its OSCCAL register. This isn't currently possible using Avrdude 7.1, but with the feature suggested in avrdudes/avrdude#1322, I think it should be possible. However, it's probably difficult to make ut fit within 256 bytes.

In the end, this may be the better way to go for users who want to run the urboot bootloader for ATtiny13A at 4.8MHz, even if the bootloader side can not fit in 256 Bytes.

@mcuee
Copy link

mcuee commented Apr 10, 2023

Other than this ATtiny13/13A, are there any other AVR MCUs have this type of two OSSCAL value for two internal oscillator frequency?

@stefanrueger
Copy link
Owner

stefanrueger commented Apr 10, 2023

ideally write this to a fixed address so that the bootloader can load this value into its OSCCAL register

How does the calibration byte come to be in flash in the first instance? Once the calibration byte has been written to flash, then the additional step (min 8 bytes code) in the bootloader to fetch that byte from that flash location and store it in OSCCAL is equivalent to using a different bootloader with the correct frequency (typically the code size stays roughly the same for different frequencies). So, if the external calibration process that burns the calibration byte into flash were to burn the bootloader with the correct frequency into flash then that step could be saved.

Does the modified OSCCAL register survive a WDR? I suspect every type of reset will load the factory calibration value and store that into OSCCAL. A bootloader normally starts the application through a WDR, so the application has to set OSCCAL again (if wants to/needs to).

Do you have a natural flash address for the calibration byte?

Another idea is to put a 8-byte subroutine at FLASHEND-6-8+1 (just below the 6-byte table at FLASHEND)

calibrate:
    ldi r24,%[oscalvalue]
    sts %[oscalregister], r24
    ret

Together with an rcall calibration at the beginning of the bootloader this would enlarge the bootloader by 10 bytes. Shorter that the reset-vector protection (that I find overrated as it only kicks in when the user writes to flash in own routines using the bootloader, for the rest avrdude -c urclock looks after the reset vector). Any application can then cast the word address (FLASHEND-14UL+1UL)/2 to a function pointer and call the calibration routine as

   ((void (*)(void))((FLASHEND-14UL+1UL)/2))();

Not pretty, but should work. Any external re-calibration procedure would write the two-byte opcode ldi r1,0xYZ rather than a single calibration byte to the flash address FLASHEND-6-8+1.

An alternative 6-byte solution is to simply have ldi r24,value, sts osccal,r24 as first thing in the bootloader. As above external calibration could change the ldi opcode at bootloader start. An application can read the table at the end of flash to figure out the start of the bootloader, load the ldi opcode there, and mask the OSCCAL value out and store it there. Many more bytes (for the application) though than the call to the calibration routine above.

All things considered, I still prefer the bootloader not deal with OSCCAL; instead select an appropriate b/loader for that part. The user is free to do with OSCCAL what they want (EEPROM/Flash/ignore/let the user press x repeatedly at application start until the application that successively changes OSCCAL can read the x and thus knows the frequency is now right/...).

@mcuee
Copy link

mcuee commented Apr 10, 2023

@stefanrueger

I could be wrong but I think by second byte in the calibration register, @MCUdude means to say the 2nd byte of the Calibration Bytes.

Section 17.3, page 111 of the ATtiny13A datasheet
https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/DataSheets/ATtiny13A-Data-Sheet-DS40002307A.pdf

The signature area of the ATtiny13A contains two bytes of calibration data for the internal oscillator. The calibration data in the high byte of address 0x00 is for use with the oscillator set to 9.6 MHz operation. During reset, this byte is automatically written into the OSCCAL register to ensure correct frequency of the oscillator.

There is a separate calibration byte for the internal oscillator in 4.8 MHz mode of operation but this data is not loaded automatically. The hardware always loads the 9.6 MHz calibration data during reset. To use separate calibration data for the oscillator in 4.8 MHz mode the OSCCAL register must be updated by firmware. The calibration data for 4.8 MHz operation is located in the high byte at address 0x01 of the signature area.

@stefanrueger
Copy link
Owner

@mcuee Thanks for the explanation. OK, so the calibration value can come from the second calibration byte of the signature area. The suggestion is that some external mechanism (AVRDUDE?) reads that byte and copies it to flash, so that the bootloader does not need to go to the expense of reading the actual (second) calibration byte. Alternatively, some external calibration mechanism could measure the actual internal 4.8 MHz clock (you rig up your chip-scale atomic clock (check out the purchase price here) to twiddle a pin once a second, upload a sketch that computes the perfect calibration byte and stores that in the flash location).

I was thinking aloud about the workflow and where to put that calibration value (a fixed flash location outside the bootloader, a fixed flash location within the bootloader, encoded as part of an ldi r24,... command in a bootloader subroutine etc) and what to do then. If you rig up an external clock source (a little quartz for a few pence will do as well :) to measure the frequency of the target AVR's oscillator with a sketch then you might as well select the right bootloader and burn that - rather than burning that calibration value to flash.

@MCUdude
Copy link
Author

MCUdude commented Apr 10, 2023

Yes, what I was trying to say was that there is currently no easy way of getting hold of the second byte in the calibration register. If it was, it would be cool if it was possible to "inject" this into the existing bootloader in flash somehow. But even this value isn't always spot on, and the user would still have to choose a bootloader to match their now "slightly off" oscillator.

BTW I'm pretty much finished implementing Urboot for MicroCore! I'll have to do a bit more testing (I can't get the bootloader to work when running at the internal 128kHz WDT oscillator), but I think I'm ready for a new MicroCore release very soon.

Thank you so much @stefanrueger for your help, knowledge and last but not least, patience! A reliable bootloader for the ATtiny13 (or any classic ATtiny for that matter) would still be a far-fetched dream if it wasn't for your excellent Urboot bootloader.

image

@stefanrueger
Copy link
Owner

stefanrueger commented Apr 10, 2023

This bootloader menu looks so cool! Note I have in the meantime pushed +/- 8.75% too.

running at the internal 128kHz WDT oscillator

The intl 128 kHz WDT oscillator too is notoriously off its nominal frequency. When I build a prototype PCB one of the things I routinely measure is the duration of the 1024 ms watchdog timeout against a GPS pps signal. My sample of 43 parts (mostly m328p) resulted in an average of 1049.6 ms +/- 39.33 ms (min of the sample was 979.8 ms and max was 1153.5 ms). Sooo, in my experience the frequency (not time) was typically between -6% and +1.4% off. My sample could be correlated by buying 10 pieces at a time (or so). The extremes were between -11.1% and +4.3% off. That asymmetry chimes with your experience of the internal RCs.

@SpenceKonde
Copy link

SpenceKonde commented Apr 10, 2023 via email

@stefanrueger
Copy link
Owner

ulp = ultra low precision? 😉

@stefanrueger
Copy link
Owner

stefanrueger commented Apr 10, 2023

I think the data sheets typically say sth about 10% for the factory calibrated(!) internal RCs, but I also suspect that these intervals are deliberately wider than reality. So would expect WDT to have similar behaviour in practice (same technolgy?)

@SpenceKonde
Copy link

SpenceKonde commented Apr 10, 2023 via email

@stefanrueger
Copy link
Owner

no easy way of getting hold of the second byte in the calibration register

So, unlike say the m328p, it's not possible to read the calibration bytes from software. Here how it's done for Atmega328P:
Screenshot from 2023-04-12 11-07-46

The data sheet for the t13a only explains how to read the lock bits, the fuse low and fuse high byte from software, so presumably it's not possible to read the calibration byte from software. The longer I look at this the more I think that it is a bug in the design to allow fuses to be set to 4.8 MHz but not load the existing calibration byte for this into OSCCAL during reset.

It might be possible to create bespoke bootloaders just for the t13/a internal 4.8 MHz oscillator but then there would need to be an agreed workflow for this and an agreed position of the byte in flash (which could be encoded into an ldi r24, %[calibrationvalue] as indicated above at bootloader start, so that would extend the bootloader only by 6 bytes).

@mcuee
Copy link

mcuee commented Apr 12, 2023

@MCUdude

Just wondering why you say "there is currently no easy way of getting hold of the second byte in the calibration register"?

I can see that avrdude can do it.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c usbtiny -p t13a -qqt
avrdude> dump calibration
0000  60 65                                             |`e              |

avrdude> quit

@mcuee
Copy link

mcuee commented Apr 12, 2023

The data sheet for the t13a only explains how to read the lock bits, the fuse low and fuse high byte from software, so presumably it's not possible to read the calibration byte from software.

@stefanrueger

I am not so sure what you mean by "from software". But at least avrdude can read the two calibration bytes.

@MCUdude
Copy link
Author

MCUdude commented Apr 12, 2023

Yes, but the microcontroller can't read calibration byte two on its own. It has to be done using an external programmer, and the value has to either be written to Flash or EEPROM. Urboot can't utilize this second byte by itself. A programmer has to read it, and then write the value somewhere so that the bootloader can utilize it without using too much flash space.

A procedure like this would be difficult to implement in Arduino IDE's platform.txt.

@mcuee
Copy link

mcuee commented Apr 12, 2023

Yes, but the microcontroller can't read calibration byte two on its own. It has to be done using an external programmer, and the value has to either be written to Flash or EEPROM. Urboot can't utilize this second byte by itself. A programmer has to read it, and then write the value somewhere so that the bootloader can utilize it without using too much flash space.

A procedure like this would be difficult to implement in Arduino IDE's platform.txt.

I see.

I think @stefanrueger's idea of template bootloader will help here. The user needs to use a programmer and use avrdude to read the second calibration byte.

Then the template bootloader can be modified to utilize this value (input by the user). If it is difficult to do within MicroCore, this can be done by a utility which can be part of urboot. This utility can even integrate the first part (calling avrdude to read the second calibration byte).

@stefanrueger
Copy link
Owner

stefanrueger commented Apr 12, 2023

the microcontroller can't read calibration byte two on its own

This is exactly why it makes Microchip's documentation so bitter. They say " To use separate calibration data for the oscillator in 4.8 MHz mode the OSCCAL register must be updated by firmware. The calibration data for 4.8 MHz operation is located in the high byte at address 0x01 of the signature area." Buy they don't say "It's actually impossible for the firmware to read the calibration data" and leave every single user to pick up the pieces for their failure to copy the 4.8 MHz calibration value into the OSCCAL register during reset when the fuses run a different 4.8 MHz oscillator.

can be done by a utility which can be part of urboot

I don't think this is a reasonable effort and a reasonable avenue for the urboot project. The project will be better off concentrating on other issues. If someone really wants to use 4.8 MHz for a project they can set the fuses to internal 9.6 MHz (which gets the factory calibration byte loaded correctly at reset) and then set the system clock prescaler to 2 at the startup() of their sketch. The bootloader would run at 9.6 MHz (b/c it wouldn't have the code for dividing down the system clock). The only situation where this would be out of specs is for a voltage below 2.8 V where 9.6 MHz is at the verge of "overclocking".

@mcuee
Copy link

mcuee commented Apr 12, 2023

I don't think this is a reasonable effort and a reasonable avenue for the urboot project. The project will be better off concentrating on other issues.

Fair enough.

@stefanrueger
Copy link
Owner

Cannot think of anything more I could do for classic parts, so have released version u7.7.

It's been a quite positive experience to work with, in particular you @mcuee and @MCUdude on this project. I have implemented a few things that I probably wouldn't have had it not been suggested persistently by either of you (autobaud solved inspired by code from @nerdralph, repository of pre-compiled bootloaders, documentation, treating internal oscillators, find a way to deal with their notorious inaccuracy etc etc).

So thank you for that and staying alongside in that journey.

Closing this issue as completed.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants