aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorSelene ToyKeeper2023-11-02 11:05:02 -0600
committerSelene ToyKeeper2023-11-02 11:05:02 -0600
commitffd9f90898699df87bf9cb283aaa724774bd91bd (patch)
treee8b6a33a5814d0b1adc6c630043650dfc19ee959 /bin
parentadded a "tactical mode" on "Off -> 6C" (diff)
parentslightly longer smooth-off animation, to make on and off feel symmetrical (diff)
downloadanduril-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-xbin/build.sh6
-rwxr-xr-xbin/flash-1616.py78
-rwxr-xr-xbin/level_calc.py45
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: