Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
78b72ed
refactor set_watchdog_timer to 504 bytes
osamuaoki Apr 22, 2020
d7dc792
Add LED support, size 510 bytes
osamuaoki Apr 22, 2020
c6c09b6
Use Y+ for extended IO, size 506 bytes
osamuaoki Apr 22, 2020
039e30f
Save 2 bytes in the setup packet read loop
sigprof Aug 20, 2021
d1d66c0
Swap send_hid_descriptor and send_hid_report_descriptor
sigprof Aug 20, 2021
bdd1337
Save 2 bytes in the descriptor sending code
sigprof Aug 20, 2021
670c092
Move SET_CONFIGURATION in preparation for fallthrough
sigprof Aug 20, 2021
70ac55d
Save 2 bytes by using fallthrough for SET_CONFIGURATION
sigprof Aug 20, 2021
5167ef7
Move HANDLE_USB_CLAS_INTERFACE in preparation for fallthrough
sigprof Aug 20, 2021
11e4101
Save 2 bytes by using fallthrough for HANDLE_USB_CLAS_INTERFACE
sigprof Aug 20, 2021
7bae4e1
Save 2 bytes by using fallthrough for GET_DESCRIPTOR
sigprof Aug 20, 2021
1d9f425
Save 2 bytes by reusing the SET_ADDRESS code for SET_CONFIGURATION
sigprof Aug 20, 2021
4fb0292
Fix USB errors due to unconfigured interrupt in endpoint
sigprof Aug 23, 2021
0ed8c5a
Makefile: Use /dev/null instead of NUL, size 506 bytes
sigprof Aug 20, 2021
7341819
Save 4 bytes by simplifying wait_finish_transfer
sigprof Aug 20, 2021
0c235b3
Save 4 bytes by refactoring UEINTX handling subroutines
sigprof Aug 20, 2021
990ad5c
Revert "Add LED support ...", size 492 bytes
osamuaoki Dec 8, 2021
aef1b8b
Save 2 bytes by refactoring the GET_DESCRIPTOR code
sigprof Aug 24, 2021
dc90560
Move SET_HID_REPORT in preparation for fallthrough
sigprof Aug 24, 2021
9a22230
Save 2 bytes by using fallthrough for SET_HID_REPORT
sigprof Aug 24, 2021
b6a4be0
Save 4 bytes in the USB detach code
sigprof Sep 4, 2021
01764e0
Save 2 bytes in the USBCON init code
sigprof Sep 4, 2021
052adef
Save 2 bytes in the HOST_TO_DEVICE parsing code
sigprof Sep 4, 2021
43969ae
Save 2 bytes in the DEVICE_TO_HOST parsing code
sigprof Sep 4, 2021
ff754ab
Save 6 bytes by refactoring UNHANDLED_SETUP_REQUEST usage, size 470 b…
sigprof Sep 4, 2021
02a9bf3
Save 2 bytes in the flash write loop
sigprof Aug 25, 2021
00c1f8b
Add bootloader overwrite protection
sigprof Aug 25, 2021
2d4bd1e
LED support: MACRO for onboard LED
osamuaoki Dec 8, 2021
fcdcc1a
LED support: Initialize LED port and OFF
osamuaoki Dec 8, 2021
f7aab3e
LED support: Turn on LED before sending descriptor
osamuaoki Dec 8, 2021
3958209
LED support: Turn off LED before exiting bootloader, size 476 bytes
osamuaoki Dec 8, 2021
7125757
Fix a typo in the comment for set_watchdog_timer
osamuaoki Dec 8, 2021
b44de33
Add comment on rONE
osamuaoki Dec 8, 2021
1f9f8ed
convert Makefile to UTF-8
osamuaoki Mar 31, 2020
f069340
Update README.md for osamu's site
osamuaoki Apr 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
# WinAVR Makefile Template written by Eric B. Weddington, J�rg Wunsch, et al.
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
#
# Released to the Public Domain
#
Expand Down Expand Up @@ -636,11 +636,11 @@ clean_list :


# Create object files directory
$(shell mkdir $(OBJDIR) 2>/NUL)
$(shell mkdir $(OBJDIR) 2>/dev/null)


# Include the dependency files.
-include $(shell mkdir .dep 2>NUL) $(wildcard .dep/*)
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)


# Listing of phony targets.
Expand Down
93 changes: 82 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
# nanoBoot
# nanoBoot (w/LED)

[![Build Status](https://travis-ci.org/volium/nanoBoot.svg?branch=master)](https://travis-ci.org/volium/nanoBoot)
## HID bootloader with LED support & overwrite protection

This repository contains the source code for the USB HID-based bootloader for ATmegaXXU4 family of devices.
<!-- CI not yet used by osamu: [![Build Status](https://travis-ci.org/volium/nanoBoot.svg?branch=master)](https://travis-ci.org/volium/nanoBoot) -->

The name *nanoBoot* comes from the fact that the compiled source fits in the smallest available boot size on the ATMegaXXu4 devices, 256 words or 512 bytes. The code is based on Dean Camera's [LUFA](https://github.com/abcminiuser/lufa) USB implementation, but it is **EXTREMELY** streamlined, size-optimized and targeted for the [ATmega16U4](http://www.atmel.com/devices/atmega16u4.aspx) and [ATmega32u4](http://www.atmel.com/devices/atmega32u4.aspx) devices; I had to make quite a few hardware assumptions, mostly to the fuse settings related to clock configuration for things to be as compact as possible, but the code still allows for some flexibility.
This repository [nanoBoot w/LED](https://github.com/osamuaoki/nanoBoot) contains the source code for the USB HID-based bootloader for ATmega32U4 family of devices with **LED support and overwrite protection**.

It's very likely that a few sections can be rewritten to make it even smaller, and the ultimate goal is to support EEPROM programming as well, although that would require changes to the host code.
The name **nanoBoot** comes from the fact that the compiled source fits in the smallest available boot size on the ATMega32u4 devices, 256 words or **512 bytes**. The code is based on Dean Camera's [LUFA](https://github.com/abcminiuser/lufa) USB implementation, but it is **EXTREMELY** streamlined, size-optimized and targeted for the [ATmega16U4](http://www.atmel.com/devices/atmega16u4.aspx) and [ATmega32u4](http://www.atmel.com/devices/atmega32u4.aspx) devices.

The current version (commit #[d0ea26b](https://github.com/volium/nanoBoot/commit/d0ea26bb01e764340dc8ad7b473ad98cefdb52eb)) is supported as-is in the 'hid_bootloader_loader.py' script that ships with [LUFA-151115](https://github.com/abcminiuser/lufa/releases/tag/LUFA-151115), and is exactly 506 bytes long.
Initial and major portion of manual assembly code optimization efforts were performed by [volium](https://github.com/volium) and published as the original [volium/nanoBoot](https://github.com/volium/nanoBoot).

Some tweaks were performed by osamu to allow arbitrary setting for CKDIV8 fuse and it was merged to the upstream.

There were a lot of manual size optimization and program size check feature addition by [sigprof](https://github.com/sigprof) and published as [sigprof/nanoBoot](https://github.com/sigprof/nanoBoot)

Osamu gathered all useful code and made a linear history commits with his LED support added as **led** branch here at [osamuaoki/nanoBoot](https://github.com/osamuaoki/nanoBoot).

There are some hardware and usage assumptions to the fuse settings which keep this bootloader as compact as possible. For the best result:

* Application should clear r3 register before calling soft reset (0x7F00) to load a new program by this nanoBoot bootloader.

The current version (2021-12-08) will tested manually with the compiled `hid_bootloader_cli.c` from [LUFA](https://github.com/abcminiuser/lufa) on Debian GNU/Linux 12 (bookworm/testing).

Required packages on Debian GNU/Linux system: `gcc-avr`, `avr-libc`, `binutils-avr`, `libusb-dev`, `build-essential`, `git`

## HW assumptions:

* CLK is 16 MHz Crystal and fuses are setup correctly to support it:
* Select Clock Source (CKSEL3:CKSEL0) fuses are set to Extenal Crystal, CKSEL=1111 SUT=11
* Divide clock by 8 fuse (CKDIV8) can be set to either 0 or 1
* Divide clock by 8 fuse (CKDIV8) can be any value.
* 16 MHz operation needs 5V VCC for MCU
* Bootloader starts on reset; Hardware Boot Enable fuse is configured, HWBE=0
* Boot Flash Size is set correctly to 256 words (512 bytes), StartAddress=0x3F00, BOOTSZ=11
* Device signature = 0x1E9587
Expand All @@ -24,10 +39,66 @@ The current version (commit #[d0ea26b](https://github.com/volium/nanoBoot/commit
* hfuse memory = 0xD6 (EESAVE=0, BOOTRST=0)
* efuse memory = 0xC7 (=0xF7, No BOD)

* Alternatively, BOD can be used to ease CKSEL-SUT setting requirements to
allow teensy-like FUSE settings:
* Alternatively BOD can be used to ease CKSEL-SUT setting requirements to
allow teensy like FUSE setting
* lfuse memory = 0x5F (CKDIV8=0, 16CK + 0ms)
* hfuse memory = 0xDF (EESAVE=1, BOOTRST=1)
* efuse memory = 0xF4 (BOD=2.4V)
* efuse memory = 0xC4 (=0xF4, BOD=2.4V)

* LED on D6 port for Teensy 2.0 (Configurable in #define for any board)

## Usage

Please install this bootloader `nanoBoot.hex` using the ISP connected programmer (e.g. AVRISP mkII).

```
$ sudo avrdude -v -p atmega32u4 -c avrisp2 -Pusb -e -U flash:w:nanoBoot.hex \
-U lfuse:w:0x5f:m -U hfuse:w:0xdf:m -U efuse:w:0xc4:m
```

You can start this bootloader by connecting the board to the PC with USB cable and pressing the RESET button. It is good idea to monitor the PC's USB connection.

```
$ watch lsusb
```

If this bootloader is started, you should see "Atmel".

Please note, now this bootloader turns on LED just before sending device ID. Thus monitoring of USB is now optional.

(If LED doesn't turn on even after 10 second wait for any reason, press the RESET button again.)

Then program MCU with, e.g., a `LED.hex` firmware as:

```
$ sudo hid_bootloader_cli -mmcu=atmega32u4 -v LED.hex
```
Please note, this bootloader turns off LED upon finish programming.

(Pressing the RESET button during active bootloader execution seems to halt the bootloader. This seems to be the reason you need to press the RESET button again.)

For your convenience, pre-compiled HEX file and associated scripts are provided under the `precompile` directory.

## Configuration

Only the first configuration choice is tested with a Teensy 2.0 compatible board.

In `Makefile`:

* `F_CPU = 16000000` or `F_CPU = 8000000`
* `BOOT_START_OFFSET = 0x7E00` or any valid ones for MCU

In `nanoBoot.S`:

* Adjust `#define LED_BIT`, `#define LED_CONF`, and `#define LED_PORT` for each board. Default is Teensy 2.0 setting.

Code for LED ON/OFF needs to be adjusted for board such as Pro Micro on which IO pin is connected to LED-cathode side and LED-anode side is connected to Vcc(5V/3V) side.

## Documentation

"The documentation is part of the source code itself, and even though some people may find it extremely verbose, I think that's better than lack of documentation; after all, assembly can be hard to read sometimes... ohhh yes, in case that was not expected, this is all written in pure GAS (GNU Assembly), compiled using the [Atmel AVR 8-bit Toolchain](http://www.atmel.com/tools/atmelavrtoolchainforwindows.aspx)." (per volium)

"The elegant programming techniques presented by volium with detailed comments were very enlightening for me to get started. It's delightful for me to read. Don't miss it!" (per osamu)

The documentation is part of the source code itself, and even though some people may find it extremely verbose, I think that's better than lack of documentation; after all, assembly can be hard to read sometimes... ohhh yes, in case that was not expected, this is all written in pure GAS (GNU Assembly), compiled using the [Atmel AVR 8-bit Toolchain](http://www.atmel.com/tools/atmelavrtoolchainforwindows.aspx).
* [AVR Instruction Set Manual](http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf)
* [ATmega16U4, ATmega32U4 - Complete Datasheet](http://ww1.microchip.com/downloads/en/devicedoc/atmel-7766-8-bit-avr-atmega16u4-32u4_datasheet.pdf)
Loading