Skip to content

Commit

Permalink
Added updiprog
Browse files Browse the repository at this point in the history
  • Loading branch information
jcoffland committed Jun 30, 2021
1 parent cfb021e commit a559b78
Show file tree
Hide file tree
Showing 15 changed files with 1,955 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/updiprog/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/updiprog
/build
25 changes: 25 additions & 0 deletions src/updiprog/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
BSD 2-Clause License

Copyright (c) 2018, Alex Kiselev
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 changes: 28 additions & 0 deletions src/updiprog/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
TARGET=updiprog

SRC := $(wildcard src/*.c)
OBJ := $(patsubst src/%.c,build/%.o,$(SRC))

CFLAGS += -O3 -Wall -Werror -Isrc
CFLAGS += -MD -MP -MT $@ -MF build/dep/$(@F).d


all: $(TARGET)

$(TARGET): $(OBJ)
$(CC) -o $@ $(OBJ) $(LDFLAGS)

build/%.o: src/%.c
@mkdir -p $(shell dirname $@)
$(CC) $(CFLAGS) -c -o $@ $<

tidy:
rm -f *~ \#*

clean: tidy
rm -rf build $(TARGET)

.PHONY: all tidy clean

# Dependencies
-include $(shell mkdir -p build/dep) $(wildcard build/dep/*.d)
112 changes: 112 additions & 0 deletions src/updiprog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# updiprog

This is UPDI programming software for AVR microcontrollers. It was based on the
code at https://github.com/Polarisru/updiprog but has undergone a lot of
restructuring and has speed and reliability improvements and additional features.
However, this version does not work on Windows.

```
Vcc Vcc
+-+ +-+
| |
+---------------------+ | | +--------------------+
| Serial port +-+ +-+ AVR device |
| | +----------+ | |
| TX +------+ 1k +---------+ UPDI |
| | +----------+ | | |
| | | | |
| RX +----------------------+ | |
| | | |
| +--+ +--+ |
+---------------------+ | | +--------------------+
+-+ +-+
GND GND
```

# Features
- Read/write flash memory
- Read/write fuses
- Chip erase
- Chip reset
- Read/write up to 1Gbps
- Autodetection using device signature
- CRC checking

## CRC Check
You can enable CRC checking with the ``-x`` option. With this option enabled
during a FLASH write updiprog will do the following:

* Read the HEX file
* Compute a CRC-16-CCITT
* Read the last 2-bytes of FLASH
* If the last 2-bytes match the CRC, stop
* Otherwise program the FLASH
* Write the CRC to the last 2-bytes of FLASH

The end result is that with the ``-x`` option updiprog will not reprogram the
chip if the CRC indicates that the programmed firmware is the same.

The programmed CRC can also be used with the AVR's CRCSCAN feature. With
CRCSCAN enabled, the chip will not run if the CRC at the end of FLASH does not
match the contents of FLASH memory.

# Options
```
updiprog [OPTIONS]
OPTIONS:
-b BAUDRATE - Serial port speed (default=115200)
-d DEVICE - Target device (optional)
-c PORT - Serial port (e.g. /dev/ttyUSB0)
-e - Chip erase
-R - Chip reset
-F - Read all fuses
-f FUSE VALUE - Write fuse
-r FILE.HEX - Hex file to read FLASH into
-w FILE.HEX - Hex file to write to FLASH
-x - Enable CRC checks
-v - Verbose logging
-h - Show this help screen and exit
```

# Supported devices
```
mega1608 mega1609 mega3208 mega3209 mega4808
mega4809 mega808 mega809 tiny1604 tiny1606
tiny1607 tiny1614 tiny1616 tiny1617 tiny1624
tiny1626 tiny1627 tiny202 tiny204 tiny212
tiny214 tiny3216 tiny3217 tiny402 tiny404
tiny406 tiny412 tiny414 tiny416 tiny417
tiny424 tiny426 tiny427 tiny804 tiny806
tiny807 tiny814 tiny816 tiny817 tiny824
tiny826 tiny827
```

# Examples
## Chip Erase
updiprog -c /dev/ttyUSB0 -e

## Program FLASH from HEX file
updiprog -c /dev/ttyUSB0 -w firmware.hex

## Program FLASH from HEX file at 1G BAUD
updiprog -c /dev/ttyUSB0 -w firmware.hex -b 1000000

## Read FLASH to HEX file
updiprog -c /dev/ttyUSB0 -r tiny_fw.hex

## Read all fuses:
updiprog -c /dev/ttyUSB0 -F

## Write 0x04 to fuse number 1 and 0x1b to fuse number 5
updiprog -c /dev/ttyUSB0 -f 1 0x04 -f 5 0x1b

## Program FLASH from HEX file at 1G BAUD with CRC check
updiprog -c /dev/ttyUSB0 -w firmware.hex -b 1000000 -x

## Erase the chip then program FLASH from HEX file at 1G BAUD
updiprog -c /dev/ttyUSB0 -e -w firmware.hex -b 1000000

## Chip Reset
updiprog -c /dev/ttyUSB0 -R
36 changes: 36 additions & 0 deletions src/updiprog/parse_atdf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env python3

import sys
from xml.etree import ElementTree as ET


for filename in sys.argv[1:]:
r = ET.parse(filename).getroot()

for i in r.findall('.//interface'):
if i.attrib['type'] == 'updi':
name = r.find('./devices/device').attrib['name'].lower()[2:]

for seg in r.findall('.//memory-segment'):
sname = seg.attrib['name']

if sname == 'FUSES': num_fuses = int(seg.attrib['size'], 0) - 1

if sname == 'MAPPED_PROGMEM':
flash_start = int(seg.attrib['start'], 0)
flash_size = int(seg.attrib['size'], 0)
page_size = int(seg.attrib['pagesize'], 0)

id = 0
for prop in r.findall('.//property-group[@name="SIGNATURES"]/property'):
i = int(prop.attrib['name'][9:])
id += int(prop.attrib['value'], 0) << (8 * (2 - i))

print(' {')
print(' "%s",' % name)
print(' 0x%06x,' % id)
print(' 0x%04x,' % flash_start)
print(' %d,' % flash_size)
print(' %d,' % page_size)
print(' %d' % num_fuses)
print(' },')
27 changes: 27 additions & 0 deletions src/updiprog/src/devices.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "devices.h"

#include <string.h>


device_t devices[] = {
#include "devices.dat"
{0} // Sentinel
};


device_t *devices_find(char *name) {
for (int i = 0; devices[i].name; i++)
if (strcmp(name, devices[i].name) == 0)
return &devices[i];

return 0;
}


device_t *devices_find_by_sig(uint32_t sig) {
for (int i = 0; devices[i].name; i++)
if (devices[i].sig == sig)
return &devices[i];

return 0;
}
Loading

0 comments on commit a559b78

Please sign in to comment.