diff options
| author | Selene ToyKeeper | 2023-11-02 11:05:02 -0600 |
|---|---|---|
| committer | Selene ToyKeeper | 2023-11-02 11:05:02 -0600 |
| commit | ffd9f90898699df87bf9cb283aaa724774bd91bd (patch) | |
| tree | e8b6a33a5814d0b1adc6c630043650dfc19ee959 /bin | |
| parent | added a "tactical mode" on "Off -> 6C" (diff) | |
| parent | slightly longer smooth-off animation, to make on and off feel symmetrical (diff) | |
| download | anduril-ffd9f90898699df87bf9cb283aaa724774bd91bd.tar.gz anduril-ffd9f90898699df87bf9cb283aaa724774bd91bd.tar.bz2 anduril-ffd9f90898699df87bf9cb283aaa724774bd91bd.zip | |
merged multi-channel branch with a major refactor and half a year of updates
Diffstat (limited to '')
| -rwxr-xr-x | bin/build.sh | 6 | ||||
| -rwxr-xr-x | bin/flash-1616.py | 78 | ||||
| -rwxr-xr-x | bin/level_calc.py | 45 |
3 files changed, 121 insertions, 8 deletions
diff --git a/bin/build.sh b/bin/build.sh index 4cb03b4..499b5bd 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -27,9 +27,11 @@ fi export MCU=attiny$ATTINY export CC=avr-gcc +export CPP=avr-cpp export OBJCOPY=avr-objcopy export DFPFLAGS="-B $ATTINY_DFP/gcc/dev/$MCU/ -I $ATTINY_DFP/include/" -export CFLAGS="-Wall -g -Os -mmcu=$MCU -c -std=gnu99 -fgnu89-inline -fwhole-program -DATTINY=$ATTINY -I.. -I../.. -I../../.. -fshort-enums $DFPFLAGS" +export CFLAGS=" -Wall -g -Os -mmcu=$MCU -c -std=gnu99 -fgnu89-inline -fwhole-program -DATTINY=$ATTINY -I.. -I../.. -I../../.. -fshort-enums $DFPFLAGS" +export CPPFLAGS="-Wall -g -Os -mmcu=$MCU -C -std=gnu99 -fgnu89-inline -fwhole-program -DATTINY=$ATTINY -I.. -I../.. -I../../.. -fshort-enums $DFPFLAGS" export OFLAGS="-Wall -g -Os -mmcu=$MCU -mrelax $DFPFLAGS" export LDFLAGS="-fgnu89-inline" export OBJCOPYFLAGS='--set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex --remove-section .fuse' @@ -45,6 +47,8 @@ function run () { if [ x"$?" != x0 ]; then exit 1 ; fi } +run $CPP $OTHERFLAGS $CPPFLAGS -o foo.cpp $PROGRAM.c +grep -a -E -v '^#|^$' foo.cpp > $PROGRAM.cpp ; rm foo.cpp run $CC $OTHERFLAGS $CFLAGS -o $PROGRAM.o -c $PROGRAM.c run $CC $OFLAGS $LDFLAGS -o $PROGRAM.elf $PROGRAM.o run $OBJCOPY $OBJCOPYFLAGS $PROGRAM.elf $PROGRAM.hex diff --git a/bin/flash-1616.py b/bin/flash-1616.py new file mode 100755 index 0000000..f431b3a --- /dev/null +++ b/bin/flash-1616.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +# Use with Python3, make sure to have the pymcuprog module installed (via pip) + +# Read out the pymcuprog version +from pymcuprog.version import VERSION as pymcuprog_version +print("pymcuprog version {}".format(pymcuprog_version)) + + +# List out the available ports +import serial.tools.list_ports as ls; +#ports = ls.comports() +ports = [] +for p in ls.comports(): + if "COM" in p.device or "USB" in p.device: + ports.append(p) + +if len(ports) == 0: + print("No serial ports found, exiting") + exit() +elif len(ports) == 1: + print("Found one serial port:", ports[0].device, "-", ports[0].description) + port = ports[0].device +else: # found more than one serial port + print("Found multiple serial ports:") + for p in ports: + print(" *", p.device, "-", p.description) + print("Which serial port would you like to use? (default: " + ports[0].device + ") ", end="") + port = input() + if not port: + port = ports[0].device + + +import sys +args = sys.argv +if len(args) == 1: # only the program name, no arguements: ask for the hex file + print("Which hex file would you like to flash? ", end="") + hexfile = input() +else: + hexfile = args[1] + + +# pymcuprog uses the Python logging module +import logging +logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.WARNING) + +# Configure the session +from pymcuprog.backend import SessionConfig +sessionconfig = SessionConfig("attiny1616") + +# Instantiate Serial transport (only 1 tool connected) +from pymcuprog.toolconnection import ToolSerialConnection +transport = ToolSerialConnection(serialport=port) + +# Instantiate backend +from pymcuprog.backend import Backend +backend = Backend() + +# Connect to tool using transport +backend.connect_to_tool(transport) + +# Start the session +backend.start_session(sessionconfig) + +# Read the target device_id +device_id = backend.read_device_id() +print("Device ID is {0:06X}".format(int.from_bytes(device_id, byteorder="little"))) + +# Erase the device, write the hexfile, and verify the write +backend.erase() +print("Memories erased.") +print("Writing hex file to the device... ") +backend.write_hex_to_target(hexfile) +print("Writing complete.") +print("Verifying the write... ") +verify_status = backend.verify_hex(hexfile) +if verify_status is True: + print("Verification successful!") + diff --git a/bin/level_calc.py b/bin/level_calc.py index 1ab507c..8958a15 100755 --- a/bin/level_calc.py +++ b/bin/level_calc.py @@ -19,6 +19,7 @@ def main(args): cli_answers = [] global max_pwm, max_pwms, dyn_pwm pwm_arg = str(max_pwm) + clock_arg = '8:16:1' # quarter/half speed levels and rise time i = 0 while i < len(args): @@ -26,6 +27,9 @@ def main(args): if a in ('--pwm',): i += 1 pwm_arg = args[i] + elif a in ('--clock',): + i += 1 + clock_arg = args[i] else: #print('unrecognized option: "%s"' % (a,)) cli_answers.append(a) @@ -83,6 +87,13 @@ def main(args): max_pwm = val max_pwms = [val] * answers.num_levels + if clock_arg: + parts = clock_arg.split(':') + answers.quarterspeed_level, answers.halfspeed_level = [int(x) for x in parts[:2]] + answers.rise_time_base = float(parts[2]) + else: + answers.quarterspeed_level, answers.halfspeed_level, answers.rise_time_base = 0,0,0 + global ramp_shape ramp_shape = answers.ramp_shape @@ -148,6 +159,7 @@ def multi_pwm(answers, channels): channel.modes = [] for i in range(answers.num_levels): goal_vis, goal_lm = goals[i] + rise_time = calc_rise_time(i, answers) # This channel already is maxed out if goal_lm >= (channel.lm_max + channel.prev_lm): # This shouldn't happen, the FET is assumed to be the highest channel @@ -176,19 +188,20 @@ def multi_pwm(answers, channels): lm_needed = goal_lm - channel.prev_lm - channel.lm_min pwm_top = max_pwms[i] - pwm_avail = pwm_top - channel.pwm_min + pwm_avail = pwm_top - channel.pwm_min - rise_time pwm_needed = pwm_avail * lm_needed / lm_avail + #pwm_needed = min(pwm_needed, pwm_avail) if dyn_pwm and (pwm_top > max_pwm): this_step = max(1, math.floor(pwm_needed)) next_step = this_step + 1 fpart = pwm_needed - math.floor(pwm_needed) correction = (next_step - fpart) / next_step pwm_top = int(pwm_avail * correction) + channel.pwm_min - pwm_avail = pwm_top - channel.pwm_min + pwm_avail = pwm_top - channel.pwm_min - rise_time pwm_needed = pwm_avail * lm_needed / lm_avail max_pwms[i] = pwm_top # save the result - pwm = max(0, pwm_needed + channel.pwm_min) + pwm = max(0, pwm_needed + channel.pwm_min + rise_time) channel.modes.append(pwm) # how close did we get? #ptop = int(round(pwm - channel.pwm_min)) @@ -206,13 +219,18 @@ def multi_pwm(answers, channels): for i in range(answers.num_levels): goal_vis, goal_lm = goals[i] pwms = [] + rise_time = calc_rise_time(i, answers) for c, channel in enumerate(channels): + #top = channel.modes[i] - channel.pwm_min - rise_time top = channel.modes[i] - channel.pwm_min if top < 0: top = 0 - bot = max_pwms[i] - channel.pwm_min - ratio = 100 * (int(round(top)) / float(bot)) - top, bot = channel.modes[i], max_pwms[i] - pwms.append('%.2f/%i (%.3f%%)' % (top, bot, ratio)) + #bot = max_pwms[i] - channel.pwm_min - rise_time + bot = max_pwms[i] + #ratio = 100 * (int(round(top)) / float(bot)) + topf, bot = channel.modes[i], max_pwms[i] + top = int(round(topf)) + ratio = 100 * top / float(bot) + pwms.append('(%.2f) %i/%i (%.3f%%)' % (topf, top, bot, ratio)) if (ratio < prev_ratios[c]) and (ratio > 0): pwms.append('WARN') prev_ratios[c] = ratio @@ -240,6 +258,19 @@ def multi_pwm(answers, channels): print('Ch%i max: %i (%.2f/%s)' % (cnum, i, channel.modes[i-1], max_pwms[i])) +def calc_rise_time(i, answers): + base = answers.rise_time_base + + if (i+1) < answers.quarterspeed_level: + rise_time = base / 4.0 + elif (i+1) < answers.halfspeed_level: + rise_time = base / 2.0 + else: + ratio = 1.0 - math.sqrt((i - base) / (answers.num_levels - base)) + rise_time = answers.rise_time_base * ratio + return rise_time + + def get_value(text, default, args): """Get input from the user, or from the command line args.""" if args: |
