Browse Source

ADD copied local files to repo

master
bucde 3 years ago
parent
commit
65b128ab01
5 changed files with 2300 additions and 0 deletions
  1. +399
    -0
      app.py
  2. +444
    -0
      app2.py
  3. +933
    -0
      main.c
  4. +43
    -0
      main.h
  5. +481
    -0
      makefile

+ 399
- 0
app.py View File

@ -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()

+ 444
- 0
app2.py View File

@ -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()

+ 933
- 0
main.c View File

@ -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;
}
}
}

+ 43
- 0
main.h View File

@ -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;

+ 481
- 0
makefile View File

@ -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

Loading…
Cancel
Save