Skip to content

Instantly share code, notes, and snippets.

@Duckle29
Last active July 28, 2018 11:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Duckle29/e4cd8d08d3e31b7b730a5238f214e07b to your computer and use it in GitHub Desktop.
Save Duckle29/e4cd8d08d3e31b7b730a5238f214e07b to your computer and use it in GitHub Desktop.
RPi avr flasher
#!/usr/bin/python3
avrdude_path = '/usr/bin/avrdude'
avrdude_timeout = 100 # Timeout in seconds before killing avrdude
bootloader_hex = '/home/pi/hexes/vitamins_included_rev2_default_production.hex'
low_fuse = '0x5E'
high_fuse = '0xD9'
ext_fuse = '0xC3'
lock_fuse = '0x3F'
log_file = '/home/pi/log'
# Pins
pin_button = 22 # Pin 15
pin_led_good = 17 # Pin 11
pin_led_bad = 27 # Pin 13
pin_oled_rst = 23 # Pin 16
import subprocess
import time
import RPi.GPIO as GPIO
import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
# Setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(pin_button, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_led_bad, GPIO.OUT)
GPIO.setup(pin_led_good, GPIO.OUT)
GPIO.setup(pin_oled_rst, GPIO.OUT)
disp = Adafruit_SSD1306.SSD1306_128_64(rst=pin_oled_rst, i2c_address=0x3C)
disp.begin()
state = 0
#### Display stuff
# Clear display.
disp.clear()
disp.display()
# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
image = Image.new('1', (width, height))
# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)
# Draw a black filled box to clear the image.
draw.rectangle((0,0,width,height), outline=0, fill=0)
# Draw some shapes.
# First define some constants to allow easy resizing of shapes.
padding = -2
top = padding
bottom = height-padding
# Move left to right keeping track of the current x position for drawing shapes.
x = 0
# Load default font.
font = ImageFont.load_default()
#### End of display stuff
def restart():
command = ["/usr/bin/sudo", "/sbin/reboot"]
process = subprocess.Popen(command, stdout=subprocess.PIPE)
output = process.communicate()[0]
print(output)
def shutdown():
command = ["/usr/bin/sudo", "/sbin/shutdown -h 0"]
process = subprocess.Popen(command, stdout=subprocess.PIPE)
output = process.communicate()[0]
print(output)
def drawScreen(x, image, lines):
# Draw a black filled box to clear the image.
draw.rectangle((0,0,width,height), outline=0, fill=0)
for idx, line in enumerate(lines):
draw.text((x,top+(8*idx)), line, font=font, fill=255)
disp.image(image)
disp.display()
def flash(avrdude_path, hex_path,log_file,ext_fuse,high_fuse,low_fuse,lock_fuse, timeout):
command = "{} -p m32u4 -c linuxspi -P /dev/spidev0.0 -b 4000000 -U flash:w:{}:a -U lfuse:w:{}:m -U hfuse:w:{}:m -U efuse:w:{}:m -U lock:w:{}:m &>{}".format(avrdude_path, hex_path, low_fuse, high_fuse, ext_fuse, lock_fuse, log_file)
command = [avrdude_path,
"-p", "m32u4",
"-c", "linuxspi",
"-P", "/dev/spidev0.0",
"-b", "4000000",
"-U", "flash:w:{}".format(hex_path),
"-U", "lfuse:w:{}:m".format(low_fuse),
"-U", "hfuse:w:{}:m".format(high_fuse),
"-U", "efuse:w:{}:m".format(ext_fuse),
"-U", "lock:w:{}:m".format(lock_fuse)
]
lines = []
start = time.time() # Time used to timeout avrdude
P_flash = subprocess.Popen(command, stdout=subprocess.PIPE)
while P_flash.poll == None:
if time.time() - start > timeout:
P_flash.kill()
raise SystemError("AVRDUDE timed out")
for line in P_flash.stdout:
if "1 bytes of efuse verified" in line:
lines.append("EFUSE : OK")
print("EFUSE : OK")
elif "1 bytes of hfuse verified" in line:
lines.append("HFUSE : OK")
print("HFUSE : OK")
elif "1 bytes of lfuse verified" in line:
lines.append("LFUSE : OK")
print("LFUSE : OK")
elif "not responding" in line:
lines.append("ERROR")
print("ERROR flashing: {}").format(line)
raise SystemError("Error flashing: {}".format(line))
drawScreen(x, image, lines)
time.sleep(0.1)
return True
while True:
lines = ["Ready to flash", "Place probe on board", "Push button to flash"]
if not GPIO.input(pin_button):
try:
if flash(avrdude_path, bootloader_hex,log_file,ext_fuse,high_fuse,low_fuse,lock_fuse, avrdude_timeout):
GPIO.output(pin_led_good, GPIO.HIGH)
GPIO.output(pin_led_bad, GPIO.LOW)
except SystemError as e:
print("Error flashing: {}".format(e))
lines = []
lines.append("Error flashing board", "Try again")
GPIO.output(pin_led_good, GPIO.LOW)
GPIO.output(pin_led_bad, GPIO.HIGH)
drawScreen(x, image, lines)
time.sleep(0.01)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment