@ -0,0 +1,399 @@ | |||||
#!/usr/bin/env python3 | |||||
import sys | |||||
import getopt | |||||
import glob | |||||
import serial | |||||
import struct | |||||
from tkinter import * | |||||
import matplotlib.figure as figure | |||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg | |||||
from datetime import datetime | |||||
def serial_ports(): | |||||
""" Lists serial port names | |||||
:raises EnvironmentError: | |||||
On unsupported or unknown platforms | |||||
:returns: | |||||
A list of the serial ports available on the system | |||||
""" | |||||
if sys.platform.startswith('win'): | |||||
ports = ['COM%s' % (i + 1) for i in range(256)] | |||||
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'): | |||||
# this excludes your current terminal "/dev/tty" | |||||
ports = glob.glob('/dev/tty[A-Za-z]*') | |||||
elif sys.platform.startswith('darwin'): | |||||
ports = glob.glob('/dev/tty.*') | |||||
else: | |||||
raise EnvironmentError('Unsupported platform') | |||||
result = [] | |||||
for port in ports: | |||||
try: | |||||
s = serial.Serial(port) | |||||
s.close() | |||||
result.append(port) | |||||
except (OSError, serial.SerialException): | |||||
pass | |||||
return result | |||||
#print(serial_ports()) | |||||
availableSerialPorts = serial_ports() | |||||
print('choose a port:') | |||||
counter = 0 | |||||
for port in availableSerialPorts: | |||||
print(' [' + str(counter) + '] ' + port) | |||||
counter += 1 | |||||
choosenPort = input('(type a number (0)) ') | |||||
if choosenPort == '': | |||||
choosenPortNumber = 0 | |||||
else: | |||||
choosenPortNumber = int(choosenPort) | |||||
counter = 0 | |||||
#serialPort = '/dev/pts/19' | |||||
serialPort = '/dev/ttyACM0' | |||||
serialPort = availableSerialPorts[choosenPortNumber] | |||||
try: | |||||
ser = serial.Serial(serialPort, 19200, serial.EIGHTBITS, serial.PARITY_NONE, serial.STOPBITS_ONE, timeout=0, writeTimeout=0) | |||||
except: | |||||
serialPort = '/dev/ttyACM1' | |||||
ser = serial.Serial(serialPort, 19200, serial.EIGHTBITS, serial.PARITY_NONE, serial.STOPBITS_ONE, timeout=0, writeTimeout=0) | |||||
#ser = serial.Serial() | |||||
#ser.port = "/dev/pts/19" | |||||
#ser.baudrate = 9600 | |||||
#ser.bytesize = serial.EIGHTBITS | |||||
#ser.parity = serial.PARITY_NONE | |||||
#ser.stopbits = serial.STOPBITS_ONE | |||||
#ser.timeout = None #block read | |||||
#ser.timeout = 1 #non-block read | |||||
#ser.timeout = 2 #timeout block read | |||||
#ser.xonxoff = False #disable software flow control | |||||
#ser.rtscts = False #disable hardware (RTS/CTS) flow control | |||||
#ser.dsrdtr = False #disable hardware (DSR/DTR) flow control | |||||
#ser.writeTimeout = 2 #timeout for write | |||||
#try: | |||||
# ser.open() | |||||
#except Exception as e: | |||||
# print('error open serial port: ' + str(e)) | |||||
# exit() | |||||
#ser.open() | |||||
#ser.write('hello world!') | |||||
#values = bytearray([4, 9, 62, 144, 56, 30, 147, 3, 210, 89, 111, 78, 184, 151, 17, 129]) | |||||
#ser.write(values) | |||||
#while True: | |||||
# print(ser.readline()) | |||||
#from serial import * | |||||
#from Tkinter import * | |||||
#serialPort = "/dev/ttyACM0" | |||||
#baudRate = 9600 | |||||
#ser = Serial(serialPort , baudRate, timeout=0, writeTimeout=0) #ensure non-blocking | |||||
logEnable = 0; | |||||
#~ temps = [20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220] | |||||
temps = [] | |||||
tick = 0 | |||||
#~ tickArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | |||||
tickArray = [] | |||||
tActArray = [] | |||||
tSetArray = [] | |||||
errArray = [] | |||||
errSumArray = [] | |||||
outOrigArray = [] | |||||
outArray = [] | |||||
def functionLog(): | |||||
global logEnable | |||||
if logEnable == 1: | |||||
sendSerial([0xa3]) | |||||
app.after(1000, functionLog) | |||||
def sendSerial(input): | |||||
print('send ' + str(len(input)) + ' byte(s): ' + str([hex(x) for x in input])) | |||||
data = bytearray([0xff, 0xf1]) | |||||
data.append(len(input)) | |||||
data.extend(bytearray(input)) | |||||
ser.write(data) | |||||
def processData(input): | |||||
global logEnable | |||||
global w | |||||
global temps | |||||
global tick | |||||
global tickArray | |||||
global tActArray | |||||
global tSetArray | |||||
global errArray | |||||
global errSumArray | |||||
global outOrigArray | |||||
global outArray | |||||
print(str([hex(x) for x in input])) | |||||
if input[0] == 0xa0: | |||||
if input[1] == 0x00: | |||||
log.insert(END, '> temp sensor 0 status: ' + str.join(':', ('%02x' % x for x in input[2:])) + '\n') | |||||
elif input[1] == 0x01: | |||||
log.insert(END, '> temp sensor 1 status: ' + str.join(':', ('%02x' % x for x in input[2:])) + '\n') | |||||
elif input[0] == 0x10: | |||||
if input[1] == 0x00: | |||||
log.insert(END, '> adc: wrong channel\n') | |||||
elif input[1] == 0x01: | |||||
log.insert(END, '> adc: start cartridge resistance measurement\n') | |||||
elif input[1] == 0x02: | |||||
log.insert(END, '> adc: start cartridge current measurement\n') | |||||
elif input[1] == 0x03: | |||||
log.insert(END, '> adc: start cartridge temperature measurement\n') | |||||
elif input[1] == 0x04: | |||||
log.insert(END, '> adc: start input voltage measurement\n') | |||||
elif input[1] == 0xff: | |||||
log.insert(END, '> adc: pending measurement\n') | |||||
elif input[0] == 0x11: | |||||
if input[1] == 0x01: | |||||
log.insert(END, '> raw_adc_cartridge_resistance: ' + str(((input[2] * 256) + input[3])) + '\n') | |||||
elif input[1] == 0x02: | |||||
log.insert(END, '> raw_adc_cartridge_current: ' + str(((input[2] * 256) + input[3])) + '\n') | |||||
elif input[1] == 0x03: | |||||
log.insert(END, '> raw_adc_cartridge_temperature: ' + str(((input[2] * 256) + input[3])) + '\n') | |||||
elif input[1] == 0x04: | |||||
log.insert(END, '> raw_adc_v_in: ' + str(((input[2] * 256) + input[3])) + '\n') | |||||
elif input[1] == 100: | |||||
# log.insert(END, '> raw_adc_cartridge_temperature_cycle: ' + str(((input[2] * 256) + input[3])) + '\n') | |||||
log.insert(END, '> raw_adc_cartridge_temperature_cycle: ' + str(round(((input[2] * 256) + input[3]) * 0.4833149757 + 35.1689715661)) + ' degC\n') | |||||
#~ tick = tick + 1 | |||||
#~ tickArray.append(tick) | |||||
#~ temps.append(((input[2] * 256) + input[3]) * 0.4833149757 + 35.1689715661) | |||||
#~ tickArray = tickArray[-200:] | |||||
#~ temps = temps[-200:] | |||||
#~ ax1.clear() | |||||
#~ ax1.set_ylim(0, 400) | |||||
#~ ax1.plot(tickArray, temps, linewidth=2, color='black') | |||||
#~ fig.canvas.draw() | |||||
elif input[0] == 0x20: | |||||
if input[1] == 0x00: | |||||
log.insert(END, '> cartridge resistance measure disabled\n') | |||||
elif input[1] == 0x01: | |||||
log.insert(END, '> cartridge resistance measure enabled\n') | |||||
elif input[0] == 0x21: | |||||
if input[1] == 0x00: | |||||
log.insert(END, '> power-mosfet disabled\n') | |||||
elif input[1] == 0x01: | |||||
log.insert(END, '> power-mosfet enabled\n') | |||||
elif input[0] == 0x8d: | |||||
cartridge_temperature_adc_raw = ((input[1] * 256) + input[2]) | |||||
tAct = struct.unpack('>f', input[3:7]) | |||||
tSet = struct.unpack('>f', input[7:11]) | |||||
err = struct.unpack('>f', input[11:15]) | |||||
errSum = struct.unpack('>f', input[15:19]) | |||||
outOrig = struct.unpack('>f', input[19:23]) | |||||
out = input[23] * 256 + input[24] | |||||
if out > 32767: | |||||
out -= 65536 | |||||
log.insert(END, 'tAct: ' + str(tAct) + 'tSet: ' + str(tSet) + 'err: ' + str(err) + 'errSum: ' + str(errSum) + 'outOrig: ' + str(outOrig) + 'out: ' + str(out) + '\n') | |||||
#~ tActArray.append(tAct) | |||||
#~ tActArray = tActArray[-200:] | |||||
#~ ax1.clear() | |||||
#~ ax1.plot(tickArray, tActArray, linewidth=2, color='black') | |||||
#~ fig.canvas.draw() | |||||
else: | |||||
log.insert(END, '> ' + str.join(':', ('%02x' % x for x in input)) + '\n') | |||||
log.see("end") | |||||
def btnClearAction(): | |||||
log.delete(1.0,END) | |||||
log.insert(END, str(datetime.now()) + '\n') | |||||
def btnGetRawAdcCartridgeResistanceAction(): | |||||
sendSerial([0x10, 0x01]) | |||||
def btnGetRawAdcCartridgeCurrentAction(): | |||||
sendSerial([0x10, 0x02]) | |||||
def btnGetRawAdcCartridgeTemperatureAction(): | |||||
sendSerial([0x10, 0x03]) | |||||
def btnGetRawAdcInputVoltageAction(): | |||||
sendSerial([0x10, 0x04]) | |||||
def btnSetCartridgeResistanceMosfetOnAction(): | |||||
sendSerial([0x20, 0x01]) | |||||
def btnSetCartridgeResistanceMosfetOffAction(): | |||||
sendSerial([0x20, 0x00]) | |||||
def btnSetPowerMosfetOnAction(): | |||||
sendSerial([0x91, 0x01, 0x18]) | |||||
def btnSetPowerMosfetOffAction(): | |||||
sendSerial([0x91, 0x00, 0x00]) | |||||
def btnGetTempSensor0DegCAction(): | |||||
sendSerial([0xa2, 0x00]) | |||||
def btnGetTempSensor1DegCAction(): | |||||
sendSerial([0xa2, 0x01]) | |||||
def btnGetTempSensorsDegCAction(): | |||||
sendSerial([0xa3]) | |||||
def btnStartLogAction(): | |||||
global logEnable | |||||
global w | |||||
w = open('reflow_oven_temperature_log', 'w') | |||||
logEnable = 1 | |||||
w.write('time;seconds;status;temperature;tAct;tSet;err;errSum;outOrig;out\n') | |||||
sendSerial([0xa5]) | |||||
#functionLog() | |||||
def btnStopLogAction(): | |||||
global logEnable | |||||
global w | |||||
sendSerial([0xa4, 0x00]) | |||||
logEnable = 0 | |||||
w.close() | |||||
def btnDisablePwmAction(): | |||||
sendSerial([0xb0, 0x00, 0x00]) | |||||
def btnSetTemperature0Action(): | |||||
sendSerial([0xb1, 0x00]) | |||||
def btnSetTemperature80Action(): | |||||
sendSerial([0xb1, 0x50]) | |||||
def btnSetTemperature150Action(): | |||||
sendSerial([0xb1, 0x96]) | |||||
def btnSetTemperature180Action(): | |||||
sendSerial([0xb1, 0xb4]) | |||||
def btnSetTemperature245Action(): | |||||
sendSerial([0xb1, 0xf5]) | |||||
#make a TkInter Window | |||||
app = Tk() | |||||
app.wm_title("attiny817_solderstation_app") | |||||
# Create figure for plotting | |||||
fig = figure.Figure(figsize=(12, 4)) | |||||
#~ fig.subplots_adjust(left=0.1, right=0.8) | |||||
ax1 = fig.add_subplot(1, 1, 1) | |||||
ax1.set_ylim(0, 400) | |||||
#~ ax1.set_xlim(0, 20) | |||||
# Create a Tk Canvas widget out of our figure | |||||
canvas = FigureCanvasTkAgg(fig, master=app) | |||||
canvas_plot = canvas.get_tk_widget() | |||||
# make a scrollbar | |||||
scrollbar = Scrollbar(app) | |||||
scrollbar.pack(side=RIGHT, fill=Y) | |||||
# make a text box to put the serial output | |||||
log = Text (app, width=250, height=20, takefocus=0) | |||||
log.pack() | |||||
# attach text box to scrollbar | |||||
log.config(yscrollcommand=scrollbar.set) | |||||
scrollbar.config(command=log.yview) | |||||
btnClear = Button(app, text='clear', command=btnClearAction) | |||||
btnGetRawAdcCartridgeResistance = Button(app, text='getRawAdcCartridgeResistance', command=btnGetRawAdcCartridgeResistanceAction) | |||||
btnGetRawAdcCartridgeCurrent = Button(app, text='getRawAdcCartridgeCurrent', command=btnGetRawAdcCartridgeCurrentAction) | |||||
btnGetRawAdcCartridgeTemperature = Button(app, text='getRawAdcCartridgeTemperature', command=btnGetRawAdcCartridgeTemperatureAction) | |||||
btnGetRawAdcInputVoltage = Button(app, text='getRawAdcInputVoltage', command=btnGetRawAdcInputVoltageAction) | |||||
btnSetCartridgeResistanceMosfetOn = Button(app, text='setCartridgeResistanceMosfetOn', command=btnSetCartridgeResistanceMosfetOnAction) | |||||
btnSetCartridgeResistanceMosfetOff = Button(app, text='setCartridgeResistanceMosfetOff', command=btnSetCartridgeResistanceMosfetOffAction) | |||||
btnSetPowerMosfetOn = Button(app, text='setPowerMosfetOn', command=btnSetPowerMosfetOnAction) | |||||
btnSetPowerMosfetOff = Button(app, text='setPowerMosfetOff', command=btnSetPowerMosfetOffAction) | |||||
btnGetTempSensor0DegC = Button(app, text='getTempSensor0DegC', command=btnGetTempSensor0DegCAction) | |||||
btnGetTempSensor1DegC = Button(app, text='getTempSensor1DegC', command=btnGetTempSensor1DegCAction) | |||||
btnGetTempSensorsDegC = Button(app, text='getTempSensorsDegC', command=btnGetTempSensorsDegCAction) | |||||
btnStartLog = Button(app, text='startLog', command=btnStartLogAction) | |||||
btnStopLog = Button(app, text='stopLog', command=btnStopLogAction) | |||||
btnDisablePwm = Button(app, text='STOP', command=btnDisablePwmAction) | |||||
btnSetTemperature0 = Button(app, text='setTemperature0', command=btnSetTemperature0Action) | |||||
btnSetTemperature80 = Button(app, text='setTemperature80', command=btnSetTemperature80Action) | |||||
btnSetTemperature150 = Button(app, text='setTemperature150', command=btnSetTemperature150Action) | |||||
btnSetTemperature180 = Button(app, text='setTemperature180', command=btnSetTemperature180Action) | |||||
btnSetTemperature245 = Button(app, text='setTemperature245', command=btnSetTemperature245Action) | |||||
btnClear.pack() | |||||
canvas_plot.pack() | |||||
btnGetRawAdcCartridgeResistance.pack() | |||||
btnGetRawAdcCartridgeCurrent.pack() | |||||
btnGetRawAdcCartridgeTemperature.pack() | |||||
btnGetRawAdcInputVoltage.pack() | |||||
btnSetCartridgeResistanceMosfetOn.pack() | |||||
btnSetCartridgeResistanceMosfetOff.pack() | |||||
btnSetPowerMosfetOn.pack() | |||||
btnSetPowerMosfetOff.pack() | |||||
#make our own buffer | |||||
#useful for parsing commands | |||||
#Serial.readline seems unreliable at times too | |||||
rxInputBuffer = bytearray() | |||||
rxStatemachine = 0 | |||||
def readSerial(): | |||||
while True: | |||||
c = ser.read() # attempt to read a character from Serial | |||||
#was anything read? | |||||
if len(c) == 0: | |||||
break | |||||
else: | |||||
#print('DATA') | |||||
#log.insert(END, ':' + c.hex()) | |||||
global rxInputBuffer | |||||
global rxStatemachine | |||||
rxInputBuffer.append(c[0]) | |||||
if rxStatemachine == 0: | |||||
if rxInputBuffer[0] == 0xff: | |||||
rxStatemachine = 1 | |||||
rxInputBuffer = rxInputBuffer[1:] | |||||
elif rxStatemachine == 1: | |||||
if rxInputBuffer[0] == 0xf1: | |||||
rxStatemachine = 2 | |||||
else: | |||||
rxStatemachine = 0 | |||||
rxInputBuffer = rxInputBuffer[1:] | |||||
elif rxStatemachine == 2: | |||||
if len(rxInputBuffer) >= rxInputBuffer[0] + 1: | |||||
processData(rxInputBuffer[1:rxInputBuffer[0] + 1]) | |||||
rxInputBuffer = bytearray() | |||||
rxStatemachine = 0 | |||||
else: | |||||
if len(rxInputBuffer) > 256: | |||||
print('rxInputBuffer reset!') | |||||
rxInputBuffer = bytearray() | |||||
rxStatemachine = 0 | |||||
app.after(1, readSerial) # check serial again soon | |||||
# after initializing serial, an arduino may need a bit of time to reset | |||||
app.after(100, readSerial) | |||||
app.mainloop() |
@ -0,0 +1,444 @@ | |||||
#!/usr/bin/env python3 | |||||
import sys | |||||
import getopt | |||||
import glob | |||||
import serial | |||||
import struct | |||||
import tkinter | |||||
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk) | |||||
# Implement the default Matplotlib key bindings. | |||||
from matplotlib.backend_bases import key_press_handler | |||||
from matplotlib.figure import Figure | |||||
import numpy as np | |||||
tempe = 0 | |||||
tSetGlobal = 0.0 | |||||
controllerDebugWindowOpen = 0 | |||||
tick = 0 | |||||
tickArray = [] | |||||
tActArray = [] | |||||
tSetArray = [] | |||||
tickDebug = 0 | |||||
tickDebugArray = [] | |||||
tActDebugArray = [] | |||||
tSetDebugArray = [] | |||||
errDebugArray = [] | |||||
errSumDebugArray = [] | |||||
outOrigDebugArray = [] | |||||
outDebugArray = [] | |||||
outAvgDebugArray = [] | |||||
sleepCounterDebugArray = [] | |||||
rxInputBuffer = bytearray() | |||||
rxStatemachine = 0 | |||||
def serial_ports(): | |||||
""" Lists serial port names | |||||
:raises EnvironmentError: | |||||
On unsupported or unknown platforms | |||||
:returns: | |||||
A list of the serial ports available on the system | |||||
""" | |||||
if sys.platform.startswith('win'): | |||||
ports = ['COM%s' % (i + 1) for i in range(256)] | |||||
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'): | |||||
# this excludes your current terminal "/dev/tty" | |||||
ports = glob.glob('/dev/tty[A-Za-z]*') | |||||
elif sys.platform.startswith('darwin'): | |||||
ports = glob.glob('/dev/tty.*') | |||||
else: | |||||
raise EnvironmentError('Unsupported platform') | |||||
result = [] | |||||
for port in ports: | |||||
try: | |||||
s = serial.Serial(port) | |||||
s.close() | |||||
result.append(port) | |||||
except (OSError, serial.SerialException): | |||||
pass | |||||
return result | |||||
#print(serial_ports()) | |||||
availableSerialPorts = serial_ports() | |||||
print('choose a port:') | |||||
counter = 0 | |||||
for port in availableSerialPorts: | |||||
print(' [' + str(counter) + '] ' + port) | |||||
counter += 1 | |||||
choosenPort = input('(type a number (0)) ') | |||||
if choosenPort == '': | |||||
choosenPortNumber = 0 | |||||
else: | |||||
choosenPortNumber = int(choosenPort) | |||||
counter = 0 | |||||
#serialPort = '/dev/pts/19' | |||||
serialPort = '/dev/ttyACM0' | |||||
serialPort = availableSerialPorts[choosenPortNumber] | |||||
try: | |||||
ser = serial.Serial(serialPort, 19200, serial.EIGHTBITS, serial.PARITY_NONE, serial.STOPBITS_ONE, timeout=0, writeTimeout=0) | |||||
except: | |||||
serialPort = '/dev/ttyACM1' | |||||
ser = serial.Serial(serialPort, 19200, serial.EIGHTBITS, serial.PARITY_NONE, serial.STOPBITS_ONE, timeout=0, writeTimeout=0) | |||||
def readSerial(): | |||||
while True: | |||||
c = ser.read() # attempt to read a character from Serial | |||||
#was anything read? | |||||
if len(c) == 0: | |||||
break | |||||
else: | |||||
#print('DATA') | |||||
#log.insert(END, ':' + c.hex()) | |||||
global rxInputBuffer | |||||
global rxStatemachine | |||||
rxInputBuffer.append(c[0]) | |||||
if rxStatemachine == 0: | |||||
if rxInputBuffer[0] == 0xff: | |||||
rxStatemachine = 1 | |||||
rxInputBuffer = rxInputBuffer[1:] | |||||
elif rxStatemachine == 1: | |||||
if rxInputBuffer[0] == 0xf1: | |||||
rxStatemachine = 2 | |||||
else: | |||||
rxStatemachine = 0 | |||||
rxInputBuffer = rxInputBuffer[1:] | |||||
elif rxStatemachine == 2: | |||||
if len(rxInputBuffer) >= rxInputBuffer[0] + 1: | |||||
processData(rxInputBuffer[1:rxInputBuffer[0] + 1]) | |||||
rxInputBuffer = bytearray() | |||||
rxStatemachine = 0 | |||||
else: | |||||
if len(rxInputBuffer) > 256: | |||||
print('rxInputBuffer reset!') | |||||
rxInputBuffer = bytearray() | |||||
rxStatemachine = 0 | |||||
root.after(10, readSerial) # check serial again soon | |||||
def processData(input): | |||||
global tSetGlobal | |||||
print([ "0x%02x" % b for b in input ]) | |||||
# ~ print(str([hex(x) for x in input])) | |||||
# ~ if input[0] == 0x11: | |||||
# ~ if input[1] == 100: | |||||
# ~ temperatureString.set(str(round(((input[2] * 256) + input[3]) * 0.4833149757 + 35.1689715661)) + "degC") | |||||
# ~ processControllerDebugData(((input[2] * 256) + input[3]) * 0.4833149757 + 35.1689715661, 20, 10, 0, -10, -20) | |||||
if input[0] == 0x33: | |||||
print("debugDataEnabled") | |||||
tickDebugArray.clear() | |||||
tActDebugArray.clear() | |||||
tSetDebugArray.clear() | |||||
errDebugArray.clear() | |||||
errSumDebugArray.clear() | |||||
outOrigDebugArray.clear() | |||||
outDebugArray.clear() | |||||
outAvgDebugArray.clear() | |||||
sleepCounterDebugArray.clear() | |||||
elif input[0] == 0x34: | |||||
print("debugDataDisabled") | |||||
elif input[0] == 0x8d: | |||||
cartridge_temperature_adc_raw = ((input[1] * 256) + input[2]) | |||||
tAct = struct.unpack('>f', input[3:7])[0] | |||||
tSet = struct.unpack('>f', input[7:11])[0] | |||||
err = struct.unpack('>f', input[11:15])[0] | |||||
errSum = struct.unpack('>f', input[15:19])[0] | |||||
outOrig = struct.unpack('>f', input[19:23])[0] | |||||
out = input[23] * 256 + input[24] | |||||
outAvg = input[25] * 256 + input[26] | |||||
sleepCounter = input[27] * 256 + input[28] | |||||
if out > 32767: | |||||
out -= 65536 | |||||
tActString.set(str(round(tAct)) + "degC") | |||||
tSetString.set("(" + str(round(tSet)) + "degC)") | |||||
tSetGlobal = tSet | |||||
processTemperatureData(tAct, tSet) | |||||
processControllerDebugData(tAct, tSet, err, errSum, outOrig, out, outAvg, sleepCounter) | |||||
elif input[0] == 0x8c: | |||||
tAct = struct.unpack('>f', input[1:5])[0] | |||||
tSet = struct.unpack('>f', input[5:9])[0] | |||||
tActString.set(str(round(tAct)) + "degC") | |||||
tSetString.set("(" + str(round(tSet)) + "degC)") | |||||
tSetGlobal = tSet | |||||
processTemperatureData(tAct, tSetGlobal) | |||||
# ~ elif input[0] == 0x91: | |||||
# ~ tSet = struct.unpack('>f', input[1:5])[0] | |||||
# ~ tSetString.set("(" + str(round(tSet)) + "degC)") | |||||
# ~ elif input[0] == 0x92: | |||||
# ~ controllerValueKpString.set("Kp: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
# ~ elif input[0] == 0x93: | |||||
# ~ controllerValueKpString.set("Kp: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
# ~ elif input[0] == 0x94: | |||||
# ~ controllerValueKiString.set("Ki: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
# ~ elif input[0] == 0x95: | |||||
# ~ controllerValueKiString.set("Ki: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
# ~ elif input[0] == 0x96: | |||||
# ~ controllerValueKdString.set("Kd: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
# ~ elif input[0] == 0x97: | |||||
# ~ controllerValueKdString.set("Kd: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
# ~ elif input[0] == 0x98: | |||||
# ~ controllerValueKitString.set("Kit: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
# ~ elif input[0] == 0x99: | |||||
# ~ controllerValueKitString.set("Kit: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
elif input[0] == 0xa0: | |||||
controllerValueKpString.set("Kp: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
elif input[0] == 0xa1: | |||||
controllerValueKiString.set("Ki: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
elif input[0] == 0xa2: | |||||
controllerValueKdString.set("Kd: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
elif input[0] == 0xa3: | |||||
controllerValueKitString.set("Kit: " + str(struct.unpack('>f', input[1:5])[0])) | |||||
elif input[0] == 0xf0: | |||||
tSet = struct.unpack('>f', input[1:5])[0] | |||||
controllerKp = struct.unpack('>f', input[5:9])[0] | |||||
controllerKi = struct.unpack('>f', input[9:13])[0] | |||||
controllerKd = struct.unpack('>f', input[13:17])[0] | |||||
controllerKit = struct.unpack('>f', input[17:21])[0] | |||||
tSetString.set("(" + str(round(tSet)) + "degC)") | |||||
tSetGlobal = tSet | |||||
controllerValueKpString.set("Kp: " + str(controllerKp)) | |||||
controllerValueKiString.set("Ki: " + str(controllerKi)) | |||||
controllerValueKdString.set("Kd: " + str(controllerKd)) | |||||
controllerValueKitString.set("Kit: " + str(controllerKit)) | |||||
def sendSerial(payloadType, payload): | |||||
# ~ print('send ' + str(len(input)) + ' byte(s): ' + str([hex(x) for x in input])) | |||||
data = bytearray([0xff, 0xf1]) | |||||
data.append(1 + len(payload)) | |||||
data.append(payloadType) | |||||
data.extend(bytearray(payload)) | |||||
print("send " + str([ "0x%02x" % b for b in data ])) | |||||
ser.write(data) | |||||
def createNewWindow(): | |||||
global controllerDebugWindowOpen | |||||
newWindow = tkinter.Toplevel(root) | |||||
newWindow.protocol("WM_DELETE_WINDOW", lambda: closeWindow(newWindow)) | |||||
# ~ labelExample = tkinter.Label(master=newWindow, text="new window") | |||||
# ~ labelExample.pack() | |||||
canvas2 = FigureCanvasTkAgg(controllerDebugFigure, master=newWindow) # A tk.DrawingArea. | |||||
canvas2.draw() | |||||
canvas2.get_tk_widget().pack() | |||||
controllerDebugWindowOpen = 1 | |||||
def closeWindow(myVar): | |||||
print("closeWindow " + str(myVar)) | |||||
controllerDebugWindowOpen = 0 | |||||
myVar.destroy() | |||||
def increaseTemperature(): | |||||
global tempe, temperatureString | |||||
tempe = tempe + 10 | |||||
temperatureString.set(str(tempe) + "degC") | |||||
def processTemperatureData(tAct, tSet): | |||||
global tick, tickArray, tActArray, tSetArray | |||||
tickArray.append(tick) | |||||
tickArray = tickArray[-30:] | |||||
tick = tick + 1 | |||||
tActArray.append(tAct) | |||||
tActArray = tActArray[-30:] | |||||
tSetArray.append(tSet) | |||||
tSetArray = tSetArray[-30:] | |||||
yMin = tSet - 10 | |||||
yMax = tSet + 10 | |||||
if min(tActArray) < yMin: | |||||
yMin = min(tActArray) - 2 | |||||
if max(tActArray) > yMax: | |||||
yMax = max(tActArray) + 2 | |||||
temperatureFigureAxis1.clear() | |||||
temperatureFigureAxis1.plot(tickArray, tActArray, linewidth=1, color="black") | |||||
temperatureFigureAxis1.plot(tickArray, tSetArray, linewidth=1, color="green") | |||||
temperatureFigureAxis1.set_ylim(yMin, yMax) | |||||
# ~ temperatureFigure.tight_layout() | |||||
temperatureFigure.canvas.draw() | |||||
def processControllerDebugData(tAct, tSet, err, errSum, outOrig, out, outAvg, sleepCounter): | |||||
# ~ print("processControllerDebugData") | |||||
global tickDebug, tickDebugArray, tActDebugArray, tSetDebugArray, errDebugArray, errSumDebugArray, outOrigDebugArray, outDebugArray, outAvgDebugArray, sleepCounterDebugArray | |||||
global controllerDebugWindowOpen | |||||
tickDebugArray.append(tickDebug) | |||||
tickDebugArray = tickDebugArray[-1000:] | |||||
tickDebug = tickDebug + 1 | |||||
tActDebugArray.append(tAct) | |||||
tActDebugArray = tActDebugArray[-1000:] | |||||
tSetDebugArray.append(tSet) | |||||
tSetDebugArray = tSetDebugArray[-1000:] | |||||
errDebugArray.append(err) | |||||
errDebugArray = errDebugArray[-1000:] | |||||
errSumDebugArray.append(errSum) | |||||
errSumDebugArray = errSumDebugArray[-1000:] | |||||
outOrigDebugArray.append(outOrig) | |||||
outOrigDebugArray = outOrigDebugArray[-1000:] | |||||
outDebugArray.append(out) | |||||
outDebugArray = outDebugArray[-1000:] | |||||
outAvgDebugArray.append(outAvg) | |||||
outAvgDebugArray = outAvgDebugArray[-1000:] | |||||
sleepCounterDebugArray.append(sleepCounter) | |||||
sleepCounterDebugArray = sleepCounterDebugArray[-1000:] | |||||
if controllerDebugWindowOpen == 1: | |||||
# ~ ax1.clear() | |||||
# ~ ax1.plot(tickArray, tActArray, linewidth=2, color='black') | |||||
# ~ fig.canvas.draw() | |||||
controllerDebugFigureAxis1.clear() | |||||
controllerDebugFigureAxis1.plot(tickDebugArray, tActDebugArray, linewidth=1, color="black", label="tAct") | |||||
controllerDebugFigureAxis1.plot(tickDebugArray, tSetDebugArray, linewidth=1, color="green", label="tSet") | |||||
controllerDebugFigureAxis1.plot(tickDebugArray, errDebugArray, linewidth=1, color="red", label="err") | |||||
controllerDebugFigureAxis1.plot(tickDebugArray, errSumDebugArray, linewidth=1, color="orange", label="errSum") | |||||
controllerDebugFigureAxis1.plot(tickDebugArray, outOrigDebugArray, linewidth=1, color="royalblue", label="outOrig") | |||||
controllerDebugFigureAxis1.plot(tickDebugArray, outDebugArray, linewidth=1, color="blueviolet", label="out") | |||||
controllerDebugFigureAxis1.plot(tickDebugArray, outAvgDebugArray, linewidth=1, color="blue", label="outAvg") | |||||
controllerDebugFigureAxis1.plot(tickDebugArray, sleepCounterDebugArray, linewidth=1, color="grey", label="sleepCounter") | |||||
controllerDebugFigureAxis1.legend(loc="lower left") | |||||
controllerDebugFigureAxis1.set_ylim(-100, 1000) | |||||
# ~ controllerDebugFigure.tight_layout() | |||||
controllerDebugFigure.canvas.draw() | |||||
root = tkinter.Tk() | |||||
root.wm_title("Embedding in Tk") | |||||
root.geometry("320x850") | |||||
# ~ root.protocol("WM_DELETE_WINDOW", lambda: closeWindow(root)) | |||||
# ~ fig = Figure(figsize=(5, 4), dpi=100) | |||||
# ~ fig2 = Figure(figsize=(5, 4), dpi=100) | |||||
# ~ t = np.arange(0, 3, .01) | |||||
# ~ fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t)) | |||||
# ~ fig2.add_subplot(111).plot(t, 2 * np.cos(2 * np.pi * t)) | |||||
temperatureFigure = Figure(figsize=(3, 2)) | |||||
temperatureFigureAxis1 = temperatureFigure.add_subplot(1, 1, 1) | |||||
temperatureFigureAxis1.yaxis.set_label_position("right") | |||||
temperatureFigureAxis1.yaxis.tick_right() | |||||
temperatureFigure.tight_layout() | |||||
controllerDebugFigure = Figure(figsize=(15, 9)) | |||||
controllerDebugFigureAxis1 = controllerDebugFigure.add_subplot(1, 1, 1) | |||||
controllerDebugFigureAxis1.yaxis.set_label_position("right") | |||||
controllerDebugFigureAxis1.yaxis.tick_right() | |||||
controllerDebugFigureAxis1.set_ylim(-200, 500) | |||||
controllerDebugFigure.tight_layout() | |||||
# ~ canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea. | |||||
# ~ canvas.draw() | |||||
# pack_toolbar=False will make it easier to use a layout manager later on. | |||||
# ~ toolbar = NavigationToolbar2Tk(canvas, root, pack_toolbar=False) | |||||
# ~ toolbar.update() | |||||
# ~ canvas.mpl_connect("key_press_event", lambda event: print(f"you pressed {event.key}")) | |||||
# ~ canvas.mpl_connect("key_press_event", key_press_handler) | |||||
# ~ btn = tk.Button(root, text="Press", command=lambda: myFunction("See this worked!")) | |||||
# ~ button = tkinter.Button(master=root, text="Quit", command=root.quit) | |||||
buttonNewWindow = tkinter.Button(master=root, text="open controller debug window", command=createNewWindow) | |||||
# Packing order is important. Widgets are processed sequentially and if there | |||||
# is no space left, because the window is too small, they are not displayed. | |||||
# The canvas is rather flexible in its size, so we pack it last which makes | |||||
# sure the UI controls are displayed as long as possible. | |||||
# ~ button.pack(side=tkinter.BOTTOM) | |||||
buttonNewWindow.pack(side=tkinter.BOTTOM) | |||||
# ~ toolbar.pack(side=tkinter.BOTTOM, fill=tkinter.X) | |||||
# ~ canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) | |||||
tkinter.Button(master=root, text="set 330degC", command=lambda: sendSerial(0x91, [0x01, 0x4a])).pack() | |||||
tkinter.Button(master=root, text="set 200degC", command=lambda: sendSerial(0x91, [0x00, 0xc8])).pack() | |||||
tkinter.Button(master=root, text="set 0degC", command=lambda: sendSerial(0x91, [0x00, 0x00])).pack() | |||||
tActString = tkinter.StringVar() | |||||
tActString.set("0degC") | |||||
tSetString = tkinter.StringVar() | |||||
tSetString.set("(0degC)") | |||||
controllerValueKpString = tkinter.StringVar() | |||||
controllerValueKpString.set("Kp: 0") | |||||
controllerValueKiString = tkinter.StringVar() | |||||
controllerValueKiString.set("Ki: 0") | |||||
controllerValueKdString = tkinter.StringVar() | |||||
controllerValueKdString.set("Kd: 0") | |||||
controllerValueKitString = tkinter.StringVar() | |||||
controllerValueKitString.set("Kit: 0") | |||||
tkinter.Label(master=root, textvariable=tActString, font=("Free Mono", 40)).pack() | |||||
tkinter.Label(master=root, textvariable=tSetString, font=("Free Mono", 20)).pack() | |||||
canvas = FigureCanvasTkAgg(temperatureFigure, master=root) # A tk.DrawingArea. | |||||
canvas.draw() | |||||
canvas.get_tk_widget().pack() | |||||
# ~ tkinter.Button(master=root, text="Kp +1", command=lambda: sendSerial(0x92, [])).pack() | |||||
tkinter.Label(master=root, textvariable=controllerValueKpString, font=("Free Mono", 20)).pack() | |||||
textValueKp = tkinter.Text(master=root, height=1, width=20) | |||||
textValueKp.pack() | |||||
tkinter.Button(master=root, text="set Kp", command=lambda: sendSerial(0xa0, convertStringToFloatBytearray(textValueKp.get("1.0", "end-1c")))).pack() | |||||
# ~ tkinter.Button(master=root, text="Kp -1", command=lambda: sendSerial(0x93, [])).pack() | |||||
# ~ tkinter.Button(master=root, text="Ki +1", command=lambda: sendSerial(0x94, [])).pack() | |||||
tkinter.Label(master=root, textvariable=controllerValueKiString, font=("Free Mono", 20)).pack() | |||||
textValueKi = tkinter.Text(master=root, height=1, width=20) | |||||
textValueKi.pack() | |||||
tkinter.Button(master=root, text="set Ki", command=lambda: sendSerial(0xa1, convertStringToFloatBytearray(textValueKi.get("1.0", "end-1c")))).pack() | |||||
# ~ tkinter.Button(master=root, text="Ki -1", command=lambda: sendSerial(0x95, [])).pack() | |||||
# ~ tkinter.Button(master=root, text="Kd +1", command=lambda: sendSerial(0x96, [])).pack() | |||||
tkinter.Label(master=root, textvariable=controllerValueKdString, font=("Free Mono", 20)).pack() | |||||
textValueKd = tkinter.Text(master=root, height=1, width=20) | |||||
textValueKd.pack() | |||||
tkinter.Button(master=root, text="set Kd", command=lambda: sendSerial(0xa2, convertStringToFloatBytearray(textValueKd.get("1.0", "end-1c")))).pack() | |||||
# ~ tkinter.Button(master=root, text="Kd -1", command=lambda: sendSerial(0x97, [])).pack() | |||||
# ~ tkinter.Button(master=root, text="Kit +1", command=lambda: sendSerial(0x98, [])).pack() | |||||
tkinter.Label(master=root, textvariable=controllerValueKitString, font=("Free Mono", 20)).pack() | |||||
textValueKit = tkinter.Text(master=root, height=1, width=20) | |||||
textValueKit.pack() | |||||
tkinter.Button(master=root, text="set Kit", command=lambda: sendSerial(0xa3, convertStringToFloatBytearray(textValueKit.get("1.0", "end-1c")))).pack() | |||||
# ~ tkinter.Button(master=root, text="Kit -1", command=lambda: sendSerial(0x99, [])).pack() | |||||
tkinter.Button(master=root, text="enable debug data", command=lambda: sendSerial(0x33, [])).pack() | |||||
tkinter.Button(master=root, text="disable debug data", command=lambda: sendSerial(0x34, [])).pack() | |||||
# ~ tkinter.Button(master=root, text="init", command=lambda: sendSerial(0xf0, [])).pack() | |||||
def convertStringToFloatBytearray(inputString): | |||||
try: | |||||
floatValue = float(inputString) | |||||
byteArrayValue = bytearray(struct.pack('>f', floatValue)) | |||||
# ~ print(str(floatValue)) | |||||
# ~ print([ "0x%02x" % b for b in byteArrayValue ]) | |||||
return byteArrayValue | |||||
except: | |||||
print("can not convert [" + inputString + "] to float!") | |||||
return [] | |||||
root.after(100, readSerial) | |||||
sendSerial(0xf0, []) | |||||
tkinter.mainloop() |
@ -0,0 +1,933 @@ | |||||
#include <avr/io.h> | |||||
#include <avr/interrupt.h> | |||||
#include <util/delay.h> | |||||
#include "main.h" | |||||
#define DEF_F_BAUD 19200 | |||||
#define DEF_BAUD 64 * F_CPU / 16 / DEF_F_BAUD | |||||
#define ADC_MUXPOS_CARTRIDGE_RESISTANCE ADC_MUXPOS_AIN4_gc | |||||
#define ADC_MUXPOS_CARTRIDGE_CURRENT ADC_MUXPOS_AIN7_gc | |||||
#define ADC_MUXPOS_CARTRIDGE_TEMPERATURE ADC_MUXPOS_AIN8_gc | |||||
#define ADC_MUXPOS_V_IN ADC_MUXPOS_AIN9_gc | |||||
#define BUFFER_SIZE (64) | |||||
volatile uint8_t debugRxStateMachine = 0x00; | |||||
volatile uint8_t debugRxBuffer[BUFFER_SIZE]; | |||||
volatile uint8_t debugRxBufferIndex = 0; | |||||
volatile uint8_t debugRxFrameLength = 0; | |||||
volatile uint8_t debugTxStateMachine = 0x00; | |||||
volatile uint8_t debugTxBuffer[BUFFER_SIZE]; | |||||
volatile uint8_t debugTxBufferIndex = 0; | |||||
volatile uint8_t debugTxFrameLength = 0; | |||||
volatile uint8_t adc_channel = 0; | |||||
volatile uint8_t adc_counter = 0; | |||||
volatile uint16_t cartridge_temperature_data[8]; | |||||
volatile uint8_t cartridge_temperature_data_pointer = 0; | |||||
//~ volatile uint8_t out_data[32]; | |||||
//~ volatile uint8_t out_data_pointer = 0; | |||||
volatile uint16_t sleep_kp_value = 0; | |||||
volatile uint16_t sleep_counter = 0; | |||||
volatile uint8_t sleep_state = 1; | |||||
volatile uint16_t out_avg = 0; | |||||
volatile int8_t out_avg_counter = 0; | |||||
#define Kp 30 | |||||
#define Kd 0 | |||||
#define Ki 0.5 | |||||
#define Kit 400 | |||||
#define errSumMax 1 / Ki * Kit | |||||
volatile float controllerKp = 0; | |||||
volatile float controllerKpBuff = Kp; | |||||
volatile uint8_t controllerKpBuffFlag = 1; | |||||
volatile float controllerKd = 0; | |||||
volatile float controllerKdBuff = Kd; | |||||
volatile uint8_t controllerKdBuffFlag = 1; | |||||
volatile float controllerKi = 0; | |||||
volatile float controllerKiBuff = Ki; | |||||
volatile uint8_t controllerKiBuffFlag = 1; | |||||
volatile float controllerKit = 0; | |||||
volatile float controllerKitBuff = Kit; | |||||
volatile uint8_t controllerKitBuffFlag = 1; | |||||
volatile float controllerErrSumMax = 0; | |||||
volatile float tSet = 0; | |||||
volatile float tSetBuff = 200; | |||||
volatile uint8_t tSetBuffFlag = 1; | |||||
#define OUT_MAX 800 | |||||
volatile float tAct = 0; | |||||
volatile float err = 0; | |||||
volatile float errAlt = 0; | |||||
volatile float errSum = 0; | |||||
volatile float outOrig = 0; | |||||
volatile uint16_t out = 0; | |||||
volatile uint16_t outOld = 0; | |||||
volatile uint8_t outSettlingCounter = 0; | |||||
volatile uint8_t outSettlingState = 0; | |||||
volatile uint8_t debugDataEnable = 0; | |||||
void DebugAppendData(uint8_t data) | |||||
{ | |||||
if (debugTxStateMachine == 0x00) | |||||
{ | |||||
if (debugTxFrameLength < BUFFER_SIZE) | |||||
{ | |||||
debugTxBuffer[debugTxFrameLength] = data; | |||||
debugTxFrameLength++; | |||||
} | |||||
} | |||||
} | |||||
void DebugSendData(void) | |||||
{ | |||||
if (debugTxStateMachine == 0x00) | |||||
{ | |||||
debugTxStateMachine = 0x01; | |||||
while ((USART0.STATUS & 0b00100000) == 0) {} | |||||
USART0.CTRLA |= 0b00100000; | |||||
USART0.TXDATAL = 0xff; | |||||
} | |||||
} | |||||
ISR(USART0_RXC_vect) | |||||
{ | |||||
uint8_t data = USART0.RXDATAL; | |||||
switch (debugRxStateMachine) | |||||
{ | |||||
case 0x00: | |||||
if (data == 0xff) | |||||
{ | |||||
debugRxStateMachine = 0x01; | |||||
} | |||||
break; | |||||
case 0x01: | |||||
if (data == 0xf1) | |||||
{ | |||||
debugRxStateMachine = 0x02; | |||||
} | |||||
else | |||||
{ | |||||
debugRxStateMachine = 0x00; | |||||
} | |||||
break; | |||||
case 0x02: | |||||
debugRxFrameLength = data; | |||||
if (debugRxFrameLength <= BUFFER_SIZE) | |||||
{ | |||||
debugRxStateMachine = 0x03; | |||||
} | |||||
else | |||||
{ | |||||
debugRxStateMachine = 0xff; | |||||
} | |||||
break; | |||||
case 0x03: | |||||
if (debugRxBufferIndex < BUFFER_SIZE) | |||||
{ | |||||
debugRxBuffer[debugRxBufferIndex] = data; | |||||
debugRxBufferIndex++; | |||||
if (debugRxBufferIndex >= debugRxFrameLength) | |||||
{ | |||||
debugRxBufferIndex = 0; | |||||
debugRxStateMachine = 0x04; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
debugRxStateMachine = 0xff; | |||||
} | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
ISR(USART0_DRE_vect) | |||||
{ | |||||
switch (debugTxStateMachine) | |||||
{ | |||||
case 0x01: | |||||
debugTxStateMachine = 0x02; | |||||
USART0.TXDATAL = 0xf1; | |||||
break; | |||||
case 0x02: | |||||
debugTxStateMachine = 0x03; | |||||
debugTxBufferIndex = 0; | |||||
USART0.TXDATAL = debugTxFrameLength; | |||||
break; | |||||
case 0x03: | |||||
if (debugTxBufferIndex == debugTxFrameLength - 1) | |||||
{ | |||||
debugTxStateMachine = 0x04; | |||||
} | |||||
USART0.TXDATAL = debugTxBuffer[debugTxBufferIndex]; | |||||
debugTxBufferIndex++; | |||||
break; | |||||
case 0x04: | |||||
USART0.CTRLA &= 0b11011111; | |||||
debugTxFrameLength = 0; | |||||
debugTxStateMachine = 0; | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
ISR(ADC0_RESRDY_vect) | |||||
{ | |||||
//~ uint16_t adc_value = ADC0.RES >> 5; | |||||
uint16_t adc_value = ADC0.RES; | |||||
switch (adc_channel) | |||||
{ | |||||
case 100: | |||||
cartridge_temperature_data[cartridge_temperature_data_pointer] = adc_value; | |||||
cartridge_temperature_data_pointer++; | |||||
cartridge_temperature_data_pointer &= 7; | |||||
uint16_t cartridge_temperature = 0; | |||||
for (uint8_t i = 0; i < 8; i++) | |||||
{ | |||||
cartridge_temperature += cartridge_temperature_data[i]; | |||||
} | |||||
cartridge_temperature >>= 3; | |||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |||||
if (tSetBuffFlag > 0) | |||||
{ | |||||
tSet = tSetBuff; | |||||
tSetBuffFlag = 0; | |||||
if (tSet > 250) | |||||
{ | |||||
sleep_state = 0; | |||||
sleep_counter = 0; | |||||
} | |||||
else | |||||
{ | |||||
sleep_state++; | |||||
} | |||||
} | |||||
if (controllerKpBuffFlag > 0) | |||||
{ | |||||
controllerKp = controllerKpBuff; | |||||
controllerKpBuffFlag = 0; | |||||
sleep_kp_value = (uint16_t) (controllerKp * 2.0); | |||||
} | |||||
if (controllerKdBuffFlag > 0) | |||||
{ | |||||
controllerKd = controllerKdBuff; | |||||
controllerKdBuffFlag = 0; | |||||
} | |||||
if (controllerKiBuffFlag > 0) | |||||
{ | |||||
if (controllerKiBuff == 0) | |||||
{ | |||||
controllerKiBuff = 1; | |||||
} | |||||
controllerKi = controllerKiBuff; | |||||
controllerErrSumMax = 1 / controllerKi * controllerKit; | |||||
controllerKiBuffFlag = 0; | |||||
} | |||||
if (controllerKitBuffFlag > 0) | |||||
{ | |||||
controllerKit = controllerKitBuff; | |||||
controllerErrSumMax = 1 / controllerKi * controllerKit; | |||||
controllerKitBuffFlag = 0; | |||||
} | |||||
float m = 0.4833149757, b = 35.1689715661; | |||||
tAct = ((float) cartridge_temperature) * m + b; | |||||
err = tSet - tAct; | |||||
errSum = errSum + err; | |||||
if (errSum < -controllerErrSumMax) | |||||
{ | |||||
errSum = -controllerErrSumMax; | |||||
} | |||||
if (errSum > controllerErrSumMax) | |||||
{ | |||||
errSum = controllerErrSumMax; | |||||
} | |||||
outOrig = controllerKp * err + controllerKi * errSum + controllerKd * (err - errAlt); | |||||
errAlt = err; | |||||
outOld = out; | |||||
if (outOrig < 0) | |||||
{ | |||||
out = 0; | |||||
} | |||||
else if (outOrig > OUT_MAX) | |||||
{ | |||||
out = OUT_MAX; | |||||
} | |||||
else | |||||
{ | |||||
out = (uint16_t) outOrig; | |||||
} | |||||
TCA0.SINGLE.CMP0BUF = out; | |||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |||||
if (out == 0 || out == OUT_MAX) | |||||
{ | |||||
outSettlingState = 0; | |||||
outSettlingCounter = 0; | |||||
} | |||||
else | |||||
{ | |||||
if (outSettlingState == 0) | |||||
{ | |||||
outSettlingCounter++; | |||||
int16_t outDiff = (int16_t) (out - outOld); | |||||
if (outDiff > 25) | |||||
{ | |||||
outSettlingCounter = 0; | |||||
} | |||||
if (outDiff < -25) | |||||
{ | |||||
outSettlingCounter = 0; | |||||
} | |||||
if (outSettlingCounter > 180) | |||||
{ | |||||
outSettlingState = 1; | |||||
} | |||||
} | |||||
} | |||||
if (outSettlingState == 0) | |||||
{ | |||||
out_avg = out; | |||||
} | |||||
else | |||||
{ | |||||
if (out > out_avg) | |||||
{ | |||||
if (out < out_avg + sleep_kp_value) | |||||
{ | |||||
out_avg_counter++; | |||||
} | |||||
//~ out_avg_counter++; | |||||
} | |||||
else if (out < out_avg) | |||||
{ | |||||
out_avg_counter--; | |||||
} | |||||
if (out_avg_counter > 10) | |||||
{ | |||||
if (out_avg < 800) | |||||
{ | |||||
out_avg++; | |||||
} | |||||
out_avg_counter = 0; | |||||
} | |||||
else if (out_avg_counter < -3) | |||||
{ | |||||
if (out_avg > 0) | |||||
{ | |||||
out_avg--; | |||||
} | |||||
out_avg_counter = 0; | |||||
} | |||||
if (sleep_state == 0) | |||||
{ | |||||
sleep_counter++; | |||||
} | |||||
if (out > out_avg + sleep_kp_value) | |||||
{ | |||||
sleep_counter = 0; | |||||
if (sleep_state > 0) | |||||
{ | |||||
tSetBuff = 330; | |||||
tSetBuffFlag++; | |||||
sleep_state = 0; | |||||
} | |||||
} | |||||
if (sleep_counter > 2350) | |||||
{ | |||||
tSetBuff = 200; | |||||
tSetBuffFlag++; | |||||
sleep_counter = 0; | |||||
sleep_state++; | |||||
} | |||||
} | |||||
//~ if (adc_counter > 4) | |||||
//~ { | |||||
//~ out_data[out_data_pointer] = (uint8_t) (out >> 2); | |||||
//~ out_data_pointer++; | |||||
//~ out_data_pointer &= 31; | |||||
//~ out_avg = 0; | |||||
//~ for (uint8_t i = 0; i < 32; i++) | |||||
//~ { | |||||
//~ out_avg += out_data[i]; | |||||
//~ } | |||||
//~ out_avg >>= 3; | |||||
//~ } | |||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |||||
if (adc_counter > 8) | |||||
{ | |||||
adc_counter = 0; | |||||
if (debugDataEnable > 0) | |||||
{ | |||||
DebugAppendData(0x8d); | |||||
DebugAppendData((uint8_t) (cartridge_temperature >> 8)); | |||||
DebugAppendData((uint8_t) (cartridge_temperature)); | |||||
uint32_t value = *(uint32_t*) &tAct; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
value = *(uint32_t*) &tSet; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
value = *(uint32_t*) &err; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
value = *(uint32_t*) &errSum; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
value = *(uint32_t*) &outOrig; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
DebugAppendData((uint8_t) ((out & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (out & 0x00FF)); | |||||
DebugAppendData((uint8_t) ((out_avg & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (out_avg & 0x00FF)); | |||||
DebugAppendData((uint8_t) ((sleep_counter & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (sleep_counter & 0x00FF)); | |||||
DebugSendData(); | |||||
} | |||||
else | |||||
{ | |||||
DebugAppendData(0x8c); | |||||
uint32_t value = *(uint32_t*) &tAct; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
value = *(uint32_t*) &tSet; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
DebugSendData(); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
adc_counter++; | |||||
} | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
//~ if (adc_channel < 100) | |||||
//~ { | |||||
//~ DebugAppendData(0x11); | |||||
//~ DebugAppendData(adc_channel); | |||||
//~ DebugAppendData((uint8_t) (adc_value >> 8)); | |||||
//~ DebugAppendData((uint8_t) (adc_value)); | |||||
//~ DebugSendData(); | |||||
//~ } | |||||
//~ else | |||||
//~ { | |||||
//~ } | |||||
adc_channel = 0; | |||||
} | |||||
ISR(TCA0_CMP1_vect) | |||||
{ | |||||
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP1_bm; | |||||
VREF.CTRLA = VREF_ADC0REFSEL_1V5_gc | VREF_DAC0REFSEL_0V55_gc; | |||||
ADC0.MUXPOS = ADC_MUXPOS_CARTRIDGE_TEMPERATURE; | |||||
_delay_us(10); | |||||
ADC0.COMMAND = ADC_STCONV_bm; | |||||
adc_channel = 100; | |||||
} | |||||
int main(void) | |||||
{ | |||||
CPU_CCP = CCP_IOREG_gc; | |||||
//~ CLKCTRL.MCLKCTRLB = CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm; | |||||
CLKCTRL.MCLKCTRLB = 0; | |||||
/* | |||||
* PA2: power_mosfet | |||||
* PA4: cartridge_resistance_measure (AIN4) | |||||
* PA7: cartridge_current_measure (AIN7) | |||||
*/ | |||||
PORTA.DIR = 0b00000100; | |||||
PORTA.OUT = 0b00000000; | |||||
//~ PORTA.INTFLAGS = ; | |||||
//~ PORTA.PIN0CTRL = ; | |||||
//~ PORTA.PIN1CTRL = ; | |||||
//~ PORTA.PIN2CTRL = ; | |||||
//~ PORTA.PIN3CTRL = ; | |||||
PORTA.PIN4CTRL = PORT_ISC_INPUT_DISABLE_gc; | |||||
//~ PORTA.PIN5CTRL = ; | |||||
//~ PORTA.PIN6CTRL = ; | |||||
PORTA.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc; | |||||
/* | |||||
* PB2: TxD | |||||
* PB3: RxD | |||||
* PB4: v_in_measure (AIN9) | |||||
* PB5: cartridge_temperature_measure (AIN8) | |||||
*/ | |||||
PORTB.DIR = 0b00000100; | |||||
PORTB.OUT = 0b00001000; | |||||
//~ PORTB.INTFLAGS = ; | |||||
//~ PORTB.PIN0CTRL = ; | |||||
//~ PORTB.PIN1CTRL = ; | |||||
//~ PORTB.PIN2CTRL = ; | |||||
//~ PORTB.PIN3CTRL = ; | |||||
PORTB.PIN4CTRL = PORT_ISC_INPUT_DISABLE_gc; | |||||
PORTB.PIN5CTRL = PORT_ISC_INPUT_DISABLE_gc; | |||||
//~ PORTB.PIN6CTRL = ; | |||||
//~ PORTB.PIN7CTRL = ; | |||||
/* | |||||
* PC0: measure_mosfet | |||||
*/ | |||||
PORTC.DIR = 0b00000001; | |||||
PORTC.OUT = 0b00000000; | |||||
//~ PORTC.INTFLAGS = ; | |||||
//~ PORTC.PIN0CTRL = ; | |||||
//~ PORTC.PIN1CTRL = ; | |||||
//~ PORTC.PIN2CTRL = ; | |||||
//~ PORTC.PIN3CTRL = ; | |||||
//~ PORTC.PIN4CTRL = ; | |||||
//~ PORTC.PIN5CTRL = ; | |||||
// configure USART | |||||
USART0.BAUD = DEF_BAUD; | |||||
USART0.CTRLC = USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_SBMODE_1BIT_gc | USART_CHSIZE_8BIT_gc; | |||||
USART0.CTRLB = USART_RXEN_bm | USART_TXEN_bm | USART_RXMODE_NORMAL_gc; | |||||
USART0.CTRLA = USART_RXCIE_bm | USART_RS485_OFF_gc; | |||||
//~ while (RTC.STATUS > 0) {} // Wait for all register to be synchronized | |||||
//~ RTC.CLKSEL = 0b00000000; | |||||
//~ //RTC.CNTL = 0; | |||||
//~ //RTC.CNTH = 0; | |||||
//~ //RTC.CMPL = 10; | |||||
//~ //RTC.CMPH = 0; | |||||
//~ RTC.PERL = 0; | |||||
//~ RTC.PERH = 134; | |||||
//~ RTC.INTCTRL = 0b00000010; | |||||
//~ RTC.CTRLA = 0b10000001; | |||||
// configure VREF | |||||
VREF.CTRLA = VREF_ADC0REFSEL_0V55_gc | VREF_DAC0REFSEL_0V55_gc; | |||||
VREF.CTRLB = VREF_ADC0REFEN_bm | VREF_DAC0REFEN_bm; | |||||
// configure ADC | |||||
ADC0.CTRLB = ADC_SAMPNUM_ACC1_gc; | |||||
ADC0.CTRLC = ADC_REFSEL_INTREF_gc | ADC_PRESC_DIV256_gc; | |||||
ADC0.CTRLD = ADC_INITDLY_DLY0_gc; | |||||
ADC0.CTRLE = ADC_WINCM_NONE_gc; | |||||
ADC0.MUXPOS = ADC_MUXPOS_CARTRIDGE_RESISTANCE; | |||||
ADC0.INTCTRL = ADC_RESRDY_bm; | |||||
ADC0.CTRLA = ADC_ENABLE_bm; | |||||
// configure DAC | |||||
DAC0.DATA = 112; | |||||
DAC0.CTRLA = DAC_RUNSTDBY_bm |DAC_ENABLE_bm; | |||||
// configure AC0 | |||||
AC0.MUXCTRLA = AC_MUXPOS_PIN0_gc | AC_MUXNEG_DAC_gc; | |||||
AC0.CTRLA = AC_RUNSTDBY_bm | AC_ENABLE_bm; | |||||
//~ AC0.CTRLA = AC_RUNSTDBY_bm | AC_OUTEN_bm | AC_LPMODE_bm | AC_ENABLE_bm; | |||||
// configure TCA0 | |||||
TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_SINGLESLOPE_gc; | |||||
TCA0.SINGLE.INTCTRL = TCA_SINGLE_CMP1EN_bm; | |||||
TCA0.SINGLE.CNT = 0; | |||||
TCA0.SINGLE.PER = 976; | |||||
TCA0.SINGLE.CMP0BUF = 0; | |||||
TCA0.SINGLE.CMP1BUF = 900; | |||||
// configure TCB0 | |||||
TCB0.CTRLB = TCB_ASYNC_bm | TCB_CCMPEN_bm | TCB_CNTMODE_SINGLE_gc; | |||||
TCB0.EVCTRL = TCB_CAPTEI_bm; | |||||
TCB0.CCMP = 50; | |||||
TCB0.CNT = 0; | |||||
// configure CCL | |||||
CCL.SEQCTRL0 = CCL_SEQSEL_RS_gc; | |||||
//~ CCL.LUT0CTRLB = CCL_INSEL1_AC0_gc | CCL_INSEL0_TCA0_gc; | |||||
//~ CCL.TRUTH0 = 0b00001010; | |||||
//~ CCL.LUT0CTRLB = CCL_INSEL1_TCB0_gc; | |||||
//~ CCL.LUT0CTRLB = CCL_INSEL0_TCA0_gc; | |||||
CCL.LUT0CTRLB = CCL_INSEL1_TCB0_gc | CCL_INSEL0_TCA0_gc; | |||||
CCL.LUT0CTRLC = CCL_INSEL2_FEEDBACK_gc; | |||||
CCL.TRUTH0 = 0b00000010; | |||||
CCL.LUT0CTRLA = CCL_EDGEDET_bm | CCL_ENABLE_bm; | |||||
//~ CCL.LUT1CTRLB = CCL_INSEL1_AC0_gc | CCL_INSEL0_TCA0_gc; | |||||
//~ CCL.TRUTH1 = 0b00001101; | |||||
CCL.LUT1CTRLB = CCL_INSEL1_AC0_gc | CCL_INSEL0_TCA0_gc; | |||||
CCL.TRUTH1 = 0b00001101; | |||||
//~ CCL.LUT1CTRLA = CCL_EDGEDET_bm | CCL_FILTSEL_SYNCH_gc | CCL_ENABLE_bm; | |||||
CCL.LUT1CTRLA = CCL_ENABLE_bm; | |||||
CCL.CTRLA = CCL_ENABLE_bm; | |||||
// configure EVSYS | |||||
EVSYS.ASYNCCH0 = EVSYS_ASYNCCH0_CCL_LUT0_gc; | |||||
EVSYS.ASYNCCH1 = EVSYS_ASYNCCH1_AC0_OUT_gc; | |||||
EVSYS.ASYNCUSER_EVOUT0 = EVSYS_ASYNCUSER_ASYNCCH0_gc; | |||||
EVSYS.ASYNCUSER_TCB0 = EVSYS_ASYNCUSER_ASYNCCH1_gc; | |||||
//~ EVSYS.ASYNCUSER_CCL_LUT0EV0 = EVSYS_ASYNCUSER_ASYNCCH2_gc; | |||||
PORTMUX.CTRLA = PORTMUX_EVOUT0_bm; | |||||
sei(); | |||||
TCB0.CTRLA = TCB_ENABLE_bm; | |||||
TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1024_gc | TCA_SINGLE_ENABLE_bm; | |||||
//~ _delay_ms(2000); | |||||
//~ DebugAppendData(0xab); | |||||
//~ DebugAppendData(0xcd); | |||||
//~ DebugAppendData(0xef); | |||||
//~ DebugSendData(); | |||||
uint32_t value; | |||||
while(1) | |||||
{ | |||||
/* | |||||
* debug protocol: 0xff, 0xf1, [length_of_data], [data] | |||||
*/ | |||||
if (debugRxStateMachine == 0x04) | |||||
{ | |||||
switch (debugRxBuffer[0]) | |||||
{ | |||||
//~ case 0x10: | |||||
//~ DebugAppendData(debugRxBuffer[0]); | |||||
//~ if (adc_channel == 0) | |||||
//~ { | |||||
//~ switch (debugRxBuffer[1]) | |||||
//~ { | |||||
//~ case 1: | |||||
//~ VREF.CTRLA = VREF_ADC0REFSEL_0V55_gc | VREF_DAC0REFSEL_0V55_gc; | |||||
//~ ADC0.MUXPOS = ADC_MUXPOS_CARTRIDGE_RESISTANCE; | |||||
//~ _delay_us(10); | |||||
//~ ADC0.COMMAND = ADC_STCONV_bm; | |||||
//~ adc_channel = 1; | |||||
//~ break; | |||||
//~ case 2: | |||||
//~ VREF.CTRLA = VREF_ADC0REFSEL_0V55_gc | VREF_DAC0REFSEL_0V55_gc; | |||||
//~ ADC0.MUXPOS = ADC_MUXPOS_CARTRIDGE_CURRENT; | |||||
//~ _delay_us(10); | |||||
//~ ADC0.COMMAND = ADC_STCONV_bm; | |||||
//~ adc_channel = 2; | |||||
//~ break; | |||||
//~ case 3: | |||||
//~ VREF.CTRLA = VREF_ADC0REFSEL_0V55_gc | VREF_DAC0REFSEL_0V55_gc; | |||||
//~ ADC0.MUXPOS = ADC_MUXPOS_CARTRIDGE_TEMPERATURE; | |||||
//~ _delay_us(10); | |||||
//~ ADC0.COMMAND = ADC_STCONV_bm; | |||||
//~ adc_channel = 3; | |||||
//~ break; | |||||
//~ case 4: | |||||
//~ VREF.CTRLA = VREF_ADC0REFSEL_4V34_gc | VREF_DAC0REFSEL_0V55_gc; | |||||
//~ ADC0.MUXPOS = ADC_MUXPOS_V_IN; | |||||
//~ _delay_us(10); | |||||
//~ ADC0.COMMAND = ADC_STCONV_bm; | |||||
//~ adc_channel = 4; | |||||
//~ break; | |||||
//~ default: | |||||
//~ break; | |||||
//~ } | |||||
//~ DebugAppendData(adc_channel); | |||||
//~ } | |||||
//~ else | |||||
//~ { | |||||
//~ DebugAppendData(255); | |||||
//~ } | |||||
//~ break; | |||||
//~ case 0x20: | |||||
//~ DebugAppendData(debugRxBuffer[0]); | |||||
//~ if (debugRxBuffer[1] > 0) | |||||
//~ { | |||||
//~ PORTC.OUTSET = 0b00000001; | |||||
//~ DebugAppendData(1); | |||||
//~ } | |||||
//~ else | |||||
//~ { | |||||
//~ PORTC.OUTCLR = 0b00000001; | |||||
//~ DebugAppendData(0); | |||||
//~ } | |||||
//~ break; | |||||
case 0x33: | |||||
DebugAppendData(debugRxBuffer[0]); | |||||
debugDataEnable = 1; | |||||
break; | |||||
case 0x34: | |||||
DebugAppendData(debugRxBuffer[0]); | |||||
debugDataEnable = 0; | |||||
break; | |||||
case 0x91: | |||||
DebugAppendData(debugRxBuffer[0]); | |||||
uint16_t receivedTemperatureSet = (uint16_t) (debugRxBuffer[1] * 256 + debugRxBuffer[2]); | |||||
if (receivedTemperatureSet > 400) | |||||
{ | |||||
receivedTemperatureSet = 400; | |||||
} | |||||
tSetBuff = (float) receivedTemperatureSet; | |||||
tSetBuffFlag++; | |||||
value = *(uint32_t*) &tSetBuff; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
break; | |||||
case 0xa0: | |||||
DebugAppendData(debugRxBuffer[0]); | |||||
value = ((uint32_t) debugRxBuffer[1]) << 24 | ((uint32_t) debugRxBuffer[2]) << 16 | ((uint32_t) debugRxBuffer[3]) << 8 | ((uint32_t) debugRxBuffer[4]); | |||||
controllerKpBuff = *(float*) &value; | |||||
controllerKpBuffFlag++; | |||||
value = *(uint32_t*) &controllerKpBuff; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
break; | |||||
case 0xa1: | |||||
DebugAppendData(debugRxBuffer[0]); | |||||
value = ((uint32_t) debugRxBuffer[1]) << 24 | ((uint32_t) debugRxBuffer[2]) << 16 | ((uint32_t) debugRxBuffer[3]) << 8 | ((uint32_t) debugRxBuffer[4]); | |||||
controllerKiBuff = *(float*) &value; | |||||
controllerKiBuffFlag++; | |||||
value = *(uint32_t*) &controllerKiBuff; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
break; | |||||
case 0xa2: | |||||
DebugAppendData(debugRxBuffer[0]); | |||||
value = ((uint32_t) debugRxBuffer[1]) << 24 | ((uint32_t) debugRxBuffer[2]) << 16 | ((uint32_t) debugRxBuffer[3]) << 8 | ((uint32_t) debugRxBuffer[4]); | |||||
controllerKdBuff = *(float*) &value; | |||||
controllerKdBuffFlag++; | |||||
value = *(uint32_t*) &controllerKdBuff; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
break; | |||||
case 0xa3: | |||||
DebugAppendData(debugRxBuffer[0]); | |||||
value = ((uint32_t) debugRxBuffer[1]) << 24 | ((uint32_t) debugRxBuffer[2]) << 16 | ((uint32_t) debugRxBuffer[3]) << 8 | ((uint32_t) debugRxBuffer[4]); | |||||
controllerKitBuff = *(float*) &value; | |||||
controllerKitBuffFlag++; | |||||
value = *(uint32_t*) &controllerKitBuff; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
break; | |||||
case 0xf0: | |||||
DebugAppendData(debugRxBuffer[0]); | |||||
value = *(uint32_t*) &tSet; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
value = *(uint32_t*) &controllerKp; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
value = *(uint32_t*) &controllerKi; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
value = *(uint32_t*) &controllerKd; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
value = *(uint32_t*) &controllerKit; | |||||
DebugAppendData((uint8_t) ((value & 0xFF000000) >> 24)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF0000) >> 16)); | |||||
DebugAppendData((uint8_t) ((value & 0xFF00) >> 8)); | |||||
DebugAppendData((uint8_t) (value & 0x00FF)); | |||||
break; | |||||
default: | |||||
DebugAppendData(0xff); | |||||
DebugAppendData(0xde); | |||||
DebugAppendData(0xad); | |||||
DebugAppendData(0xbe); | |||||
DebugAppendData(0xef); | |||||
break; | |||||
} | |||||
DebugSendData(); | |||||
debugRxFrameLength = 0; | |||||
debugRxStateMachine = 0x00; | |||||
} | |||||
} | |||||
} |
@ -0,0 +1,43 @@ | |||||
#ifndef _AVR_ATTINY817_H_INCLUDED | |||||
# error "<avr/iotn817.h> must be included before this file." | |||||
#endif | |||||
/* | |||||
-------------------------------------------------------------------------- | |||||
EVSYS - Event System | |||||
-------------------------------------------------------------------------- | |||||
*/ | |||||
#define ASYNCUSER_TCB0 ASYNCUSER0 | |||||
#define ASYNCUSER_ADC0 ASYNCUSER1 | |||||
#define ASYNCUSER_CCL_LUT0EV0 ASYNCUSER2 | |||||
#define ASYNCUSER_CCL_LUT1EV0 ASYNCUSER3 | |||||
#define ASYNCUSER_CCL_LUT0EV1 ASYNCUSER4 | |||||
#define ASYNCUSER_CCL_LUT1EV1 ASYNCUSER5 | |||||
#define ASYNCUSER_TCD0_EV0 ASYNCUSER6 | |||||
#define ASYNCUSER_TCD0_EV1 ASYNCUSER7 | |||||
#define ASYNCUSER_EVOUT0 ASYNCUSER8 | |||||
#define ASYNCUSER_EVOUT1 ASYNCUSER9 | |||||
#define ASYNCUSER_EVOUT2 ASYNCUSER10 | |||||
#define SYNCUSER_TCA0 SYNCUSER0 | |||||
#define SYNCUSER_USART0 SYNCUSER1 | |||||
/* Asynchronous User Ch x Input Selection */ | |||||
typedef enum EVSYS_ASYNCUSER_enum | |||||
{ | |||||
EVSYS_ASYNCUSER_OFF_gc = (0x00<<0), /* Off */ | |||||
EVSYS_ASYNCUSER_SYNCCH0_gc = (0x01<<0), /* Synchronous Event Channel 0 */ | |||||
EVSYS_ASYNCUSER_SYNCCH1_gc = (0x02<<0), /* Synchronous Event Channel 1 */ | |||||
EVSYS_ASYNCUSER_ASYNCCH0_gc = (0x03<<0), /* Asynchronous Event Channel 0 */ | |||||
EVSYS_ASYNCUSER_ASYNCCH1_gc = (0x04<<0), /* Asynchronous Event Channel 1 */ | |||||
EVSYS_ASYNCUSER_ASYNCCH2_gc = (0x05<<0), /* Asynchronous Event Channel 2 */ | |||||
EVSYS_ASYNCUSER_ASYNCCH3_gc = (0x06<<0), /* Asynchronous Event Channel 3 */ | |||||
} EVSYS_ASYNCUSER_t; | |||||
/* Synchronous User Ch x Input Selection */ | |||||
typedef enum EVSYS_SYNCUSER_enum | |||||
{ | |||||
EVSYS_SYNCUSER_OFF_gc = (0x00<<0), /* Off */ | |||||
EVSYS_SYNCUSER_SYNCCH0_gc = (0x01<<0), /* Synchronous Event Channel 0 */ | |||||
EVSYS_SYNCUSER_SYNCCH1_gc = (0x02<<0), /* Synchronous Event Channel 1 */ | |||||
} EVSYS_SYNCUSER_t; |
@ -0,0 +1,481 @@ | |||||
# Hey Emacs, this is a -*- makefile -*- | |||||
# | |||||
# WinAVR makefile written by Eric B. Weddington, Jörg Wunsch, et al. | |||||
# Released to the Public Domain | |||||
# Please read the make user manual! | |||||
# | |||||
# Additional material for this makefile was submitted by: | |||||
# Tim Henigan | |||||
# Peter Fleury | |||||
# Reiner Patommel | |||||
# Sander Pool | |||||
# Frederik Rouleau | |||||
# Markus Pfaff | |||||
# | |||||
# On command line: | |||||
# | |||||
# make all = Make software. | |||||
# | |||||
# make clean = Clean out built project files. | |||||
# | |||||
# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). | |||||
# | |||||
# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio | |||||
# 4.07 or greater). | |||||
# | |||||
# make program = Download the hex file to the device, using avrdude. Please | |||||
# customize the avrdude settings below first! | |||||
# | |||||
# make filename.s = Just compile filename.c into the assembler code only | |||||
# | |||||
# To rebuild project do "make clean" then "make all". | |||||
# | |||||
# mth 2004/09 | |||||
# Differences from WinAVR 20040720 sample: | |||||
# - DEPFLAGS according to Eric Weddingtion's fix (avrfreaks/gcc-forum) | |||||
# - F_OSC Define in CFLAGS and AFLAGS | |||||
# MCU name | |||||
MCU = attiny817 | |||||
# Main Oscillator Frequency | |||||
# This is only used to define F_OSC in all assembler and c-sources. | |||||
F_CPU = 20000000 | |||||
# Output format. (can be srec, ihex, binary) | |||||
FORMAT = ihex | |||||
# Target file name (without extension). | |||||
TARGET = main | |||||
# List C source files here. (C dependencies are automatically generated.) | |||||
SRC = $(TARGET).c | |||||
# List Assembler source files here. | |||||
# Make them always end in a capital .S. Files ending in a lowercase .s | |||||
# will not be considered source files but generated files (assembler | |||||
# output from the compiler), and will be deleted upon "make clean"! | |||||
# Even though the DOS/Win* filesystem matches both .s and .S the same, | |||||
# it will preserve the spelling of the filenames, and gcc itself does | |||||
# care about how the name is spelled on its command-line. | |||||
ASRC = | |||||
# Optimization level, can be [0, 1, 2, 3, s]. | |||||
# 0 = turn off optimization. s = optimize for size. | |||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) | |||||
OPT = s | |||||
# Debugging format. | |||||
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. | |||||
# AVR (extended) COFF requires stabs, plus an avr-objcopy run. | |||||
#DEBUG = stabs | |||||
DEBUG = dwarf-2 | |||||
# List any extra directories to look for include files here. | |||||
# Each directory must be seperated by a space. | |||||
EXTRAINCDIRS = | |||||
# Compiler flag to set the C Standard level. | |||||
# c89 - "ANSI" C | |||||
# gnu89 - c89 plus GCC extensions | |||||
# c99 - ISO C99 standard (not yet fully implemented) | |||||
# gnu99 - c99 plus GCC extensions | |||||
CSTANDARD = -std=gnu99 | |||||
# Place -D or -U options here | |||||
CDEFS = | |||||
# Place -I options here | |||||
CINCS = | |||||
# Compiler flags. | |||||
# -g*: generate debugging information | |||||
# -O*: optimization level | |||||
# -f...: tuning, see GCC manual and avr-libc documentation | |||||
# -Wall...: warning level | |||||
# -Wa,...: tell GCC to pass this to the assembler. | |||||
# -adhlns...: create assembler listing | |||||
CFLAGS = -g$(DEBUG) | |||||
CFLAGS += $(CDEFS) $(CINCS) | |||||
CFLAGS += -O$(OPT) | |||||
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums | |||||
CFLAGS += -Wall -Wstrict-prototypes | |||||
CFLAGS += -Wa,-adhlns=$(<:.c=.lst) | |||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) | |||||
CFLAGS += $(CSTANDARD) | |||||
CFLAGS += -DF_CPU=$(F_CPU) | |||||
#CFLAGS += -B /home/bucde/__avr_gcc/ATtiny_DFP/1.3.172/gcc/dev/attiny817/ | |||||
#CFLAGS += -I /home/bucde/__avr_gcc/ATtiny_DFP/1.3.172/include/ | |||||
# Assembler flags. | |||||
# -Wa,...: tell GCC to pass this to the assembler. | |||||
# -ahlms: create listing | |||||
# -gstabs: have the assembler create line number information; note that | |||||
# for use in COFF files, additional information about filenames | |||||
# and function names needs to be present in the assembler source | |||||
# files -- see avr-libc docs [FIXME: not yet described there] | |||||
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs | |||||
ASFLAGS += -DF_OSC=$(F_OSC) | |||||
#Additional libraries. | |||||
# Minimalistic printf version | |||||
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min | |||||
# Floating point printf version (requires MATH_LIB = -lm below) | |||||
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt | |||||
PRINTF_LIB = | |||||
# Minimalistic scanf version | |||||
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min | |||||
# Floating point + %[ scanf version (requires MATH_LIB = -lm below) | |||||
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt | |||||
SCANF_LIB = | |||||
MATH_LIB = -lm | |||||
# External memory options | |||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!), | |||||
# used for variables (.data/.bss) and heap (malloc()). | |||||
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff | |||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!), | |||||
# only used for heap (malloc()). | |||||
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff | |||||
EXTMEMOPTS = | |||||
# Linker flags. | |||||
# -Wl,...: tell GCC to pass this to linker. | |||||
# -Map: create map file | |||||
# --cref: add cross reference to map file | |||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref | |||||
LDFLAGS += $(EXTMEMOPTS) | |||||
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) | |||||
LDFLAGS += -Ttext=0x0000 | |||||
# Programming support using avrdude. Settings and variables. | |||||
# Programming hardware: alf avr910 avrisp bascom bsd | |||||
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 | |||||
# | |||||
# Type: avrdude -c ? | |||||
# to get a full listing. | |||||
# | |||||
AVRDUDE_PROGRAMMER = xplainedmini_updi | |||||
# com1 = serial port. Use lpt1 to connect to parallel port. | |||||
AVRDUDE_PORT = usb | |||||
# programmer connected to serial device | |||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex | |||||
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep | |||||
# Uncomment the following if you want avrdude's erase cycle counter. | |||||
# Note that this counter needs to be initialized first using -Yn, | |||||
# see avrdude manual. | |||||
#AVRDUDE_ERASE_COUNTER = -y | |||||
# Uncomment the following if you do /not/ wish a verification to be | |||||
# performed after programming the device. | |||||
#AVRDUDE_NO_VERIFY = -V | |||||
# Increase verbosity level. Please use this when submitting bug | |||||
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> | |||||
# to submit bug reports. | |||||
#AVRDUDE_VERBOSE = -v -v | |||||
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) | |||||
#AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) | |||||
#AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) | |||||
#AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) | |||||
#read fuses | |||||
#./avrdude -p atmega4808 -P usb -c xplainedmini_updi -U fuse0:r:fuse_wdtcfg:h -U fuse1:r:fuse_bodcfg:h -U fuse2:r:fuse_osccfg:h -U fuse5:r:fuse_syscfg0:h -U fuse6:r:fuse_syscfg1:h -U fuse7:r:fuse_append:h -U fuse8:r:fuse_bootend:h | |||||
AVRDUDE_FUSE0_WDTCFG = 0x00 | |||||
AVRDUDE_FUSE1_BODCFG = 0x00 | |||||
AVRDUDE_FUSE2_OSCCFG = 0x02 | |||||
AVRDUDE_FUSE5_SYSCFG0 = 0b11101101 | |||||
#AVRDUDE_FUSE5_SYSCFG0[2] must be set to 1 | |||||
#AVRDUDE_FUSE5_SYSCFG0[5] must be set to 1 | |||||
AVRDUDE_FUSE6_SYSCFG1 = 0x00 | |||||
AVRDUDE_FUSE7_APPEND = 0x00 | |||||
AVRDUDE_FUSE8_BOOTEND = 0x00 | |||||
AVRDUDE_WRITE_FUSES = -U fuse0:w:$(AVRDUDE_FUSE0_WDTCFG):m | |||||
AVRDUDE_WRITE_FUSES += -U fuse1:w:$(AVRDUDE_FUSE1_BODCFG):m | |||||
AVRDUDE_WRITE_FUSES += -U fuse2:w:$(AVRDUDE_FUSE2_OSCCFG):m | |||||
AVRDUDE_WRITE_FUSES += -U fuse5:w:$(AVRDUDE_FUSE5_SYSCFG0):m | |||||
AVRDUDE_WRITE_FUSES += -U fuse6:w:$(AVRDUDE_FUSE6_SYSCFG1):m | |||||
AVRDUDE_WRITE_FUSES += -U fuse7:w:$(AVRDUDE_FUSE7_APPEND):m | |||||
AVRDUDE_WRITE_FUSES += -U fuse8:w:$(AVRDUDE_FUSE8_BOOTEND):m | |||||
AVRDUDE_READ_FUSES = -U fuse0:r:fuse0_wdtcfg:h | |||||
AVRDUDE_READ_FUSES += -U fuse1:r:fuse1_bodcfg:h | |||||
AVRDUDE_READ_FUSES += -U fuse2:r:fuse2_osccfg:h | |||||
AVRDUDE_READ_FUSES += -U fuse5:r:fuse5_syscfg0:h | |||||
AVRDUDE_READ_FUSES += -U fuse6:r:fuse6_syscfg1:h | |||||
AVRDUDE_READ_FUSES += -U fuse7:r:fuse7_append:h | |||||
AVRDUDE_READ_FUSES += -U fuse8:r:fuse8_bootend:h | |||||
# --------------------------------------------------------------------------- | |||||
# Define directories, if needed. | |||||
#DIRAVR = /home/bucde/local/avr | |||||
DIRAVR = /home/bucde/documents/hobby/repos/avrgcc | |||||
#DIRAVR = ${AVRGCC} | |||||
DIRAVRBIN = $(DIRAVR)/bin | |||||
#DIRAVRUTILS = $(DIRAVR)/utils/bin | |||||
#DIRINC = . | |||||
#DIRLIB = $(DIRAVR)/avr/lib | |||||
# Define programs and commands. | |||||
SHELL = sh | |||||
CC = $(DIRAVRBIN)/avr-gcc | |||||
OBJCOPY = $(DIRAVRBIN)/avr-objcopy | |||||
OBJDUMP = $(DIRAVRBIN)/avr-objdump | |||||
SIZE = $(DIRAVRBIN)/avr-size | |||||
NM = $(DIRAVRBIN)/avr-nm | |||||
AVRDUDE = $(DIRAVRBIN)/avrdude | |||||
REMOVE = rm -f | |||||
COPY = cp | |||||
# Define Messages | |||||
# English | |||||
MSG_ERRORS_NONE = Errors: none | |||||
MSG_INFO = -------- info -------- | |||||
MSG_BEGIN = -------- begin -------- | |||||
MSG_END = -------- end -------- | |||||
MSG_SIZE_BEFORE = Size before: | |||||
MSG_SIZE_AFTER = Size after: | |||||
MSG_COFF = Converting to AVR COFF: | |||||
MSG_EXTENDED_COFF = Converting to AVR Extended COFF: | |||||
MSG_FLASH = Creating load file for Flash: | |||||
MSG_EEPROM = Creating load file for EEPROM: | |||||
MSG_EXTENDED_LISTING = Creating Extended Listing: | |||||
MSG_SYMBOL_TABLE = Creating Symbol Table: | |||||
MSG_LINKING = Linking: | |||||
MSG_COMPILING = Compiling: | |||||
MSG_ASSEMBLING = Assembling: | |||||
MSG_CLEANING = Cleaning project: | |||||
# Define all object files. | |||||
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) | |||||
# Define all listing files. | |||||
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) | |||||
# Compiler flags to generate dependency files. | |||||
### GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d | |||||
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d | |||||
# Combine all necessary flags and optional flags. | |||||
# Add target processor to flags. | |||||
#ALL_CFLAGS = -mmcu=$(MCU) -B /home/bucde/local/packs/Atmel.ATtiny_DFP.1.3.172.atpack_FILES/gcc/dev/attiny817 -I. $(CFLAGS) $(GENDEPFLAGS) | |||||
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) | |||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) | |||||
# Default target. | |||||
all: info begin gccversion sizebefore build sizeafter finished end | |||||
build: elf hex eep lss sym | |||||
elf: $(TARGET).elf | |||||
hex: $(TARGET).hex | |||||
eep: $(TARGET).eep | |||||
lss: $(TARGET).lss | |||||
sym: $(TARGET).sym | |||||
# Eye candy. | |||||
# AVR Studio 3.x does not check make's exit code but relies on | |||||
# the following magic strings to be generated by the compile job. | |||||
begin: | |||||
@echo | |||||
@echo $(MSG_BEGIN) | |||||
finished: | |||||
@echo $(MSG_ERRORS_NONE) | |||||
end: | |||||
@echo $(MSG_END) | |||||
@echo | |||||
# Display size of file. | |||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex | |||||
ELFSIZE = $(SIZE) -A $(TARGET).elf | |||||
sizebefore: | |||||
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi | |||||
sizeafter: | |||||
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi | |||||
info: | |||||
@echo | |||||
@echo $(MSG_INFO) | |||||
@echo MCU: $(MCU) | |||||
@echo F_CPU: $(F_CPU) | |||||
# Display compiler version information. | |||||
gccversion : | |||||
@$(CC) --version | |||||
# Program the device. | |||||
program: $(TARGET).hex $(TARGET).eep | |||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) | |||||
flashfuses : | |||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES) | |||||
readfuses : | |||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES) | |||||
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. | |||||
COFFCONVERT=$(OBJCOPY) --debugging \ | |||||
--change-section-address .data-0x800000 \ | |||||
--change-section-address .bss-0x800000 \ | |||||
--change-section-address .noinit-0x800000 \ | |||||
--change-section-address .eeprom-0x810000 | |||||
coff: $(TARGET).elf | |||||
@echo | |||||
@echo $(MSG_COFF) $(TARGET).cof | |||||
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof | |||||
extcoff: $(TARGET).elf | |||||
@echo | |||||
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof | |||||
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof | |||||
# Create final output files (.hex, .eep) from ELF output file. | |||||
%.hex: %.elf | |||||
@echo | |||||
@echo $(MSG_FLASH) $@ | |||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ | |||||
%.eep: %.elf | |||||
@echo | |||||
@echo $(MSG_EEPROM) $@ | |||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ | |||||
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@ | |||||
# Create extended listing file from ELF output file. | |||||
%.lss: %.elf | |||||
@echo | |||||
@echo $(MSG_EXTENDED_LISTING) $@ | |||||
$(OBJDUMP) -h -S $< > $@ | |||||
# Create a symbol table from ELF output file. | |||||
%.sym: %.elf | |||||
@echo | |||||
@echo $(MSG_SYMBOL_TABLE) $@ | |||||
$(NM) -n $< > $@ | |||||
# Link: create ELF output file from object files. | |||||
.SECONDARY : $(TARGET).elf | |||||
.PRECIOUS : $(OBJ) | |||||
%.elf: $(OBJ) | |||||
@echo | |||||
@echo $(MSG_LINKING) $@ | |||||
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) | |||||
# Compile: create object files from C source files. | |||||
%.o : %.c | |||||
@echo | |||||
@echo $(MSG_COMPILING) $< | |||||
$(CC) -c $(ALL_CFLAGS) $< -o $@ | |||||
# Compile: create assembler files from C source files. | |||||
%.s : %.c | |||||
$(CC) -S $(ALL_CFLAGS) $< -o $@ | |||||
# Assemble: create object files from assembler source files. | |||||
%.o : %.S | |||||
@echo | |||||
@echo $(MSG_ASSEMBLING) $< | |||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@ | |||||
# Target: clean project. | |||||
clean: begin clean_list finished end | |||||
clean_list : | |||||
@echo | |||||
@echo $(MSG_CLEANING) | |||||
$(REMOVE) $(TARGET).hex | |||||
$(REMOVE) $(TARGET).eep | |||||
$(REMOVE) $(TARGET).obj | |||||
$(REMOVE) $(TARGET).cof | |||||
$(REMOVE) $(TARGET).elf | |||||
$(REMOVE) $(TARGET).map | |||||
$(REMOVE) $(TARGET).obj | |||||
$(REMOVE) $(TARGET).a90 | |||||
$(REMOVE) $(TARGET).sym | |||||
$(REMOVE) $(TARGET).lnk | |||||
$(REMOVE) $(TARGET).lss | |||||
$(REMOVE) $(OBJ) | |||||
$(REMOVE) $(LST) | |||||
$(REMOVE) $(SRC:.c=.s) | |||||
$(REMOVE) $(SRC:.c=.d) | |||||
$(REMOVE) .dep/* | |||||
# Include the dependency files. | |||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) | |||||
# Listing of phony targets. | |||||
.PHONY : all begin finish end sizebefore sizeafter gccversion \ | |||||
build elf hex eep lss sym coff extcoff \ | |||||
clean clean_list program |