Added old firmware and pcb design files

These are all design documents that I thought I had lost. It's may make
me cringe, but it's still cool to use it to see how far I've come.
This commit is contained in:
2016-05-12 20:04:43 -07:00
parent a4df0d921d
commit b300c76103
1047 changed files with 379298 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
#include "AxisClass.h"
#include <Arduino.h>
extern const unsigned char Microstep[6][3];
Axis::Axis (unsigned char AxisStep, unsigned char AxisDir, unsigned char AxisM0, unsigned char AxisM1, unsigned char AxisM2, unsigned char AxisFault){
p_Step = AxisStep;
p_Dir = AxisDir;
p_M0 = AxisM0;
p_M1 = AxisM1;
p_M2 = AxisM2;
p_Fault = AxisFault;
DelVal = 8;
pinMode(p_Step, OUTPUT);
pinMode(p_Dir, OUTPUT);
pinMode(p_M0, OUTPUT);
pinMode(p_M1, OUTPUT);
pinMode(p_M2, OUTPUT);
pinMode(p_Fault, INPUT);
SetMicrostep(8);
}
void Axis::SetMicrostep(unsigned char Level){
unsigned char row = -1;
switch (Level){
case 1:
row = 0;
break;
case 2:
row = 1;
break;
case 4:
row = 2;
break;
case 8:
row = 3;
break;
case 16:
row = 4;
break;
case 32:
row = 5;
break;
}
digitalWrite(p_M0, Microstep[row][0]);
digitalWrite(p_M1, Microstep[row][1]);
digitalWrite(p_M2, Microstep[row][2]);
}
void Axis::StepForward(){
digitalWrite(p_Dir, HIGH);
digitalWrite(p_Step, HIGH);
digitalWrite(p_Step, LOW);
}
void Axis::StepBackward(){
digitalWrite(p_Dir, LOW);
digitalWrite(p_Step, HIGH);
digitalWrite(p_Step, LOW);
}
int Axis::SetRPM(int RPM){
int CountVal = ((16000000L/8)/((200L*8*RPM)/60));
cli();
OCR1A = CountVal;
sei();
return CountVal;
}
void Axis::SetDelay(unsigned int delLen){
DelVal = delLen;
}

View File

@@ -0,0 +1,49 @@
#ifndef AXIS_CLASS_H
#define AXIS_CLASS_H
const unsigned char Microstep[6][3] = {
{
0, 0, 0
}
,
{
1, 0, 0
}
,
{
0, 1, 0
}
,
{
1, 1, 0
}
,
{
0, 0, 1
}
,
{
1, 0, 1
}
};
class Axis {
private:
unsigned char p_Step;
unsigned char p_Dir;
unsigned char p_M0;
unsigned char p_M1;
unsigned char p_M2;
unsigned char p_Fault;
unsigned int DelVal;
public:
Axis (unsigned char AxisStep, unsigned char AxisDir, unsigned char AxisM0, unsigned char AxisM1, unsigned char AxisM2, unsigned char AxisFault);
void SetMicrostep(unsigned char Level);
void StepForward();
void StepBackward();
int SetRPM(int RPM);
void SetDelay(unsigned int delLen);
};
#endif

View File

@@ -0,0 +1,73 @@
#include "DriverBoardClass.h"
#include <Arduino.h>
DriverBoard::DriverBoard(Axis *XAxisPt,Axis *YAxisPt, Axis *ZAxisPt, unsigned char ServoP, unsigned char StatusLed, unsigned char ErrorLed, unsigned char M_Enable, unsigned char ESTOP, unsigned char LimitESTOP, unsigned char X1_Lim, unsigned char X2_Lim, unsigned char Y1_Lim,
unsigned char Y2_Lim, unsigned char Z1_Lim, unsigned char Z2_Lim, unsigned char A1_Lim, unsigned char A2_Lim, unsigned char XJL, unsigned char XJR, unsigned char YJF, unsigned char YJB, unsigned char ZJU,
unsigned char ZJD, unsigned char AJF, unsigned char AJB, unsigned char JSI, unsigned char JSD){
//Assign Pins to Class Variables
XAxis = XAxisPt;
YAxis = YAxisPt;
ZAxis = ZAxisPt;
p_Servo = ServoP;
p_StatusLed = StatusLed;
p_ErrorLed = ErrorLed;
p_M_Enable = M_Enable;
p_ESTOP = ESTOP;
p_LimitESTOP = LimitESTOP;
p_X1_Lim = X1_Lim;
p_X2_Lim = X2_Lim;
p_Y1_Lim = Y1_Lim;
p_Y2_Lim = Y2_Lim;
p_Z1_Lim = Z1_Lim;
p_Z2_Lim = Z2_Lim;
p_A1_Lim = A1_Lim;
p_A2_Lim = A2_Lim;
p_XJL = XJL;
p_XJR = XJR;
p_YJF = YJF;
p_YJB = YJB;
p_ZJU = ZJU;
p_ZJD = ZJD;
p_AJF = AJF;
p_AJB = AJB;
p_JSI = JSI;
p_JSD = JSD;
//Set pin modes for output pins
pinMode(p_Servo, OUTPUT);
pinMode(p_StatusLed, OUTPUT);
pinMode(p_ErrorLed, OUTPUT);
pinMode(p_M_Enable, OUTPUT);
//Set pin modes for input pins
pinMode(p_ESTOP, INPUT);
pinMode(p_LimitESTOP, INPUT);
pinMode(p_X1_Lim, INPUT);
pinMode(p_X2_Lim, INPUT);
pinMode(p_Y1_Lim, INPUT);
pinMode(p_Y2_Lim, INPUT);
pinMode(p_Z1_Lim, INPUT);
pinMode(p_Z2_Lim, INPUT);
pinMode(p_A1_Lim, INPUT);
pinMode(p_A2_Lim, INPUT);
pinMode(p_XJL, INPUT);
pinMode(p_XJR, INPUT);
pinMode(p_YJF, INPUT);
pinMode(p_YJB, INPUT);
pinMode(p_ZJU, INPUT);
pinMode(p_ZJD, INPUT);
pinMode(p_AJF, INPUT);
pinMode(p_AJB, INPUT);
pinMode(p_JSI, INPUT);
pinMode(p_JSD, INPUT);
digitalWrite(p_M_Enable, LOW); //Enable motor drivers
};
void DriverBoard::MoveToPosition(long XPos){
XAxis->StepForward();
YAxis->StepForward();
ZAxis->StepForward();
}

View File

@@ -0,0 +1,53 @@
#ifndef DRIVERBOARD_CLASS_H
#define DRIVERBOARD_CLASS_H
#include "AxisClass.h"
//extern Axis XAxis;
///extern Axis YAxis;
//extern Axis ZAxis;
class DriverBoard{
private:
float CurXPos;
float CurYPos;
float CurZPos;
unsigned char p_Servo;
unsigned char p_StatusLed;
unsigned char p_ErrorLed;
unsigned char p_M_Enable;
unsigned char p_ESTOP;
unsigned char p_LimitESTOP;
unsigned char p_X1_Lim;
unsigned char p_X2_Lim;
unsigned char p_Y1_Lim;
unsigned char p_Y2_Lim;
unsigned char p_Z1_Lim;
unsigned char p_Z2_Lim;
unsigned char p_A1_Lim;
unsigned char p_A2_Lim;
unsigned char p_XJL;
unsigned char p_XJR;
unsigned char p_YJF;
unsigned char p_YJB;
unsigned char p_ZJU;
unsigned char p_ZJD;
unsigned char p_AJF;
unsigned char p_AJB;
unsigned char p_JSI;
unsigned char p_JSD;
Axis *XAxis;
Axis *YAxis;
Axis *ZAxis;
public:
DriverBoard(Axis *XAxisPt, Axis *YAxisPt, Axis *ZAxisPt, unsigned char ServoP, unsigned char StatusLed, unsigned char ErrorLed, unsigned char M_Enable, unsigned char ESTOP, unsigned char LimitESTOP, unsigned char X1_Lim, unsigned char X2_Lim, unsigned char Y1_Lim,
unsigned char Y2_Lim, unsigned char Z1_Lim, unsigned char Z2_Lim, unsigned char A1_Lim, unsigned char A2_Lim, unsigned char XJL, unsigned char XJR, unsigned char YJF, unsigned char YJB, unsigned char ZJU,
unsigned char ZJD, unsigned char AJF, unsigned char AJB, unsigned char JSI, unsigned char JSD);
void MoveToPosition(long XPos);
};
#endif

View File

@@ -0,0 +1,159 @@
#include <SoftwareSerial.h>
#include "DriverBoardClass.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Pin Definitions
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Inputs/////////////////////////////////////////
////////////////////////////////////////////////
const unsigned char p_ESTOP = 2;
const unsigned char p_LimitESTOP = 3;
const unsigned char p_XFault = 27;
const unsigned char p_YFault = 33;
const unsigned char p_AFault = 41;
const unsigned char p_SFault = A13;
const unsigned char p_X1_Lim = A0;
const unsigned char p_X2_Lim = A1;
const unsigned char p_Y1_Lim = A2;
const unsigned char p_Y2_Lim = A3;
const unsigned char p_Z1_Lim = A4;
const unsigned char p_Z2_Lim = A5;
const unsigned char p_A1_Lim = A6;
const unsigned char p_A2_Lim = A7;
const unsigned char p_XJL = 42;
const unsigned char p_XJR = 43;
const unsigned char p_YJF = 44;
const unsigned char p_YJB = 45;
const unsigned char p_ZJU = 46;
const unsigned char p_ZJD = 47;
const unsigned char p_AJF = 48;
const unsigned char p_AJB = 49;
const unsigned char p_JSI = A14;
const unsigned char p_JSD = A15;
/////////////////////////////////////////////////
//Outputs////////////////////////////////////////
////////////////////////////////////////////////
const unsigned char p_M_Enable = 13;
const unsigned char p_StatusLed = 8;
const unsigned char p_ErrorLed = 9;
const unsigned char p_XStep = 22;
const unsigned char p_XDir = 23;
const unsigned char p_XM0 = 24;
const unsigned char p_XM1 = 25;
const unsigned char p_XM2 = 26;
const unsigned char p_YStep = 28;
const unsigned char p_YDir = 29;
const unsigned char p_YM0 = 30;
const unsigned char p_YM1 = 31;
const unsigned char p_YM2 = 32;
const unsigned char p_AStep = 34;
const unsigned char p_ADir = 35;
const unsigned char p_AM0 = 36;
const unsigned char p_AM1 = 37;
const unsigned char p_AM2 = 40;
const unsigned char p_SStep = A8;
const unsigned char p_SDir = A9;
const unsigned char p_SM0 = A10;
const unsigned char p_SM1 = A11;
const unsigned char p_SM2 = A12;
const unsigned char p_Servo = 5;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Global Variables and Instantiations
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Axis XAxis(p_XStep, p_XDir, p_XM0, p_XM1, p_XM2, p_XFault);
Axis YAxis(p_YStep, p_YDir, p_YM0, p_YM1, p_YM2, p_YFault);
Axis ZAxis(p_AStep, p_ADir, p_AM0, p_AM1, p_AM2, p_AFault);
DriverBoard myDriver(&XAxis, &YAxis, &ZAxis, p_Servo, p_StatusLed, p_ErrorLed, p_M_Enable, p_ESTOP, p_LimitESTOP, p_X1_Lim, p_X2_Lim, p_Y1_Lim, p_Y2_Lim,
p_Z1_Lim, p_Z2_Lim, p_A1_Lim, p_A2_Lim, p_XJL, p_XJR, p_YJF, p_YJB, p_ZJU, p_ZJD, p_AJF, p_AJB, p_JSI, p_JSD);
SoftwareSerial MySerial(10, 12);
String ReceiveBuffer = "";
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Interrupt Service Routines
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ISR(TIMER1_COMPA_vect){
myDriver.MoveToPosition(1);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Arduino Setup Function
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup(){
// cli();
Serial.begin(4800);
MySerial.begin(4800);
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
PRR1 &= ~(1 << PRTIM1); //Disable power reduction mode on timer 1 ((Might need to be changed...))
TCCR1B |= ((1 << WGM12) | (1 << CS11));// | (1 << CS10)); //Set prescalaer to 64
OCR1A = 2358; //Set count value
TIMSK1 = (1 << OCIE1A);
sei();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Arduino Main Program Loop
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop(){
if(MySerial.available()){
ReceiveBuffer = "";
while(MySerial.available()){
int temp = MySerial.read();
if(isDigit(temp)){
ReceiveBuffer += char(temp);
}
}
//XAxis.SetDelay(ReceiveBuffer.toInt());
//YAxis.SetDelay(ReceiveBuffer.toInt());
//ZAxis.SetDelay(ReceiveBuffer.toInt());
MySerial.println(XAxis.SetRPM(ReceiveBuffer.toInt()));
}
//ZAxis.StepForward();
if(digitalRead(p_XJL)){
myDriver.MoveToPosition(1);
}
else if(digitalRead(p_XJR)){
//myDriver.MoveToPosition(1);
}
if(digitalRead(p_YJF)){
//YAxis.StepForward();
}
else if(digitalRead(p_YJB)){
//YAxis.StepBackward();
}
}

View File

@@ -0,0 +1,380 @@
/*
* DefinesAndMacros.h
*
* Created: 8/9/2014 1:13:12 PM
* Author: corwin
*/
#ifndef DEFINESANDMACROS_H_
#define DEFINESANDMACROS_H_
//////////Led state defines//////////
#define L_RDY 0
#define L_STARTUP 1
#define L_HOME 2
#define L_CAL 3
#define L_RUN 4
#define L_SOFTERR 5
#define L_ERR 6
//////////End led state defines//////////
//////////
#include "usart_driver.h"
#define UARTBUFFERSIZE 100
uint8_t sendArray[UARTBUFFERSIZE];
uint8_t receiveArray[UARTBUFFERSIZE];
USART_data_t usartData;
//////////
#define LOWSTATE 0
#define HIGHSTATE 1
#define ISINPUT 0
#define ISOUTPUT 1
#define TRUE 1
#define FALSE 0
#define PIN__STEP_EN PIN4_bm
#define PORT__STEP_EN PORTF
#define PINDIR__STEP_EN ISOUTPUT
#define INITSTATE__STEP_EN HIGHSTATE
#define STEP_EN_SET() PORT__STEP_EN.OUTSET = PIN__STEP_EN
#define STEP_EN_CLR() PORT__STEP_EN.OUTCLR = PIN__STEP_EN
#define PIN__X_FAULT PIN5_bm
#define PORT__X_FAULT PORTC
#define PINDIR__X_FAULT ISINPUT
#define INITSTATE__X_FAULT HIGHSTATE
#define X_FAULT_GET() (PORTC.IN & PIN__X_FAULT)
#define PIN__X_DIR PIN3_bm
#define PORT__X_DIR PORTC
#define PINDIR__X_DIR ISOUTPUT
#define INITSTATE__X_DIR LOWSTATE
#define X_DIR_SET() PORT__X_DIR.OUTSET = PIN__X_DIR
#define X_DIR_CLR() PORT__X_DIR.OUTCLR = PIN__X_DIR
#define PIN__X_STEP PIN4_bm
#define PORT__X_STEP PORTC
#define PINDIR__X_STEP ISOUTPUT
#define INITSTATE__X_STEP LOWSTATE
#define X_STEP_SET() PORT__X_STEP.OUTSET = PIN__X_STEP
#define X_STEP_CLR() PORT__X_STEP.OUTCLR = PIN__X_STEP
#define PIN__X_M0 PIN0_bm
#define PORT__X_M0 PORTC
#define PINDIR__X_M0 ISOUTPUT
#define INITSTATE__X_M0 LOWSTATE
#define X_M0_SET() PORT__X_M0.OUTSET = PIN__X_M0
#define X_M0_CLR() PORT__X_M0.OUTCLR = PIN__X_M0
#define PIN__X_M1 PIN1_bm
#define PORT__X_M1 PORTC
#define PINDIR__X_M1 ISOUTPUT
#define INITSTATE__X_M1 HIGHSTATE
#define X_M1_SET() PORT__X_M1.OUTSET = PIN__X_M1
#define X_M1_CLR() PORT__X_M1.OUTCLR = PIN__X_M1
#define PIN__X_M2 PIN2_bm
#define PORT__X_M2 PORTC
#define PINDIR__X_M2 ISOUTPUT
#define INITSTATE__X_M2 LOWSTATE
#define X_M2_SET() PORT__X_M2.OUTSET = PIN__X_M2
#define X_M2_CLR() PORT__X_M2.OUTCLR = PIN__X_M2
#define PIN__Y_FAULT PIN3_bm
#define PORT__Y_FAULT PORTD
#define PINDIR__Y_FAULT ISINPUT
#define INITSTATE__Y_FAULT HIGHSTATE
#define Y_FAULT_GET() (PORTD.IN & PIN__Y_FAULT)
#define PIN__Y_DIR PIN1_bm
#define PORT__Y_DIR PORTD
#define PINDIR__Y_DIR ISOUTPUT
#define INITSTATE__Y_DIR LOWSTATE
#define Y_DIR_SET() PORT__Y_DIR.OUTSET = PIN__Y_DIR
#define Y_DIR_CLR() PORT__Y_DIR.OUTCLR = PIN__Y_DIR
#define PIN__Y_STEP PIN2_bm
#define PORT__Y_STEP PORTD
#define PINDIR__Y_STEP ISOUTPUT
#define INITSTATE__Y_STEP LOWSTATE
#define Y_STEP_SET() PORT__Y_STEP.OUTSET = PIN__Y_STEP
#define Y_STEP_CLR() PORT__Y_STEP.OUTCLR = PIN__Y_STEP
#define PIN__Y_M0 PIN6_bm
#define PORT__Y_M0 PORTC
#define PINDIR__Y_M0 ISOUTPUT
#define INITSTATE__Y_M0 LOWSTATE
#define Y_M0_SET() PORT__Y_M0.OUTSET = PIN__Y_M0
#define Y_M0_CLR() PORT__Y_M0.OUTCLR = PIN__Y_M0
#define PIN__Y_M1 PIN7_bm
#define PORT__Y_M1 PORTC
#define PINDIR__Y_M1 ISOUTPUT
#define INITSTATE__Y_M1 HIGHSTATE
#define Y_M1_SET() PORT__Y_M1.OUTSET = PIN__Y_M1
#define Y_M1_CLR() PORT__Y_M1.OUTCLR = PIN__Y_M1
#define PIN__Y_M2 PIN0_bm
#define PORT__Y_M2 PORTD
#define PINDIR__Y_M2 ISOUTPUT
#define INITSTATE__Y_M2 LOWSTATE
#define Y_M2_SET() PORT__Y_M2.OUTSET = PIN__Y_M2
#define Y_M2_CLR() PORT__Y_M2.OUTCLR = PIN__Y_M2
#define PIN__Z_FAULT PIN1_bm
#define PORT__Z_FAULT PORTE
#define PINDIR__Z_FAULT ISINPUT
#define INITSTATE__Z_FAULT HIGHSTATE
#define Z_FAULT_GET() (PORTE.IN & PIN__Z_FAULT)
#define PIN__Z_DIR PIN7_bm
#define PORT__Z_DIR PORTD
#define PINDIR__Z_DIR ISOUTPUT
#define INITSTATE__Z_DIR LOWSTATE
#define Z_DIR_SET() PORT__Z_DIR.OUTSET = PIN__Z_DIR
#define Z_DIR_CLR() PORT__Z_DIR.OUTCLR = PIN__Z_DIR
#define PIN__Z_STEP PIN0_bm
#define PORT__Z_STEP PORTE
#define PINDIR__Z_STEP ISOUTPUT
#define INITSTATE__Z_STEP LOWSTATE
#define Z_STEP_SET() PORT__Z_STEP.OUTSET = PIN__Z_STEP
#define Z_STEP_CLR() PORT__Z_STEP.OUTCLR = PIN__Z_STEP
#define PIN__Z_M0 PIN4_bm
#define PORT__Z_M0 PORTD
#define PINDIR__Z_M0 ISOUTPUT
#define INITSTATE__Z_M0 HIGHSTATE
#define Z_M0_SET() PORT__Z_M0.OUTSET = PIN__Z_M0
#define Z_M0_CLR() PORT__Z_M0.OUTCLR = PIN__Z_M0
#define PIN__Z_M1 PIN5_bm
#define PORT__Z_M1 PORTD
#define PINDIR__Z_M1 ISOUTPUT
#define INITSTATE__Z_M1 HIGHSTATE
#define Z_M1_SET() PORT__Z_M1.OUTSET = PIN__Z_M1
#define Z_M1_CLR() PORT__Z_M1.OUTCLR = PIN__Z_M1
#define PIN__Z_M2 PIN6_bm
#define PORT__Z_M2 PORTD
#define PINDIR__Z_M2 ISOUTPUT
#define INITSTATE__Z_M2 HIGHSTATE
#define Z_M2_SET() PORT__Z_M2.OUTSET = PIN__Z_M2
#define Z_M2_CLR() PORT__Z_M2.OUTCLR = PIN__Z_M2
#define PIN__A_FAULT PIN7_bm
#define PORT__A_FAULT PORTE
#define PINDIR__A_FAULT ISINPUT
#define INITSTATE__A_FAULT HIGHSTATE
#define A_FAULT_GET() (PORTE.IN & PIN__A_FAULT)
#define PIN__A_DIR PIN5_bm
#define PORT__A_DIR PORTE
#define PINDIR__A_DIR ISOUTPUT
#define INITSTATE__A_DIR LOWSTATE
#define A_DIR_SET() PORT__A_DIR.OUTSET = PIN__A_DIR
#define A_DIR_CLR() PORT__A_DIR.OUTCLR = PIN__A_DIR
#define PIN__A_STEP PIN6_bm
#define PORT__A_STEP PORTE
#define PINDIR__A_STEP ISOUTPUT
#define INITSTATE__A_STEP LOWSTATE
#define A_STEP_SET() PORT__A_STEP.OUTSET = PIN__A_STEP
#define A_STEP_CLR() PORT__A_STEP.OUTCLR = PIN__A_STEP
#define PIN__A_M0 PIN2_bm
#define PORT__A_M0 PORTE
#define PINDIR__A_M0 ISOUTPUT
#define INITSTATE__A_M0 LOWSTATE
#define A_M0_SET() PORT__A_M0.OUTSET = PIN__A_M0
#define A_M0_CLR() PORT__A_M0.OUTCLR = PIN__A_M0
#define PIN__A_M1 PIN3_bm
#define PORT__A_M1 PORTE
#define PINDIR__A_M1 ISOUTPUT
#define INITSTATE__A_M1 LOWSTATE
#define A_M1_SET() PORT__A_M1.OUTSET = PIN__A_M1
#define A_M1_CLR() PORT__A_M1.OUTCLR = PIN__A_M1
#define PIN__A_M2 PIN4_bm
#define PORT__A_M2 PORTE
#define PINDIR__A_M2 ISOUTPUT
#define INITSTATE__A_M2 LOWSTATE
#define A_M2_SET() PORT__A_M2.OUTSET = PIN__A_M2
#define A_M2_CLR() PORT__A_M2.OUTCLR = PIN__A_M2
#define PIN__X_LIM_LEFT PIN0_bm
#define PORT__X_LIM_LEFT PORTA
#define PINDIR__X_LIM_LEFT ISINPUT
#define INITSTATE__X_LIM_LEFT HIGHSTATE
#define X_LIM_LEFT_GET() (PORTA.IN & PIN__X_LIM_LEFT)
#define PIN__X_LIM_RIGHT PIN1_bm
#define PORT__X_LIM_RIGHT PORTA
#define PINDIR__X_LIM_RIGHT ISINPUT
#define INITSTATE__X_LIM_RIGHT HIGHSTATE
#define X_LIM_RIGHT_GET() (PORTA.IN & PIN__X_LIM_RIGHT)
#define PIN__Y_LIM_FORW PIN2_bm
#define PORT__Y_LIM_FORW PORTA
#define PINDIR__Y_LIM_FORW ISINPUT
#define INITSTATE__Y_LIM_FORW HIGHSTATE
#define Y_LIM_FORW_GET() (PORTA.IN & PIN__Y_LIM_FORW)
#define PIN__Y_LIM_BACK PIN3_bm
#define PORT__Y_LIM_BACK PORTA
#define PINDIR__Y_LIM_BACK ISINPUT
#define INITSTATE__Y_LIM_BACK HIGHSTATE
#define Y_LIM_BACK_GET() (PORTA.IN & PIN__Y_LIM_BACK)
#define PIN__Z_LIM_DOWN PIN4_bm
#define PORT__Z_LIM_DOWN PORTA
#define PINDIR__Z_LIM_DOWN ISINPUT
#define INITSTATE__Z_LIM_DOWN HIGHSTATE
#define Z_LIM_DOWN_GET() (PORTA.IN & PIN__Z_LIM_DOWN)
#define PIN__A_LIM_1 PIN5_bm
#define PORT__A_LIM_1 PORTA
#define PINDIR__A_LIM_1 ISINPUT
#define INITSTATE__A_LIM_1 HIGHSTATE
#define A_LIM_1_GET() (PORTA.IN & PIN__A_LIM_1)
#define PIN__A_LIM_2 PIN6_bm
#define PORT__A_LIM_2 PORTA
#define PINDIR__A_LIM_2 ISINPUT
#define INITSTATE__A_LIM_2 HIGHSTATE
#define A_LIM_2_GET() (PORTA.IN & PIN__A_LIM_2)
#define PIN__SYS_CHNG_STATE PIN7_bm
#define PORT__SYS_CHNG_STATE PORTA
#define PINDIR__SYS_CHNG_STATE ISINPUT
#define INITSTATE__SYS_CHNG_STATE HIGHSTATE
#define SYS_CHNG_STATE_GET() (PORTA.IN & PIN__SYS_CHNG_STATE)
#define PIN__SYS_START PIN0_bm
#define PORT__SYS_START PORTB
#define PINDIR__SYS_START ISINPUT
#define INITSTATE__SYS_START HIGHSTATE
#define SYS_START_GET() (PORTB.IN & PIN__SYS_START)
#define PIN__SYS_STOP PIN1_bm
#define PORT__SYS_STOP PORTB
#define PINDIR__SYS_STOP ISINPUT
#define INITSTATE__SYS_STOP HIGHSTATE
#define SYS_STOP_GET() (PORTB.IN & PIN__SYS_STOP)
#define PIN__SYS_HOME PIN2_bm
#define PORT__SYS_HOME PORTB
#define PINDIR__SYS_HOME ISINPUT
#define INITSTATE__SYS_HOME HIGHSTATE
#define SYS_HOME_GET() (PORTB.IN & PIN__SYS_HOME)
#define PIN__SYS_CAL PIN3_bm
#define PORT__SYS_CAL PORTB
#define PINDIR__SYS_CAL ISINPUT
#define INITSTATE__SYS_CAL HIGHSTATE
#define SYS_CAL_GET() (PORTB.IN & PIN__SYS_CAL)
#define PIN__ESTOP PIN0_bm
#define PORT__ESTOP PORTF
#define PINDIR__ESTOP ISINPUT
#define INITSTATE__ESTOP HIGHSTATE
#define ESTOP_GET() (PORTF.IN & PIN__ESTOP)
#define PIN__LIGHT_CTRL PIN1_bm
#define PORT__LIGHT_CTRL PORTF
#define PINDIR__LIGHT_CTRL ISOUTPUT
#define INITSTATE__LIGHT_CTRL LOWSTATE
#define LIGHT_CTRL_SET() PORT__LIGHT_CTRL.OUTSET = PIN__LIGHT_CTRL
#define LIGHT_CTRL_CLR() PORT__LIGHT_CTRL.OUTCLR = PIN__LIGHT_CTRL
#define PIN__UART_RX PIN2_bm
#define PORT__UART_RX PORTF
#define PINDIR__UART_RX ISINPUT
#define INITSTATE__UART_RX HIGHSTATE
#define UART_RX_GET() (PORTF.IN & PIN__UART_RX)
#define PIN__UART_TX PIN3_bm
#define PORT__UART_TX PORTF
#define PINDIR__UART_TX ISOUTPUT
#define INITSTATE__UART_TX HIGHSTATE
#define UART_TX_SET() PORT__UART_TX.OUTSET = PIN__UART_TX
#define UART_TX_CLR() PORT__UART_TX.OUTCLR = PIN__UART_TX
#define PIN__RDY_LED PIN5_bm
#define PORT__RDY_LED PORTF
#define PINDIR__RDY_LED ISOUTPUT
#define INITSTATE__RDY_LED LOWSTATE
#define RDY_LED_SET() PORT__RDY_LED.OUTSET = PIN__RDY_LED
#define RDY_LED_CLR() PORT__RDY_LED.OUTCLR = PIN__RDY_LED
#define RDY_LED_TGL() PORT__RDY_LED.OUTTGL = PIN__RDY_LED
#define PIN__RUN_LED PIN6_bm
#define PORT__RUN_LED PORTF
#define PINDIR__RUN_LED ISOUTPUT
#define INITSTATE__RUN_LED LOWSTATE
#define RUN_LED_SET() PORT__RUN_LED.OUTSET = PIN__RUN_LED
#define RUN_LED_CLR() PORT__RUN_LED.OUTCLR = PIN__RUN_LED
#define RUN_LED_TGL() PORT__RUN_LED.OUTTGL = PIN__RUN_LED
#define PIN__ERR_LED PIN7_bm
#define PORT__ERR_LED PORTF
#define PINDIR__ERR_LED ISOUTPUT
#define INITSTATE__ERR_LED LOWSTATE
#define ERR_LED_SET() PORT__ERR_LED.OUTSET = PIN__ERR_LED
#define ERR_LED_CLR() PORT__ERR_LED.OUTCLR = PIN__ERR_LED
#define ERR_LED_TGL() PORT__ERR_LED.OUTTGL = PIN__ERR_LED
#endif /* DEFINESANDMACROS_H_ */

View File

@@ -0,0 +1,331 @@
/*
* InitFunctions.c
*
* Created: 8/9/2014 4:24:25 PM
* Author: corwin
*/
#include "InitFunctions.h"
void setupDriverBoardComplete()
{
setupXMEGAIO();
setupXMEGAClock();
setupXMEGAUART();
setupXMEGATimers();
setupStepperPararms();
setupPinChangeInterrupts();
PMIC.CTRL |= PMIC_LOLVLEN_bm;
sei();
}
void testDriverBoardComplete()
{
testStatusLeds();
testLightBoard();
testSteppers();
testUART();
}
void setupXMEGAIO()
{
//Setup motor enable control
setupIOPin(&PORT__STEP_EN, PIN__STEP_EN, PINDIR__STEP_EN, INITSTATE__STEP_EN);
//Setup X Axis motor driver
setupIOPin(&PORT__X_FAULT, PIN__X_FAULT, PINDIR__X_FAULT, INITSTATE__X_FAULT);
setupIOPin(&PORT__X_DIR, PIN__X_DIR, PINDIR__X_DIR, INITSTATE__X_DIR);
setupIOPin(&PORT__X_STEP, PIN__X_STEP, PINDIR__X_STEP, INITSTATE__X_STEP);
setupIOPin(&PORT__X_M0, PIN__X_M0, PINDIR__X_M0, INITSTATE__X_M0);
setupIOPin(&PORT__X_M1, PIN__X_M1, PINDIR__X_M1, INITSTATE__X_M1);
setupIOPin(&PORT__X_M2, PIN__X_M2, PINDIR__X_M2, INITSTATE__X_M2);
//Setup Y Axis motor driver
setupIOPin(&PORT__Y_FAULT, PIN__Y_FAULT, PINDIR__Y_FAULT, INITSTATE__Y_FAULT);
setupIOPin(&PORT__Y_DIR, PIN__Y_DIR, PINDIR__Y_DIR, INITSTATE__Y_DIR);
setupIOPin(&PORT__Y_STEP, PIN__Y_STEP, PINDIR__Y_STEP, INITSTATE__Y_STEP);
setupIOPin(&PORT__Y_M0, PIN__Y_M0, PINDIR__Y_M0, INITSTATE__Y_M0);
setupIOPin(&PORT__Y_M1, PIN__Y_M1, PINDIR__Y_M1, INITSTATE__Y_M1);
setupIOPin(&PORT__Y_M2, PIN__Y_M2, PINDIR__Y_M2, INITSTATE__Y_M2);
//Setup Z Axis motor driver
setupIOPin(&PORT__Z_FAULT, PIN__Z_FAULT, PINDIR__Z_FAULT, INITSTATE__Z_FAULT);
setupIOPin(&PORT__Z_DIR, PIN__Z_DIR, PINDIR__Z_DIR, INITSTATE__Z_DIR);
setupIOPin(&PORT__Z_STEP, PIN__Z_STEP, PINDIR__Z_STEP, INITSTATE__Z_STEP);
setupIOPin(&PORT__Z_M0, PIN__Z_M0, PINDIR__Z_M0, INITSTATE__Z_M0);
setupIOPin(&PORT__Z_M1, PIN__Z_M1, PINDIR__Z_M1, INITSTATE__Z_M1);
setupIOPin(&PORT__Z_M2, PIN__Z_M2, PINDIR__Z_M2, INITSTATE__Z_M2);
//Setup A Axis motor driver
setupIOPin(&PORT__A_FAULT, PIN__A_FAULT, PINDIR__A_FAULT, INITSTATE__A_FAULT);
setupIOPin(&PORT__A_DIR, PIN__A_DIR, PINDIR__A_DIR, INITSTATE__A_DIR);
setupIOPin(&PORT__A_STEP, PIN__A_STEP, PINDIR__A_STEP, INITSTATE__A_STEP);
setupIOPin(&PORT__A_M0, PIN__A_M0, PINDIR__A_M0, INITSTATE__A_M0);
setupIOPin(&PORT__A_M1, PIN__A_M1, PINDIR__A_M1, INITSTATE__A_M1);
setupIOPin(&PORT__A_M2, PIN__A_M2, PINDIR__A_M2, INITSTATE__A_M2);
//Setup up limits
setupIOPin(&PORT__X_LIM_LEFT, PIN__X_LIM_LEFT, PINDIR__X_LIM_LEFT, INITSTATE__X_LIM_LEFT);
setupIOPin(&PORT__X_LIM_RIGHT, PIN__X_LIM_RIGHT, PINDIR__X_LIM_RIGHT, INITSTATE__X_LIM_RIGHT);
setupIOPin(&PORT__Y_LIM_FORW, PIN__Y_LIM_FORW, PINDIR__Y_LIM_FORW, INITSTATE__Y_LIM_FORW);
setupIOPin(&PORT__Y_LIM_BACK, PIN__Y_LIM_BACK, PINDIR__Y_LIM_BACK, INITSTATE__Y_LIM_BACK);
setupIOPin(&PORT__Z_LIM_DOWN, PIN__Z_LIM_DOWN, PINDIR__Z_LIM_DOWN, INITSTATE__Z_LIM_DOWN);
setupIOPin(&PORT__A_LIM_1, PIN__A_LIM_1, PINDIR__A_LIM_1, INITSTATE__A_LIM_1);
setupIOPin(&PORT__A_LIM_2, PIN__A_LIM_2, PINDIR__A_LIM_2, INITSTATE__A_LIM_2);
//Setup control panel buttons
setupIOPin(&PORT__SYS_CHNG_STATE, PIN__SYS_CHNG_STATE, PINDIR__SYS_CHNG_STATE, INITSTATE__SYS_CHNG_STATE);
setupIOPin(&PORT__SYS_START, PIN__SYS_START, PINDIR__SYS_START, INITSTATE__SYS_START);
setupIOPin(&PORT__SYS_STOP, PIN__SYS_STOP, PINDIR__SYS_STOP, INITSTATE__SYS_STOP);
setupIOPin(&PORT__SYS_HOME, PIN__SYS_HOME, PINDIR__SYS_HOME, INITSTATE__SYS_HOME);
setupIOPin(&PORT__SYS_CAL, PIN__SYS_CAL, PINDIR__SYS_CAL, INITSTATE__SYS_CAL);
//Setup ESTOP
setupIOPin(&PORT__ESTOP, PIN__ESTOP, PINDIR__ESTOP, INITSTATE__ESTOP);
//Setup pin for light board control
setupIOPin(&PORT__LIGHT_CTRL, PIN__LIGHT_CTRL, PINDIR__LIGHT_CTRL, INITSTATE__LIGHT_CTRL);
//Setup pins for uart communication
setupIOPin(&PORT__UART_RX, PIN__UART_RX, PINDIR__UART_RX, INITSTATE__UART_RX);
setupIOPin(&PORT__UART_TX, PIN__UART_TX, PINDIR__UART_TX, INITSTATE__UART_TX);
//Setup status led board
setupIOPin(&PORT__RDY_LED, PIN__RDY_LED, PINDIR__RDY_LED, INITSTATE__RDY_LED);
setupIOPin(&PORT__RUN_LED, PIN__RUN_LED, PINDIR__RUN_LED, INITSTATE__RUN_LED);
setupIOPin(&PORT__ERR_LED, PIN__ERR_LED, PINDIR__ERR_LED, INITSTATE__ERR_LED);
//Show initialization led sequence to show end of initialization
}
void setupXMEGAClock()
{
int temp = 0; //Temporary variable for helping avoid 4 clock cycle limitation when updating secure registers
//Enable external 8MHz oscillator
OSC.XOSCCTRL = (OSC_FRQRANGE_2TO9_gc | OSC_XOSCSEL_XTAL_16KCLK_gc); //Set external oscillator to be between 2 and 9 MHz and select it
OSC.CTRL |= OSC_XOSCEN_bm; //Enable the external oscillator
while(!(OSC.STATUS & OSC_XOSCRDY_bm)){ERR_LED_SET();}; //While the external oscillator is not ready, set the error led
ERR_LED_CLR(); //Clear the error led if the external oscillator has stabilized
//Enable phase locked loop to multiply external oscillator by 4 to get 32MHz
temp = ((OSC_PLLSRC_XOSC_gc & OSC_PLLSRC_gm) | (OSC_PLLFAC_gm & 4)); //Set the external oscillator as the clock source for the pll and set to multiply by 4
CCP = CCP_IOREG_gc; //Disable register security so we can update the pll control settings
OSC.PLLCTRL = temp; //Write pll control settings to register
OSC.CTRL |= OSC_PLLEN_bm; //Enable the pll
while(!(OSC.STATUS & OSC_PLLRDY_bm)){ERR_LED_SET();}; //While the pll is not ready, set the error led
ERR_LED_CLR(); //Disable the error led if successfully stabilized
//Set system pll clock divisions and set up as source for all system clocks
temp = ((CLK_PSADIV_gm & CLK_PSADIV_1_gc) | (CLK_PSBCDIV_gm & CLK_PSBCDIV_1_1_gc)); //Set system to use pll divided by 1 (no division)
CCP = CCP_IOREG_gc; //Disable register security so we can update the clock source division setting
CLK.CTRL = temp; //Write division settings to register
temp = CLK_SCLKSEL_PLL_gc; //Set pll as system clock source
CCP = CCP_IOREG_gc; //Disable register security so we can update the system clock
CLK.CTRL = temp; //Write clock source settings to register
}
void setupXMEGATimers()
{
setupRTC();
setupStepDriveTimer();
}
void setupXMEGAUART()
{
USART_InterruptDriver_Initialize(&usartData, &USARTF0, USART_DREINTLVL_LO_gc); //Initialize USARTC0 as interrupt driven serial and clear it's buffers
USART_Format_Set(usartData.usart, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false); //Set the data format of 8 bits, no parity, 1 stop bit
USART_RxdInterruptLevel_Set(usartData.usart, USART_RXCINTLVL_LO_gc); //Enable the receive interrupt
USART_Baudrate_Set(&USARTF0, 207 , 0); //Set baudrate to 9600 with 32Mhz system clock
USART_Rx_Enable(usartData.usart); //Enable receiving over serial
USART_Tx_Enable(usartData.usart); //Enable transmitting over serial
//PMIC.CTRL |= PMIC_LOLVLEX_bm; //Enable serial interrupts
}
void setupStepperPararms()
{
XAxis.dirPort = &PORT__X_DIR;
XAxis.dirPin = PIN__X_DIR;
XAxis.stepPort = &PORT__X_STEP;
XAxis.stepPin = PIN__X_STEP;
XAxis.directionReversed = TRUE;
XAxis.inManualMode = FALSE;
XAxis.stepsPerMM = 250;
XAxis.mmFromZero = 0;
XAxis.acceptableError = .005;
XAxis.steps = 0;
XAxis.shouldMove = FALSE;
YAxis.dirPort = &PORT__Y_DIR;
YAxis.dirPin = PIN__Y_DIR;
YAxis.stepPort = &PORT__Y_STEP;
YAxis.stepPin = PIN__Y_STEP;
YAxis.directionReversed = FALSE;
YAxis.inManualMode = FALSE;
YAxis.stepsPerMM = 250;
YAxis.mmFromZero = 0;
YAxis.acceptableError = .005;
YAxis.steps = 0;
YAxis.shouldMove = FALSE;
ZAxis.dirPort = &PORT__Z_DIR;
ZAxis.dirPin = PIN__Z_DIR;
ZAxis.stepPort = &PORT__Z_STEP;
ZAxis.stepPin = PIN__Z_STEP;
ZAxis.directionReversed = FALSE;
ZAxis.inManualMode = FALSE;
ZAxis.stepsPerMM = 323;
ZAxis.mmFromZero = 8.25;
ZAxis.acceptableError = .004;
ZAxis.steps = 0;
ZAxis.shouldMove = FALSE;
AAxis.dirPort = &PORT__A_DIR;
AAxis.dirPin = PIN__A_DIR;
AAxis.stepPort = &PORT__A_STEP;
AAxis.stepPin = PIN__A_STEP;
AAxis.directionReversed = TRUE;
AAxis.inManualMode = FALSE;
AAxis.stepsPerMM = 250;
AAxis.mmFromZero = 0;
AAxis.acceptableError = .005;
AAxis.steps = 0;
AAxis.shouldMove = FALSE;
}
void setupPinChangeInterrupts(){
PORT__ESTOP.PIN0CTRL |= PORT_OPC_PULLUP_gc | PORT_ISC_FALLING_gc;
PORT__ESTOP.INT0MASK |= PIN__ESTOP;
PORT__ESTOP.INTCTRL |= PORT_INT0LVL_LO_gc;
PORT__SYS_HOME.PIN2CTRL |= PORT_OPC_PULLUP_gc | PORT_ISC_FALLING_gc;
PORT__SYS_HOME.INT0MASK |= PIN__SYS_HOME;
PORT__SYS_HOME.INTCTRL |= PORT_INT0LVL_LO_gc;
PORT__SYS_CAL.PIN3CTRL |= PORT_OPC_PULLUP_gc | PORT_ISC_FALLING_gc;
PORT__SYS_CAL.INT0MASK |= PIN__SYS_CAL;
PORT__SYS_CAL.INTCTRL |= PORT_INT0LVL_LO_gc;
PORT__SYS_START.PIN0CTRL |= PORT_OPC_PULLUP_gc | PORT_ISC_FALLING_gc;
PORT__SYS_START.INT0MASK |= PIN__SYS_START;
PORT__SYS_START.INTCTRL |= PORT_INT0LVL_LO_gc;
}
void setupSystemParams(){
btnState.estopPressed = FALSE;
btnState.startPressed = FALSE;
btnState.stopPressed = FALSE;
btnState.homePressed = FALSE;
btnState.calibratePressed = FALSE;
}
void testStatusLeds()
{
for(int i = 0 ; i < 3 ; i++){
RDY_LED_SET();
ERR_LED_CLR();
_delay_ms(200);
RUN_LED_SET();
RDY_LED_CLR();
_delay_ms(200);
RUN_LED_CLR();
ERR_LED_SET();
_delay_ms(200);
}
for(int i = 0 ; i < 3 ; i++){
RDY_LED_SET();
RUN_LED_SET();
ERR_LED_SET();
_delay_ms(200);
RUN_LED_CLR();
RDY_LED_CLR();
ERR_LED_CLR();
_delay_ms(200);
}
RDY_LED_CLR();
RUN_LED_CLR();
ERR_LED_CLR();
}
void testLightBoard()
{
LIGHT_CTRL_SET();
_delay_ms(1250);
LIGHT_CTRL_CLR();
}
void testSteppers()
{
}
void testUART()
{
}
void setupIOPin(PORT_t *port, int pinbm, char direction, char defaultstate)
{
if(direction == ISINPUT){
port->DIRCLR = pinbm;
}else if(direction == ISOUTPUT){
port->DIRSET = pinbm;
}
if(defaultstate == LOWSTATE){
port->OUTCLR = pinbm;
}else if(defaultstate == HIGHSTATE){
port->OUTSET = pinbm;
}
}
void setupRTC()
{
OSC.CTRL |= OSC_RC32KEN_bm; //Enable 32.768KHz oscillator
while(!(OSC.STATUS & OSC_RC32KRDY_bm)){ERR_LED_SET();} ; //Wait for oscillator to stabilize, light error led while not
ERR_LED_CLR(); //Now stabilized, turn off the error led
CLK.RTCCTRL = (CLK_RTCSRC_RCOSC_gc | CLK_RTCEN_bm); //Set RTC clock source to be the internal oscillator and enable
while(RTC.STATUS & RTC_SYNCBUSY_bm){ERR_LED_SET();}; //Wait for RTC to no longer be busy, set error led while it is
ERR_LED_CLR();
RTC.PER = 10; //
RTC.CNT = 0; //Zero the count register
RTC.COMP = 0; //Set compare value to zero
RTC.CTRL = RTC_PRESCALER_DIV1_gc; //Set prescaler to clk / 1
RTC.INTCTRL = (RTC_OVFINTLVL_LO_gc | RTC_COMPINTLVL_OFF_gc);
}
void setupStepDriveTimer()
{
//For X Axis
TCC0.CTRLA = TC_CLKSEL_DIV1_gc; //125000 counts per second with 32Mhz Processor
TCC0.CTRLB = TC_WGMODE_NORMAL_gc;
TCC0.PER = 9216;
TCC0.INTCTRLA = TC_OVFINTLVL_LO_gc;
//For Y Axis
TCD0.CTRLA = TC_CLKSEL_DIV1_gc; //31250 counts per second with 32Mhz Processor
TCD0.CTRLB = TC_WGMODE_NORMAL_gc;
TCD0.PER = 9216;
TCD0.INTCTRLA = TC_OVFINTLVL_LO_gc;
//For Z Axis
TCE0.CTRLA = TC_CLKSEL_DIV1_gc; //31250 counts per second with 32Mhz Processor
TCE0.CTRLB = TC_WGMODE_NORMAL_gc;
TCE0.PER = 9216;
TCE0.INTCTRLA = TC_OVFINTLVL_LO_gc;
//For A Axis
TCF0.CTRLA = TC_CLKSEL_DIV1_gc; //31250 counts per second with 32Mhz Processor
TCF0.CTRLB = TC_WGMODE_NORMAL_gc;
TCF0.PER = 9216;
TCF0.INTCTRLA = TC_OVFINTLVL_LO_gc;
}

View File

@@ -0,0 +1,44 @@
/*
* InitFunctions.h
*
* Created: 8/9/2014 4:24:44 PM
* Author: corwin
*/
#ifndef INITFUNCTIONS_H_
#define INITFUNCTIONS_H_
#define F_CPU 32000000UL
#include <avr/io.h>
#include <util/delay.h>
#include "avr_compiler.h"
#include "DefinesAndMacros.h"
#include "usart_driver.h"
#include "Steppers.h"
#include "SystemInputFunctions.h"
void setupDriverBoardComplete();
void testDriverBoardComplete();
void setupXMEGAIO();
void setupXMEGAClock();
void setupXMEGAUART();
void setupXMEGATimers();
void setupStepperPararms();
void setupPinChangeInterrupts();
void setupSystemParams();
void testStatusLeds();
void testLightBoard();
void testSteppers();
void testUART();
void setupIOPin(PORT_t *port, int pinbm, char direction, char defaultstate);
void setupRTC();
void setupStepDriveTimer();
#endif /* INITFUNCTIONS_H_ */

View File

@@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Atmel Studio Solution File, Format Version 11.00
Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "PickAndPlaceDriverBoardRev2.0", "PickAndPlaceDriverBoardRev2.0.cproj", "{E3FF968B-6C08-4B3E-995E-ED8AF6D18F09}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AVR = Debug|AVR
Release|AVR = Release|AVR
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E3FF968B-6C08-4B3E-995E-ED8AF6D18F09}.Debug|AVR.ActiveCfg = Debug|AVR
{E3FF968B-6C08-4B3E-995E-ED8AF6D18F09}.Debug|AVR.Build.0 = Debug|AVR
{E3FF968B-6C08-4B3E-995E-ED8AF6D18F09}.Release|AVR.ActiveCfg = Release|AVR
{E3FF968B-6C08-4B3E-995E-ED8AF6D18F09}.Release|AVR.Build.0 = Release|AVR
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,206 @@
/*
* PickAndPlaceDriverBoardRev2.c
*
* Created: 8/6/2014 5:56:07 PM
* Author: corwin
*/
#define F_CPU 32000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include "DefinesAndMacros.h"
#include "usart_driver.h"
#include "InitFunctions.h"
#include "TimerCounterFunctionsAndISR.h"
#include "SystemInputFunctions.h"
#include "Steppers.h"
#include "SystemInputFunctions.h"
#define MANUALCONTROLSTEPSIZE 1
enum SystemStates{
systemInitialization,
connectToHost,
connectedWaitForStart,
disconnectedWaitForStart,
runSequence,
homeAxes,
calibrateAxes,
manualControl
}systemState = systemInitialization, systemStatePrevious = systemInitialization;
bool switchToManualMode(){
PreviousTime = CurrentTime;
while(!SYS_CHNG_STATE_GET()){
if((CurrentTime-PreviousTime) >= 2){
return true;
}
}
return false;
}
void roughManualControl(){
static char manState = 0;
if(manState == 0){
if(!SYS_START_GET()){
XAxis.desiredPosition = (getAxisPosition(&XAxis) - MANUALCONTROLSTEPSIZE);
XAxis.shouldMove = TRUE;
}else if(!SYS_STOP_GET()){
XAxis.desiredPosition = (getAxisPosition(&XAxis) + MANUALCONTROLSTEPSIZE);
XAxis.shouldMove = TRUE;
}
if(!SYS_HOME_GET()){
YAxis.desiredPosition = (getAxisPosition(&YAxis) - MANUALCONTROLSTEPSIZE);
YAxis.shouldMove = TRUE;
}else if(!SYS_CAL_GET()){
YAxis.desiredPosition = (getAxisPosition(&YAxis) + MANUALCONTROLSTEPSIZE);
YAxis.shouldMove = TRUE;
}
}else if(manState == 1){
if(!SYS_HOME_GET()){
ZAxis.desiredPosition = (getAxisPosition(&ZAxis) + MANUALCONTROLSTEPSIZE);
ZAxis.shouldMove = TRUE;
}else if(!SYS_CAL_GET()){
ZAxis.desiredPosition = (getAxisPosition(&ZAxis) - MANUALCONTROLSTEPSIZE);
ZAxis.shouldMove = TRUE;
}
}
_delay_us(500);
if(!SYS_CHNG_STATE_GET()){
manState = !manState;
_delay_ms(500);
}
}
int main(void)
{
while(1){
//////////Initialize System//////////
if(systemState == systemInitialization){
setupDriverBoardComplete();
testDriverBoardComplete();
RDY_LED_SET();
systemState = connectToHost;
//////////End initialize system//////////
//////////Wait for host connection//////////
}else if(systemState == connectToHost){
if(btnState.startPressed == TRUE){
enableSteppers();
char jump = 5;
XAxis.desiredPosition = 10;
YAxis.desiredPosition = 10;
while(1){
//sprintf((char *)sendArray, "Current jump size is %d.\r\n", jump);
// for(int i = 0 ; sendArray[i] != '\0' ; i++){
// while (!USART_IsTXDataRegisterEmpty(&USARTF0));
// USART_TXBuffer_PutByte(&usartData ,sendArray[i]);
// }
YAxis.desiredPosition += jump;
YAxis.shouldMove = TRUE;
while(XAxis.shouldMove || YAxis.shouldMove);
XAxis.desiredPosition += jump;
XAxis.shouldMove = TRUE;
while(XAxis.shouldMove || YAxis.shouldMove);
YAxis.desiredPosition = 10;
YAxis.shouldMove = TRUE;
while(XAxis.shouldMove || YAxis.shouldMove);
XAxis.desiredPosition = 10;
XAxis.shouldMove = TRUE;
while(XAxis.shouldMove || YAxis.shouldMove);
jump += 5;
}
disableSteppers();
}else if(btnState.homePressed){
systemState = homeAxes;
systemStatePrevious = connectToHost;
}else if(btnState.calibratePressed == TRUE){
systemState = calibrateAxes;
systemStatePrevious = connectToHost;
}else if(switchToManualMode() == true){
systemState = manualControl;
systemStatePrevious = connectToHost;
enableSteppers();
XAxis.inManualMode = TRUE;
YAxis.inManualMode = TRUE;
ZAxis.inManualMode = TRUE;
AAxis.inManualMode = TRUE;
_delay_ms(1500);
}
//////////End wait for host connection//////////
//////////Connected to Host and wait for start//////////
}else if(systemState == connectedWaitForStart){
//////////End connected to host and wait for start//////////
}else if(systemState == disconnectedWaitForStart){
//////////End connect to host and wait for start//////////
//////////Start pick and place run sequence//////////
}else if(systemState == runSequence){
//////////End start pick and place run sequence//////////
//////////Home system axes to zero position//////////
}else if(systemState == homeAxes){
enableSteppers();
homeAllSteppers();
disableSteppers();
btnState.homePressed = FALSE;
systemState = systemStatePrevious;
systemStatePrevious = homeAxes;
//////////End home system axes//////////
/////////Calibrate system stepper axes//////////
}else if(systemState == calibrateAxes){
ERR_LED_CLR();
enableSteppers();
calibrateAllSteppers();
btnState.calibratePressed = FALSE;
if(systemStatePrevious == systemInitialization){
systemState = connectToHost;
}else{
systemState = systemStatePrevious;
}
systemStatePrevious = calibrateAxes;
//////////End calibrate system stepper axes//////////
//////////Manual control of system axes//////////
}else if(systemState == manualControl){
roughManualControl();
if(switchToManualMode() == true){
XAxis.inManualMode = FALSE;
YAxis.inManualMode = FALSE;
ZAxis.inManualMode = FALSE;
AAxis.inManualMode = FALSE;
btnState.homePressed = FALSE;
btnState.startPressed = FALSE;
btnState.stopPressed = FALSE;
btnState.calibratePressed = FALSE;
disableSteppers();
systemState = systemStatePrevious;
systemStatePrevious = manualControl;
}
}
//////////End manual control of system axes//////////
}
}

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<ProjectVersion>6.2</ProjectVersion>
<ToolchainName>com.Atmel.AVRGCC8.C</ToolchainName>
<ProjectGuid>{e3ff968b-6c08-4b3e-995e-ed8af6d18f09}</ProjectGuid>
<avrdevice>ATxmega256A3U</avrdevice>
<avrdeviceseries>none</avrdeviceseries>
<OutputType>Executable</OutputType>
<Language>C</Language>
<OutputFileName>$(MSBuildProjectName)</OutputFileName>
<OutputFileExtension>.elf</OutputFileExtension>
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
<AssemblyName>PickAndPlaceDriverBoardRev2.0</AssemblyName>
<Name>PickAndPlaceDriverBoardRev2.0</Name>
<RootNamespace>PickAndPlaceDriverBoardRev2.0</RootNamespace>
<ToolchainFlavour>Native</ToolchainFlavour>
<KeepTimersRunning>true</KeepTimersRunning>
<OverrideVtor>false</OverrideVtor>
<CacheFlash>true</CacheFlash>
<ProgFlashFromRam>true</ProgFlashFromRam>
<RamSnippetAddress>0x20000000</RamSnippetAddress>
<UncachedRange />
<OverrideVtorValue>exception_table</OverrideVtorValue>
<BootSegment>2</BootSegment>
<eraseonlaunchrule>0</eraseonlaunchrule>
<AsfFrameworkConfig>
<framework-data xmlns="">
<options />
<configurations />
<files />
<documentation help="" />
<offline-documentation help="" />
<dependencies>
<content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.18.1" />
</dependencies>
</framework-data>
</AsfFrameworkConfig>
<avrtool>com.atmel.avrdbg.tool.avrdragon</avrtool>
<com_atmel_avrdbg_tool_avrdragon>
<ToolOptions>
<InterfaceProperties>
<JtagEnableExtResetOnStartSession>false</JtagEnableExtResetOnStartSession>
</InterfaceProperties>
<InterfaceName>JTAG</InterfaceName>
</ToolOptions>
<ToolType>com.atmel.avrdbg.tool.avrdragon</ToolType>
<ToolNumber>00A200050749</ToolNumber>
<ToolName>AVR Dragon</ToolName>
</com_atmel_avrdbg_tool_avrdragon>
<avrtoolinterface>JTAG</avrtoolinterface>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings>
<AvrGcc>
<avrgcc.common.optimization.RelaxBranches>True</avrgcc.common.optimization.RelaxBranches>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>NDEBUG</Value>
</ListValues>
</avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</avrgcc.linker.libraries.Libraries>
</AvrGcc>
</ToolchainSettings>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<ToolchainSettings>
<AvrGcc>
<avrgcc.common.optimization.RelaxBranches>True</avrgcc.common.optimization.RelaxBranches>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>DEBUG</Value>
</ListValues>
</avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</avrgcc.linker.libraries.Libraries>
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
</AvrGcc>
</ToolchainSettings>
</PropertyGroup>
<ItemGroup>
<Compile Include="avr_compiler.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="DefinesAndMacros.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="InitFunctions.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="InitFunctions.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="PickAndPlaceDriverBoardRev2.0.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="Steppers.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="Steppers.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="SystemInputFunctions.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="SystemInputFunctions.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="TC_driver.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="TC_driver.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="TimerCounterFunctionsAndISR.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="usart_driver.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="usart_driver.h">
<SubType>compile</SubType>
</Compile>
</ItemGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
</Project>

View File

@@ -0,0 +1,109 @@
/*
* Steppers.c
*
* Created: 8/9/2014 1:10:47 PM
* Author: corwin
*/
#include "Steppers.h"
void enableSteppers()
{
STEP_EN_CLR();
steppersEnabled = TRUE;
_delay_ms(100);
}
void disableSteppers()
{
STEP_EN_SET();
steppersEnabled = FALSE;
_delay_ms(100);
}
void calibrateAllSteppers()
{
ZAxis.desiredPosition = 40; //Set position for the pipette to be up initially so it doesn't get broken on anything
ZAxis.shouldMove = TRUE; //Allow axis to move
while(ZAxis.shouldMove); //Wait for the pipette to come up before continuing
homeYStepper(); //Home the y axis against the limit switch
homeXStepper(); //Home the x axis against the limit switch
_delay_ms(100);
XAxis.desiredPosition = 47.5; //Set x position to z calibration point
YAxis.desiredPosition = 36.5; //Move y position to z calibration point
XAxis.shouldMove = TRUE; //Allow axis to move
YAxis.shouldMove = TRUE; //Allow axis to move
while(YAxis.shouldMove || XAxis.shouldMove); //Don't continue until calibration point has been reached
homeZStepper(); //Home the z axis against the limit switch
setStepsOffset(&ZAxis); //Re-align z steps to account for switch offset
}
void homeAllSteppers()
{
ZAxis.desiredPosition = 40; //Set position for the pipette to be up initially so it doesn't get broken on anything
ZAxis.shouldMove = TRUE; //Allow axis to move
while(ZAxis.shouldMove); //Wait for the pipette to come up before continuing
homeYStepper(); //Home the y axis against the limit switch
homeXStepper(); //Home the x axis against the limit switch
}
void homeXStepper()
{
X_DIR_CLR();
while(X_LIM_LEFT_GET()){
X_STEP_SET();
_delay_us(2);
X_STEP_CLR();
_delay_us(400);
}
XAxis.steps = 0;
}
void homeYStepper()
{
Y_DIR_SET();
while(Y_LIM_FORW_GET()){
Y_STEP_SET();
_delay_us(2);
Y_STEP_CLR();
_delay_us(400);
}
YAxis.steps = 0;
}
void homeZStepper()
{
Z_DIR_SET();
while(Z_LIM_DOWN_GET()){
Z_STEP_SET();
_delay_us(2);
Z_STEP_CLR();
_delay_us(400);
}
ZAxis.steps = 0;
ZAxis.desiredPosition = 30;
ZAxis.shouldMove = TRUE;
while(ZAxis.shouldMove);
}
void homeAStepper()
{
}
double getAxisPosition(Axes_t *axis)
{
return (axis->steps/axis->stepsPerMM);
}
void setStepsOffset(Axes_t *axis)
{
axis->steps = (axis->steps + (axis->mmFromZero * axis->stepsPerMM));
}

View File

@@ -0,0 +1,74 @@
/*
* Steppers.h
*
* Created: 8/9/2014 1:10:58 PM
* Author: corwin
*/
#ifndef STEPPERS_H_
#define STEPPERS_H_
#define F_CPU 32000000UL
#include <avr/io.h>
#include <util/delay.h>
#include "DefinesAndMacros.h"
#define XLEFT 0
#define XRIGHT 1
#define YFORWARDS 1
#define YBACKWARDS 0
#define ZUP 0
#define ZDOWN 1
#define XSTEPPERMM 250
#define YSTEPERMM 250
#define ZSTEPPERMM 323
#define ASTEPPERMM 250 //Needs to be found
typedef struct Axes{
PORT_t *dirPort;
int dirPin;
PORT_t *stepPort;
int stepPin;
char directionReversed;
char inManualMode;
int stepsPerMM;
double mmFromZero;
double acceptableError;
volatile long long steps;
volatile double desiredPosition;
volatile char shouldMove;
}Axes_t;
Axes_t XAxis;
Axes_t YAxis;
Axes_t ZAxis;
Axes_t AAxis;
char steppersEnabled;
void enableSteppers();
void disableSteppers();
void calibrateAllSteppers();
void homeAllSteppers();
void homeXStepper();
void homeYStepper();
void homeZStepper();
void homeAStepper();
double getAxisPosition(Axes_t *axis);
void setStepsOffset(Axes_t *axis);
#endif /* STEPPERS_H_ */

View File

@@ -0,0 +1,8 @@
/*
* SystemInputFunctions.c
*
* Created: 8/12/2014 3:31:50 PM
* Author: corwin
*/
#include "SystemInputFunctions.h"

View File

@@ -0,0 +1,23 @@
/*
* SystemInputFunctions.h
*
* Created: 8/12/2014 3:32:03 PM
* Author: corwin
*/
#ifndef SYSTEMINPUTFUNCTIONS_H_
#define SYSTEMINPUTFUNCTIONS_H_
typedef struct ButtonStates{
volatile char estopPressed;
volatile char startPressed;
volatile char stopPressed;
volatile char homePressed;
volatile char calibratePressed;
}ButtonStates_t;
ButtonStates_t btnState;
#endif /* SYSTEMINPUTFUNCTIONS_H_ */

View File

@@ -0,0 +1,433 @@
/* This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief XMEGA Timer/Counter driver source file.
*
* This file contains the function implementations the XMEGA Timer/Counter
* driver.
*
* The driver is not intended for size and/or speed critical code, since
* most functions are just a few lines of code, and the function call
* overhead would decrease code performance. The driver is intended for
* rapid prototyping and documentation purposes for getting started with
* the XMEGA Timer/Counter module.
*
* For size and/or speed critical code, it is recommended to copy the
* function contents directly into your application instead of making
* a function call.
*
* Several functions use the following construct:
* "some_register = ... | (some_parameter ? SOME_BIT_bm : 0) | ..."
* Although the use of the ternary operator ( if ? then : else ) is discouraged,
* in some occasions the operator makes it possible to write pretty clean and
* neat code. In this driver, the construct is used to set or not set a
* configuration bit based on a boolean input parameter, such as
* the "some_parameter" in the example above.
*
* \par Application note:
* AVR1306: Using the XMEGA Timer/Counter
*
* \par Documentation
* For comprehensive code documentation, supported compilers, compiler
* settings and supported devices see readme.html
*
* \author
* Atmel Corporation: http://www.atmel.com \n
* Support email: avr@atmel.com
*
* $Revision: 1569 $
* $Date: 2008-04-22 13:03:43 +0200 (ti, 22 apr 2008) $ \n
*
* Copyright (c) 2008, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include "avr_compiler.h"
#include "TC_driver.h"
/*! \brief Configures clock source for the Timer/Counter 0.
*
* This function clears the old clock source setting of the Timer/Counter and
* sets a new clock source according to the clockSelection parameter.
*
* \param tc Timer/Counter module instance.
* \param clockSelection Timer/Counter clock source setting.
*/
void TC0_ConfigClockSource( volatile TC0_t * tc, TC_CLKSEL_t clockSelection )
{
tc->CTRLA = ( tc->CTRLA & ~TC0_CLKSEL_gm ) | clockSelection;
}
/*! \brief Configures clock source for the Timer/Counter 1.
*
* This function clears the old clock source setting of the Timer/Counter and
* sets a new clock source according to the clockSelection parameter.
*
* \param tc Timer/Counter module instance.
* \param clockSelection Timer/Counter clock source setting.
*/
void TC1_ConfigClockSource( volatile TC1_t * tc, TC_CLKSEL_t clockSelection )
{
tc->CTRLA = ( tc->CTRLA & ~TC1_CLKSEL_gm ) | clockSelection;
}
/*! \brief Configures the Waveform Generation Mode for the Timer/Counter 0.
*
* This function clears the old WGM setting of the Timer/Counter and sets a
* new WGM setting according to the wgm parameter.
*
* \param tc Timer/Counter module instance.
* \param wgm Waveform generation mode.
*/
void TC0_ConfigWGM( volatile TC0_t * tc, TC_WGMODE_t wgm )
{
tc->CTRLB = ( tc->CTRLB & ~TC0_WGMODE_gm ) | wgm;
}
/*! \brief Configures the Waveform Generation Mode for the Timer/Counter 1.
*
* This function clears the old WGM setting of the Timer/Counter and sets a
* new WGM setting according to the wgm parameter.
*
* \param tc Timer/Counter module instance.
* \param wgm Waveform generation mode.
*/
void TC1_ConfigWGM( volatile TC1_t * tc, TC_WGMODE_t wgm )
{
tc->CTRLB = ( tc->CTRLB & ~TC1_WGMODE_gm ) | wgm;
}
/*! \brief Configures the Timer/Counter 0 for input capture operation.
*
* This function sets the Timer/Counter in input capture mode and selects
* the event lines that will trigger the individual input capture channels.
*
* \note Output compare operation is disabled when input capture operation is
* enabled.
*
* \param tc Timer/Counter module instance.
* \param eventSource Event source selection.
*/
void TC0_ConfigInputCapture( volatile TC0_t * tc, TC_EVSEL_t eventSource )
{
tc->CTRLD = ( tc->CTRLD & ~( TC0_EVSEL_gm | TC0_EVACT_gm ) ) |
eventSource |
TC_EVACT_CAPT_gc;
}
/*! \brief Configures the Timer/Counter 1 for input capture operation.
*
* This function sets the Timer/Counter in input capture mode and selects
* the event lines that will trigger the individual input capture channels.
*
* \note Output compare operation is disabled when input capture operation is
* enabled.
*
* \param tc Timer/Counter module instance.
* \param eventSource Event source selection.
*/
void TC1_ConfigInputCapture( volatile TC1_t * tc, TC_EVSEL_t eventSource )
{
tc->CTRLD = ( tc->CTRLD & ~( TC1_EVSEL_gm | TC1_EVACT_gm ) ) |
eventSource |
TC_EVACT_CAPT_gc;
}
/*! \brief Enables compare/capture channels for Timer/Counter 0.
*
* This function enables compare/capture channels according to the supplied
* enableMask. The enableMask can be obtained by ORing together the symbols
* - TC0_CCAEN_bm
* - TC0_CCBEN_bm
* - TC0_CCCEN_bm
* - TC0_CCDEN_bm
*
* Example: TC0_EnableCCChannels( &TCC0, TC0_CCAEN_bm | TC0_CCCEN_bm ) will
* enable channels A and C.
*
* \note No capture/compare channels are disabled by calling this function.
* Disabling is done by calling \ref TC0_DisableCCChannels.
*
* \param tc Timer/Counter module instance.
* \param enableMask Mask of channels to enable.
*/
void TC0_EnableCCChannels( volatile TC0_t * tc, uint8_t enableMask )
{
/* Make sure only CCxEN bits are set in enableMask. */
enableMask &= ( TC0_CCAEN_bm | TC0_CCBEN_bm | TC0_CCCEN_bm | TC0_CCDEN_bm );
/* Enable channels. */
tc->CTRLB |= enableMask;
}
/*! \brief Enables compare/capture channels for Timer/Counter 1.
*
* This function enables compare/capture channels according to the supplied
* enableMask. The enableMask can be obtained by ORing together the symbols
* - TC1_CCAEN_bm
* - TC1_CCBEN_bm
*
* Example: TC1_EnableCCChannels( &TCC1, TC1_CCAEN_bm | TC1_CCBEN_bm ) will
* enable channels A and B.
*
* \note No capture/compare channels are disabled by calling this function.
* Disabling is done by calling \ref TC1_DisableCCChannels.
*
* \param tc Timer/Counter module instance.
* \param enableMask Mask of channels to enable.
*/
void TC1_EnableCCChannels( volatile TC1_t * tc, uint8_t enableMask )
{
/* Make sure only CCxEN bits are set in enableMask. */
enableMask &= ( TC1_CCAEN_bm | TC1_CCBEN_bm );
/* Enable channels. */
tc->CTRLB |= enableMask;
}
/*! \brief Disables compare/capture channels on Timer/Counter 0.
*
* This function disables compare/capture channels according to the supplied
* disableMask. The disableMask can be obtained by ORing together the symbols
* - TC0_CCAEN_bm
* - TC0_CCBEN_bm
* - TC0_CCCEN_bm
* - TC0_CCDEN_bm
*
* Example: TC0_DisableCCChannels( &TCC0, TC0_CCAEN_bm | TC0_CCCEN_bm ) will
* disable channels A and C.
*
* \param tc Timer/Counter module instance.
* \param disableMask Mask of channels to disable.
*/
void TC0_DisableCCChannels( volatile TC0_t * tc, uint8_t disableMask )
{
/* Make sure only CCxEN bits are set in disableMask. */
disableMask &= ( TC0_CCAEN_bm | TC0_CCBEN_bm | TC0_CCCEN_bm | TC0_CCDEN_bm );
/* Disable channels. */
tc->CTRLB &= ~disableMask;
}
/*! \brief Disables compare/capture channels on Timer/Counter 1.
*
* This function disables compare/capture channels according to the supplied
* disableMask. The disableMask can be obtained by ORing together the symbols
* - TC1_CCAEN_bm
* - TC1_CCBEN_bm
*
* Example: TC1_DisableCCChannels( &TCC1, TC1_CCAEN_bm | TC1_CCBEN_bm ) will
* disable channels A and B.
*
* \param tc Timer/Counter module instance.
* \param disableMask Mask of channels to disable.
*/
void TC1_DisableCCChannels( volatile TC1_t * tc, uint8_t disableMask )
{
/* Make sure only CCxEN bits are set in disableMask. */
disableMask &= ( TC1_CCAEN_bm | TC1_CCBEN_bm );
/* Disable channels. */
tc->CTRLB &= ~disableMask;
}
/*! \brief Sets the overflow interrupt level.
*
* This function sets the overflow interrupt level of this Timer/Counter 0.
*
* \param tc Timer/Counter module instance.
* \param intLevel New overflow interrupt level.
*/
void TC0_SetOverflowIntLevel( volatile TC0_t * tc, TC_OVFINTLVL_t intLevel )
{
tc->INTCTRLA = ( tc->INTCTRLA & ~TC0_OVFINTLVL_gm ) | intLevel;
}
/*! \brief Sets the overflow interrupt level.
*
* This function sets the overflow interrupt level of this Timer/Counter 1.
*
* \param tc Timer/Counter module instance.
* \param intLevel New overflow interrupt level.
*/
void TC1_SetOverflowIntLevel( volatile TC1_t * tc, TC_OVFINTLVL_t intLevel )
{
tc->INTCTRLA = ( tc->INTCTRLA & ~TC1_OVFINTLVL_gm ) | intLevel;
}
/*! \brief Sets the Error interrupt level.
*
* This function sets the overflow interrupt level of this Timer/Counter 0.
*
* \param tc Timer/Counter module instance.
* \param intLevel New error interrupt level.
*/
void TC0_SetErrorIntLevel( volatile TC0_t * tc, TC_ERRINTLVL_t intLevel )
{
tc->INTCTRLA = ( tc->INTCTRLA & ~TC0_ERRINTLVL_gm ) | intLevel;
}
/*! \brief Sets the Error interrupt level.
*
* This function sets the overflow interrupt level of this Timer/Counter 1.
*
* \param tc Timer/Counter module instance.
* \param intLevel New error interrupt level.
*/
void TC1_SetErrorIntLevel( volatile TC1_t * tc, TC_ERRINTLVL_t intLevel )
{
tc->INTCTRLA = ( tc->INTCTRLA & ~TC1_ERRINTLVL_gm ) | intLevel;
}
/*! \brief Sets the interrupt level for compare/capture channel A interrupt.
*
* This function sets the interrupt level for compare/capture channel A
* interrupt in Timer/Counter 0.
*
* \param tc Timer/Counter module instance.
* \param intLevel New compare/capture channel A interrupt level.
*/
void TC0_SetCCAIntLevel( volatile TC0_t * tc, TC_CCAINTLVL_t intLevel )
{
tc->INTCTRLB = ( tc->INTCTRLB & ~TC0_CCAINTLVL_gm ) | intLevel;
}
/*! \brief Sets the interrupt level for compare/capture channel A interrupt.
*
* This function sets the interrupt level for compare/capture channel A
* interrupt in Timer/Counter 1.
*
* \param tc Timer/Counter module instance.
* \param intLevel New compare/capture channel A interrupt level.
*/
void TC1_SetCCAIntLevel( volatile TC1_t * tc, TC_CCAINTLVL_t intLevel )
{
tc->INTCTRLB = ( tc->INTCTRLB & ~TC1_CCAINTLVL_gm ) | intLevel;
}
/*! \brief Sets the interrupt level for compare/capture channel B interrupt.
*
* This function sets the interrupt level for compare/capture channel B
* interrupt in Timer/Counter 0.
*
* \param tc Timer/Counter module instance.
* \param intLevel New compare/capture channel B interrupt level.
*/
void TC0_SetCCBIntLevel( volatile TC0_t * tc, TC_CCBINTLVL_t intLevel )
{
tc->INTCTRLB = ( tc->INTCTRLB & ~TC0_CCBINTLVL_gm ) | intLevel;
}
/*! \brief Sets the interrupt level for compare/capture channel B interrupt.
*
* This function sets the interrupt level for compare/capture channel B
* interrupt in Timer/Counter 1.
*
* \param tc Timer/Counter module instance.
* \param intLevel New compare/capture channel B interrupt level.
*/
void TC1_SetCCBIntLevel( volatile TC1_t * tc, TC_CCBINTLVL_t intLevel )
{
tc->INTCTRLB = ( tc->INTCTRLB & ~TC1_CCBINTLVL_gm ) | intLevel;
}
/*! \brief Sets the interrupt level for compare/capture channel C interrupt.
*
* This function sets the interrupt level for compare/capture channel C
* interrupt in Timer/Counter 0.
*
* \param tc Timer/Counter module instance.
* \param intLevel New compare/capture channel A interrupt level.
*/
void TC0_SetCCCIntLevel( volatile TC0_t * tc, TC_CCCINTLVL_t intLevel )
{
tc->INTCTRLB = ( tc->INTCTRLB & ~TC0_CCCINTLVL_gm ) | intLevel;
}
/*! \brief Sets the interrupt level for compare/capture channel D interrupt.
*
* This function sets the interrupt level for compare/capture channel D
* interrupt in Timer/Counter 0.
*
* \param tc Timer/Counter module instance.
* \param intLevel New compare/capture channel A interrupt level.
*/
void TC0_SetCCDIntLevel( volatile TC0_t * tc, TC_CCDINTLVL_t intLevel )
{
tc->INTCTRLB = ( tc->INTCTRLB & ~TC0_CCDINTLVL_gm ) | intLevel;
}
/*! \brief Resets the Timer/Counter 0.
*
* This function will reset the Timer/Counter. After calling this function,
* the Timer/Counter will be in the same state as it would after a full
* reset of the device.
*
* \param tc Timer/Counter 0 module instance.
*/
void TC0_Reset( volatile TC0_t * tc )
{
/* TC must be turned off before a Reset command. */
tc->CTRLA = ( tc->CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_OFF_gc;
/* Issue Reset command. */
tc->CTRLFSET = TC_CMD_RESET_gc;
}
/*! \brief Resets the Timer/Counter 1.
*
* This function will reset the Timer/Counter. After calling this function,
* the Timer/Counter will be in the same state as it would after a full
* reset of the device.
*
* \param tc Timer/Counter 1 module instance.
*/
void TC1_Reset( volatile TC1_t * tc )
{
/* TC must be turned off before a Reset command. */
tc->CTRLA = ( tc->CTRLA & ~TC1_CLKSEL_gm ) | TC_CLKSEL_OFF_gc;
/* Issue Reset command. */
tc->CTRLFSET = TC_CMD_RESET_gc;
}

View File

@@ -0,0 +1,423 @@
/* This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief XMEGA Timer/Counter driver header file.
*
* This file contains the function prototypes and enumerator definitions
* for various configuration parameters for the XMEGA Timer/Counter driver.
*
* The driver is not intended for size and/or speed critical code, since
* most functions are just a few lines of code, and the function call
* overhead would decrease code performance. The driver is intended for
* rapid prototyping and documentation purposes for getting started with
* the XMEGA Timer/Counter module.
*
* For size and/or speed critical code, it is recommended to copy the
* function contents directly into your application instead of making
* a function call.
*
* \par Application note:
* AVR1306: Using the XMEGA Timer/Counter
*
* \par Documentation
* For comprehensive code documentation, supported compilers, compiler
* settings and supported devices see readme.html
*
* \author
* Atmel Corporation: http://www.atmel.com \n
* Support email: avr@atmel.com
*
* $Revision: 1569 $
* $Date: 2008-04-22 13:03:43 +0200 (ti, 22 apr 2008) $ \n
*
* Copyright (c) 2008, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef TC_DRIVER_H
#define TC_DRIVER_H
#include "avr_compiler.h"
/* Definition of macros. */
/*! \brief Enables the event delay for this TC.
*
* This macro enables a one clock cycle delay of event sources for this TC.
* Mainly used for the high word TC when two TCs are cascaded to form a 32-bit
* TC.
*
* \param _tc The Timer/Counter to enable delay on.
*/
#define TC_EnableEventDelay( _tc ) ( (_tc)->CTRLD |= TC0_EVDLY_bm )
/*! \brief This macro disables the event delay for this TC.
*
* \param _tc The Timer/Counter to disable delay on.
*/
#define TC_DisableEventDelay( _tc ) ( (_tc)->CTRLD &= ~TC0_EVDLY_bm )
/*! \brief Locks automatic updating of compare and period registers.
*
* This macro will lock automatic updates of compare registers from the
* corresponding buffer registers. To enable automatic updates again, use the
* \ref TC_UnlockCompareUpdate macro.
*
* \param _tc Timer/Counter module instance.
*/
#define TC_LockCompareUpdate( _tc ) ( (_tc)->CTRLFSET = TC0_LUPD_bm )
/*! \brief Unlocks automatic updating of compare and period registers.
*
* This macro will unlock automatic updates of compare registers from the
* corresponding buffer registers. Note that the output compare registers will
* not be updated until an update event occurs, e.g. that the counter hits
* TOP or BOTTOM. To force an update of the compare register from the buffer
* register, use the \ref TC_ForceUpdate macro.
*
* \param _tc Timer/Counter module instance.
*/
#define TC_UnlockCompareUpdate( _tc ) ( (_tc)->CTRLFCLR = TC0_LUPD_bm )
/*! \brief Force an update of the output compare and period registers.
*
* This macro will trigger a transfer from the output compare and period
* buffer registers ( CCxBUF and PERBUF ) to the output compare and period
* registers ( CCx and PER ). Calling this macro has the same effect as an
* update condition.
*
* \param _tc Timer/Counter module instance.
*/
#define TC_ForceUpdate( _tc ) ( (_tc)->CTRLFSET = TC_CMD_UPDATE_gc )
/*! \brief Restart the Timer/Counter.
*
* This macro will restart the timer. The effect of running this command is:
* - The CNT[H:L] register is cleared.
* - The direction (DIR ) is reset. (Next clock cycle will increase the counter )
* - All compare outputs are set to 0.
* - If a DTI module is connected to the timer, it will be reset as well.
*
* \param _tc Timer/Counter module instance.
*/
#define TC_Restart( _tc ) ( (_tc)->CTRLFSET = TC_CMD_RESTART_gc )
/*! \brief Manually set the count.
*
* This macro writes a new value to the CNT[H:L] register.
* Note that the CNT[H:L] register is not double buffered, so it is recommended
* that the timer is not running when this macro is used.
*
* \param _tc Timer/Counter module instance.
* \param _count New count value.
*/
#define TC_SetCount( _tc, _count ) ( (_tc)->CNT = (_count) )
/*! \brief Sets the timer period.
*
* This macro sets a new timer period. The period buffer register is not
* used, so the new period will be valid immediately after the 16-bit write
* is finished.
*
* \param _tc Timer/Counter module instance.
* \param _period New Timer/Counter period.
*/
#define TC_SetPeriod( _tc, _period ) ( (_tc)->PER = (_period) )
/*! \brief Sets the timer period ( double buffered ).
*
* This macro sets a new timer period. The period buffer register is used,
* so the new period will be valid after the next update condition.
*
* \param _tc Timer/Counter 0 or 1 module instance.
* \param _period New Timer/Counter period.
*/
#define TC_SetPeriodBuffered( _tc, _period ) ( (_tc)->PERBUF = (_period) )
/*! \brief Set new compare value for compare channel A. ( Double buffered )
*
* This macro sets a new compare value for compare channel A. The compare
* channel A buffer register is used, so the new period will be valid from the
* next update condition.
*
* \param _tc Timer/Counter 0 or 1 module instance.
* \param _compareValue New compare value for compare channel A.
*/
#define TC_SetCompareA( _tc, _compareValue ) ( (_tc)->CCABUF = (_compareValue) )
/*! \brief Set new compare value for compare channel B. ( Double buffered )
*
* This macro sets a new compare value for compare channel B. The compare
* channel B buffer register is used, so the new period will be valid from the
* next update condition.
*
* \param _tc Timer/Counter 0 or 1 module instance.
* \param _compareValue New compare value for compare channel B.
*/
#define TC_SetCompareB( _tc, _compareValue ) ( (_tc)->CCBBUF = (_compareValue) )
/*! \brief Set new compare value for compare channel C. ( Double buffered )
*
* This macro sets a new compare value for compare channel C. The compare
* channel C buffer register is used, so the new period will be valid from the
* next update condition.
*
* \note The CCC channel is not available on TCx1.
*
* \param _tc Timer/Counter 0 module instance.
* \param _compareValue New compare value for compare channel C.
*/
#define TC_SetCompareC( _tc, _compareValue ) ( (_tc)->CCCBUF = (_compareValue) )
/*! \brief Set new compare value for compare channel D. ( Double buffered )
*
* This macro sets a new compare value for compare channel D. The compare
* channel D buffer register is used, so the new period will be valid from the
* next update condition.
*
* \note The CCD channel is not available on TCx1.
*
* \param _tc Timer/Counter 0 module instance.
* \param _compareValue New compare value for compare channel D.
*/
#define TC_SetCompareD( _tc, _compareValue ) ( (_tc)->CCDBUF = (_compareValue) )
/*! \brief Test whether an overflow has occurred.
*
* The return value of this macro indicates if an overflow has occurred.
*
* \param _tc Timer/Counter module instance.
*
* \return Non-zero if overflow flag is set, zero otherwise.
*/
#define TC_GetOverflowFlag( _tc ) ( (_tc)->INTFLAGS & TC0_OVFIF_bm )
/*! \brief Clears the Timer/Counter overflow flag.
*
* This macro clears the Timer/Counter overflow flag.
*
* \param _tc Timer/Counter module instance.
*/
#define TC_ClearOverflowFlag( _tc ) ( (_tc)->INTFLAGS = TC0_OVFIF_bm )
/*! \brief Test whether an error has occurred.
*
* The return value of this macro indicates if an error has occurred.
*
* \param _tc Timer/Counter module instance.
*
* \return Non-zero if the Timer error flag is set.
*/
#define TC_GetErrorFlag( _tc ) ( (_tc)->INTFLAGS & TC0_ERRIF_bm )
/*! \brief Clears the Timer/Counter error flag.
*
* This macro clears the Timer/Counter error flag.
*
* \param _tc Timer/Counter module instance.
*/
#define TC_ClearErrorFlag( _tc ) ( (_tc)->INTFLAGS = TC0_ERRIF_bm )
/*! \brief Get the status for Compare or Capture channel A.
*
* When the TC is in Input Capture mode, the return value of this macro
* indicates whether there is an unread input capture value available for
* capture channel A.
*
* When the TC is in any other mode, the return value of this macro
* indicates whether there has been a compare match between channel A and the
* counter.
*
* \param _tc Timer/Counter 0 or 1 module instance.
*
* \return Non-zero if Compare or capture has occured, zero otherwise.
*/
#define TC_GetCCAFlag( _tc ) ( (_tc)->INTFLAGS & TC0_CCAIF_bm )
/*! \brief Clears the Timer/Counter compare or capture A interrupt flag.
*
* \param _tc Timer/Counter 0 or 1 module instance.
*/
#define TC_ClearCCAFlag( _tc ) ( (_tc)->INTFLAGS = TC0_CCAIF_bm )
/*! \brief Get the status for Compare or Capture channel B.
*
* When the TC is in Input Capture mode, the return value of this macro
* indicates whether there is an unread input capture value available for
* capture channel B.
*
* When the TC is in any other mode, the return value of this macro
* indicates whether there has been a compare match between channel B and the
* counter.
*
* \param _tc Timer/Counter 0 or 1 module instance.
*
* \return Non-zero if Compare or capture has occured, zero otherwise.
*/
#define TC_GetCCBFlag( _tc ) ( (_tc)->INTFLAGS & TC0_CCBIF_bm )
/*! \brief Clears the Timer/Counter compare or capture B interrupt flag.
*
* \param _tc Timer/Counter 0 or 1 module instance.
*/
#define TC_ClearCCBFlag( _tc ) ( (_tc)->INTFLAGS = TC0_CCBIF_bm )
/*! \brief Get the status for Compare or Capture channel C.
*
* When the TC is in Input Capture mode, the return value of this macro
* indicates whether there is an unread input capture value available for
* capture channel C.
*
* When the TC is in any other mode, the return value of this macro
* indicates whether there has been a compare match between channel C and the
* counter.
*
* \note The CCC channel is not available on TCx1.
*
* \param _tc Timer/Counter 0 module instance.
*
* \return Non-zero if Compare or capture has occured, zero otherwise.
*/
#define TC_GetCCCFlag( _tc ) ( (_tc)->INTFLAGS & TC0_CCCIF_bm )
/*! \brief Clears the Timer/Counter compare or capture C interrupt flag.
*
* This macro clears the Timer/Counter compare or capture C interrupt flag.
*
* \note The CCC channel is not available on TCx1.
*
* \param _tc Timer/Counter 0 module instance.
*/
#define TC_ClearCCCFlag( _tc ) ( (_tc)->INTFLAGS = TC0_CCCIF_bm )
/*! \brief Get the status for Compare or Capture channel D.
*
* When the TC is in Input Capture mode, the return value of this macro
* indicates whether there is an unread input capture value available for
* capture channel D.
*
* When the TC is in any other mode, the return value of this macro
* indicates whether there has been a compare match between channel D and the
* counter.
*
* \note The CCD channel is not available on TCx1.
*
* \param _tc Timer/Counter 0 module instance.
*
* \return Non-zero if Compare or capture has occured, zero otherwise.
*/
#define TC_GetCCDFlag( _tc ) ( (_tc)->INTFLAGS & TC0_CCDIF_bm )
/*! \brief Clears the Timer/Counter compare or capture D interrupt flag.
*
* This macro clears the Timer/Counter compare or capture D interrupt flag.
*
* \note The CCD channel is not available on TCx1.
*
* \param _tc Timer/Counter 0 module instance.
*/
#define TC_ClearCCDFlag( _tc ) ( (_tc)->INTFLAGS = TC0_CCDIF_bm )
/*! \brief Reads the first available input capture value for channel A.
*
* This macro returns the first available input capture value for
* capture channel A.
*
* \param _tc Timer/Counter 0 or 1 module instance.
*
* \return The first available input capture value for channel A.
*/
#define TC_GetCaptureA( _tc ) ( (_tc)->CCA )
/*! \brief Reads the first available input capture value for channel B.
*
* This macro returns the first available input capture value for
* capture channel B.
*
* \param _tc Timer/Counter 0 or 1 module instance.
*
* \return The first available input capture value for channel B.
*/
#define TC_GetCaptureB( _tc ) ( (_tc)->CCB )
/*! \brief Reads the first available input capture value for channel C.
*
* This macro returns the first available input capture value for
* capture channel C.
*
* \note The CCC channel is not available on TCx1.
*
* \param _tc Timer/Counter 0 module instance.
*
* \return The first available input capture value for channel C.
*/
#define TC_GetCaptureC( _tc ) ( (_tc)->CCC )
/*! \brief Reads the first available input capture value for channel D.
*
* This macro returns the first available input capture value for
* capture channel D.
*
* \note The CCD channel is not available on TCx1.
*
* \param _tc Timer/Counter 0 module instance.
*
* \return The first available input capture value for channel D.
*/
#define TC_GetCaptureD( _tc ) ( (_tc)->CCD )
/* Prototyping of functions. Documentation can be found in source file. */
void TC0_ConfigClockSource( volatile TC0_t * tc, TC_CLKSEL_t clockSelection );
void TC0_ConfigWGM( volatile TC0_t * tc, TC_WGMODE_t wgm );
void TC0_ConfigInputCapture( volatile TC0_t * tc, TC_EVSEL_t eventSource );
void TC0_EnableCCChannels( volatile TC0_t * tc, uint8_t enableMask );
void TC0_DisableCCChannels( volatile TC0_t * tc, uint8_t disableMask );
void TC0_SetOverflowIntLevel( volatile TC0_t * tc, TC_OVFINTLVL_t intLevel );
void TC0_SetErrorIntLevel( volatile TC0_t * tc, TC_ERRINTLVL_t intLevel );
void TC0_SetCCAIntLevel( volatile TC0_t * tc, TC_CCAINTLVL_t intLevel );
void TC0_SetCCBIntLevel( volatile TC0_t * tc, TC_CCBINTLVL_t intLevel );
void TC0_SetCCCIntLevel( volatile TC0_t * tc, TC_CCCINTLVL_t intLevel );
void TC0_SetCCDIntLevel( volatile TC0_t * tc, TC_CCDINTLVL_t intLevel );
void TC0_Reset( volatile TC0_t * tc );
void TC1_ConfigClockSource( volatile TC1_t * tc, TC_CLKSEL_t clockSelection );
void TC1_ConfigWGM( volatile TC1_t * tc, TC_WGMODE_t wgm );
void TC1_ConfigInputCapture( volatile TC1_t * tc, TC_EVSEL_t eventSource );
void TC1_EnableCCChannels( volatile TC1_t * tc, uint8_t enableMask );
void TC1_DisableCCChannels( volatile TC1_t * tc, uint8_t disableMask );
void TC1_SetOverflowIntLevel( volatile TC1_t * tc, TC_OVFINTLVL_t intLevel );
void TC1_SetErrorIntLevel( volatile TC1_t * tc, TC_ERRINTLVL_t intLevel );
void TC1_SetCCAIntLevel( volatile TC1_t * tc, TC_CCAINTLVL_t intLevel );
void TC1_SetCCBIntLevel( volatile TC1_t * tc, TC_CCBINTLVL_t intLevel );
void TC1_SetCCCIntLevel( volatile TC1_t * tc, TC_CCCINTLVL_t intLevel );
void TC1_SetCCDIntLevel( volatile TC1_t * tc, TC_CCDINTLVL_t intLevel );
void TC1_Reset( volatile TC1_t * tc );
#endif

View File

@@ -0,0 +1,310 @@
/*
* TimerCounterFunctionsAndISR.h
*
* Created: 8/12/2014 3:56:59 PM
* Author: corwin
*/
#ifndef TIMERCOUNTERFUNCTIONSANDISR_H_
#define TIMERCOUNTERFUNCTIONSANDISR_H_
#include "DefinesAndMacros.h"
#include "Steppers.h"
#include "SystemInputFunctions.h"
#include <stdlib.h>
volatile long int CurrentTime = 0, PreviousTime = 0;
volatile char secondCounter = 0;
ISR(RTC_OVF_vect)
{
secondCounter++;
if(secondCounter >= 100){
CurrentTime++;
if(CurrentTime == 0){
PreviousTime = 0;
}
secondCounter = 0;
}
if((secondCounter % 25) == 0){
RDY_LED_TGL();
}
}
ISR(TCC0_OVF_vect){
static double desiredPositionPrevious = 0, currentPosition = 0;
static double middlePosition = 0, middleOffset = 0, maxDiff = 0, scalar = 0;
static double axisDiff = 0;
static char doneOnce = FALSE;
if(XAxis.shouldMove && steppersEnabled){
currentPosition = getAxisPosition(&XAxis);
if(doneOnce == FALSE){
desiredPositionPrevious = currentPosition;
middlePosition = (((XAxis.desiredPosition-desiredPositionPrevious)/2) + desiredPositionPrevious);
maxDiff = abs(middlePosition - desiredPositionPrevious);
doneOnce = TRUE;
}
axisDiff = (XAxis.desiredPosition - currentPosition);
if(XAxis.inManualMode == TRUE){
TCC0.PER = 14336;
}else{
middleOffset = abs(middlePosition - currentPosition);
if(middleOffset >= (((double)7*maxDiff)/10)){
double ratio = (maxDiff - (((double)7*maxDiff)/10));
double prescalar = (ratio-((double)maxDiff-middleOffset));
scalar = ((prescalar*10000)/ratio);
TCC0.PER = 5500+(int)scalar;
}
}
if(abs(axisDiff) <= XAxis.acceptableError){
XAxis.shouldMove = FALSE;
doneOnce = FALSE;
}else if(axisDiff > 0){
X_DIR_SET();
_delay_us(2);
X_STEP_SET();
_delay_us(2);
X_STEP_CLR();
XAxis.steps++;
}else if(axisDiff < 0){
if(X_LIM_LEFT_GET()){
X_DIR_CLR();
_delay_us(2);
X_STEP_SET();
_delay_us(2);
X_STEP_CLR();
XAxis.steps--;
}else{
XAxis.steps = 0;
}
}else{
ERR_LED_SET();
while(1);
}
}
}
ISR(TCD0_OVF_vect){
static double desiredPositionPrevious = 0, currentPosition = 0;
static double middlePosition = 0, middleOffset = 0, maxDiff = 0, scalar = 0;
static double axisDiff = 0;
static char doneOnce = FALSE;
if(YAxis.shouldMove && steppersEnabled){
currentPosition = getAxisPosition(&YAxis);
if(doneOnce == FALSE){
desiredPositionPrevious = currentPosition;
middlePosition = (((YAxis.desiredPosition-desiredPositionPrevious)/2) + desiredPositionPrevious);
maxDiff = abs(middlePosition - desiredPositionPrevious);
doneOnce = TRUE;
}
axisDiff = (YAxis.desiredPosition - currentPosition);
if(YAxis.inManualMode == TRUE){
TCD0.PER = 10752;
}else{
middleOffset = abs(middlePosition - currentPosition);
if(middleOffset >= (((double)7*maxDiff)/10)){
double ratio = (maxDiff - (((double)7*maxDiff)/10));
double prescalar = (ratio-((double)maxDiff-middleOffset));
scalar = ((prescalar*10000)/ratio);
TCD0.PER = 5500+(int)scalar;
}
}
if(abs(axisDiff) <= YAxis.acceptableError){
YAxis.shouldMove = FALSE;
doneOnce = FALSE;
}else if(axisDiff > 0){
Y_DIR_CLR();
_delay_us(2);
Y_STEP_SET();
_delay_us(2);
Y_STEP_CLR();
YAxis.steps++;
}else if(axisDiff < 0){
if(Y_LIM_FORW_GET()){
Y_DIR_SET();
_delay_us(2);
Y_STEP_SET();
_delay_us(2);
Y_STEP_CLR();
YAxis.steps--;
}else{
YAxis.steps = 0;
}
}else{
ERR_LED_SET();
while(1);
}
}
}
ISR(TCE0_OVF_vect){
static double desiredPositionPrevious = 0, currentPosition = 0;
static double middlePosition = 0, middleOffset = 0, maxDiff = 0, scalar = 0;
static double axisDiff = 0;
static char doneOnce = FALSE;
if(ZAxis.shouldMove && steppersEnabled){
currentPosition = getAxisPosition(&ZAxis);
if(doneOnce == FALSE){
desiredPositionPrevious = currentPosition;
middlePosition = (((ZAxis.desiredPosition-desiredPositionPrevious)/2) + desiredPositionPrevious);
maxDiff = abs(middlePosition - desiredPositionPrevious);
doneOnce = TRUE;
}
axisDiff = (ZAxis.desiredPosition - currentPosition);
if(ZAxis.inManualMode == TRUE){
TCE0.PER = 10752;
}else{
middleOffset = abs(middlePosition - currentPosition);
if(middleOffset >= (((double)7*maxDiff)/10)){
double ratio = (maxDiff - (((double)7*maxDiff)/10));
double prescalar = (ratio-((double)maxDiff-middleOffset));
scalar = ((prescalar*4608)/ratio);
TCE0.PER = 2304+(int)scalar;
}
}
if(abs(axisDiff) <= ZAxis.acceptableError){
ZAxis.shouldMove = FALSE;
doneOnce = FALSE;
}else if(axisDiff > 0){
Z_DIR_CLR();
_delay_us(2);
Z_STEP_SET();
_delay_us(2);
Z_STEP_CLR();
ZAxis.steps++;
}else if(axisDiff < 0){
Z_DIR_SET();
_delay_us(2);
Z_STEP_SET();
_delay_us(2);
Z_STEP_CLR();
ZAxis.steps--;
}else{
ERR_LED_SET();
while(1);
}
}
}
ISR(TCF0_OVF_vect){
static double desiredPositionPrevious = 0, currentPosition = 0;
static double middlePosition = 0, middleOffset = 0, maxDiff = 0, scalar = 0;
static double axisDiff = 0;
static char doneOnce = FALSE;
if(AAxis.shouldMove){
currentPosition = getAxisPosition(&AAxis);
if(doneOnce == FALSE){
desiredPositionPrevious = currentPosition;
middlePosition = (((AAxis.desiredPosition-desiredPositionPrevious)/2) + desiredPositionPrevious);
maxDiff = abs(middlePosition - desiredPositionPrevious);
doneOnce = TRUE;
}
axisDiff = (AAxis.desiredPosition - currentPosition);
if(AAxis.inManualMode == TRUE){
TCF0.PER = 10752;
}else{
middleOffset = abs(middlePosition - currentPosition);
scalar = (middleOffset*9216/maxDiff);
TCF0.PER = 4608+(int)scalar;
}
if(abs(axisDiff) <= AAxis.acceptableError){
AAxis.shouldMove = FALSE;
doneOnce = FALSE;
}else if(axisDiff > 0){
A_DIR_SET();
_delay_us(2);
A_STEP_SET();
_delay_us(2);
A_STEP_CLR();
AAxis.steps++;
}else if(axisDiff < 0){
A_DIR_CLR();
_delay_us(2);
A_STEP_SET();
_delay_us(2);
A_STEP_CLR();
AAxis.steps--;
}else{
ERR_LED_SET();
while(1);
}
}
}
ISR(USARTC0_RXC_vect){
USART_RXComplete(&usartData);
}
ISR(USARTC0_DRE_vect){
USART_DataRegEmpty(&usartData);
}
ISR(PORTB_INT0_vect){
static long int debounceTimePrevious;
if((CurrentTime - debounceTimePrevious) > 1){
if(!SYS_HOME_GET()){
btnState.homePressed = TRUE;
}
if(!SYS_CAL_GET()){
btnState.calibratePressed = TRUE;
}
if(!SYS_START_GET()){
btnState.startPressed = TRUE;
}
debounceTimePrevious = CurrentTime;
}
}
ISR(PORTF_INT0_vect){
static long int debounceTimePrevious;
if((CurrentTime - debounceTimePrevious) > 1){
if(!ESTOP_GET()){
disableSteppers();
ERR_LED_SET();
_delay_ms(5000);
CCP = CCP_IOREG_gc;
RST.CTRL = RST_SWRST_bm;
}
debounceTimePrevious = CurrentTime;
}
}
#endif /* TIMERCOUNTERFUNCTIONSANDISR_H_ */

View File

@@ -0,0 +1,154 @@
/* This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief This file implements some macros that makes the IAR C-compiler and
* avr-gcc work with the same code base for the AVR architecture.
*
* \par Documentation
* For comprehensive code documentation, supported compilers, compiler
* settings and supported devices see readme.html
*
* \author
* Atmel Corporation: http://www.atmel.com \n
* Support email: avr@atmel.com
*
* $Revision: 1694 $
* $Date: 2008-07-29 14:21:58 +0200 (ti, 29 jul 2008) $ \n
*
* Copyright (c) 2008, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#ifndef COMPILER_AVR_H
#define COMPILER_AVR_H
#ifndef F_CPU
/*! \brief Define default CPU frequency, if this is not already defined. */
#define F_CPU 2000000UL
#endif
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
/*! \brief This macro will protect the following code from interrupts. */
#define AVR_ENTER_CRITICAL_REGION( ) uint8_t volatile saved_sreg = SREG; \
cli();
/*! \brief This macro must always be used in conjunction with AVR_ENTER_CRITICAL_REGION
* so the interrupts are enabled again.
*/
#define AVR_LEAVE_CRITICAL_REGION( ) SREG = saved_sreg;
#if defined( __ICCAVR__ )
#include <inavr.h>
#include <ioavr.h>
#include <intrinsics.h>
#include <pgmspace.h>
#ifndef __HAS_ELPM__
#define _MEMATTR __flash
#else /* __HAS_ELPM__ */
#define _MEMATTR __farflash
#endif /* __HAS_ELPM__ */
/*! \brief Perform a delay of \c us microseconds.
*
* The macro F_CPU is supposed to be defined to a constant defining the CPU
* clock frequency (in Hertz).
*
* The maximal possible delay is 262.14 ms / F_CPU in MHz.
*
* \note For the IAR compiler, currently F_CPU must be a
* multiple of 1000000UL (1 MHz).
*/
#define delay_us( us ) ( __delay_cycles( ( F_CPU / 1000000UL ) * ( us ) ) )
/*! \brief Preprocessor magic.
*
* Some preprocessor magic to allow for a header file abstraction of
* interrupt service routine declarations for the IAR compiler. This
* requires the use of the C99 _Pragma() directive (rather than the
* old #pragma one that could not be used as a macro replacement), as
* well as two different levels of preprocessor concetanations in
* order to do both, assign the correct interrupt vector name, as well
* as construct a unique function name for the ISR.
*
* \note Do *NOT* try to reorder the macros below, as this will only
* work in the given order.
*/
#define PRAGMA(x) _Pragma( #x )
#define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void)
#define sei( ) (__enable_interrupt( ))
#define cli( ) (__disable_interrupt( ))
/*! \brief Define the no operation macro. */
#define nop( ) (__no_operation())
/*! \brief Define the watchdog reset macro. */
#define watchdog_reset( ) (__watchdog_reset( ))
#define INLINE PRAGMA( inline=forced ) static
#define FLASH_DECLARE(x) _MEMATTR x
#define FLASH_STRING(x) ((_MEMATTR const char *)(x))
#define FLASH_STRING_T char const _MEMATTR *
#define FLASH_BYTE_ARRAY_T uint8_t const _MEMATTR *
#define PGM_READ_BYTE(x) *(x)
#define PGM_READ_WORD(x) *(x)
#define SHORTENUM /**/
#elif defined( __GNUC__ )
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
/*! \brief Define the delay_us macro for GCC. */
#define delay_us( us ) (_delay_us( us ))
#define INLINE static inline
/*! \brief Define the no operation macro. */
#define nop() do { __asm__ __volatile__ ("nop"); } while (0)
#define MAIN_TASK_PROLOGUE int
#define MAIN_TASK_EPILOGUE() return -1;
#define SHORTENUM __attribute__ ((packed))
#else
#error Compiler not supported.
#endif
#endif

View File

@@ -0,0 +1,320 @@
/* This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief
* XMEGA USART driver source file.
*
* This file contains the function implementations the XMEGA interrupt
* and polled USART driver.
*
* The driver is not intended for size and/or speed critical code, since
* most functions are just a few lines of code, and the function call
* overhead would decrease code performance. The driver is intended for
* rapid prototyping and documentation purposes for getting started with
* the XMEGA ADC module.
*
* For size and/or speed critical code, it is recommended to copy the
* function contents directly into your application instead of making
* a function call.
*
* Some functions use the following construct:
* "some_register = ... | (some_parameter ? SOME_BIT_bm : 0) | ..."
* Although the use of the ternary operator ( if ? then : else ) is discouraged,
* in some occasions the operator makes it possible to write pretty clean and
* neat code. In this driver, the construct is used to set or not set a
* configuration bit based on a boolean input parameter, such as
* the "some_parameter" in the example above.
*
* \par Application note:
* AVR1307: Using the XMEGA USART
*
* \par Documentation
* For comprehensive code documentation, supported compilers, compiler
* settings and supported devices see readme.html
*
* \author
* Atmel Corporation: http://www.atmel.com \n
* Support email: avr@atmel.com
*
* $Revision: 1694 $
* $Date: 2008-07-29 14:21:58 +0200 (ti, 29 jul 2008) $ \n
*
* Copyright (c) 2008, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include "usart_driver.h"
/*! \brief Initializes buffer and selects what USART module to use.
*
* Initializes receive and transmit buffer and selects what USART module to use,
* and stores the data register empty interrupt level.
*
* \param usart_data The USART_data_t struct instance.
* \param usart The USART module.
* \param dreIntLevel Data register empty interrupt level.
*/
void USART_InterruptDriver_Initialize(USART_data_t * usart_data,
USART_t * usart,
USART_DREINTLVL_t dreIntLevel)
{
usart_data->usart = usart;
usart_data->dreIntLevel = dreIntLevel;
usart_data->buffer.RX_Tail = 0;
usart_data->buffer.RX_Head = 0;
usart_data->buffer.TX_Tail = 0;
usart_data->buffer.TX_Head = 0;
}
/*! \brief Set USART DRE interrupt level.
*
* Set the interrupt level on Data Register interrupt.
*
* \note Changing the DRE interrupt level in the interrupt driver while it is
* running will not change the DRE interrupt level in the USART before the
* DRE interrupt have been disabled and enabled again.
*
* \param usart_data The USART_data_t struct instance
* \param dreIntLevel Interrupt level of the DRE interrupt.
*/
void USART_InterruptDriver_DreInterruptLevel_Set(USART_data_t * usart_data,
USART_DREINTLVL_t dreIntLevel)
{
usart_data->dreIntLevel = dreIntLevel;
}
/*! \brief Test if there is data in the transmitter software buffer.
*
* This function can be used to test if there is free space in the transmitter
* software buffer.
*
* \param usart_data The USART_data_t struct instance.
*
* \retval true There is data in the receive buffer.
* \retval false The receive buffer is empty.
*/
bool USART_TXBuffer_FreeSpace(USART_data_t * usart_data)
{
/* Make copies to make sure that volatile access is specified. */
uint8_t tempHead = (usart_data->buffer.TX_Head + 1) & USART_TX_BUFFER_MASK;
uint8_t tempTail = usart_data->buffer.TX_Tail;
/* There are data left in the buffer unless Head and Tail are equal. */
return (tempHead != tempTail);
}
/*! \brief Put data (5-8 bit character).
*
* Stores data byte in TX software buffer and enables DRE interrupt if there
* is free space in the TX software buffer.
*
* \param usart_data The USART_data_t struct instance.
* \param data The data to send.
*/
bool USART_TXBuffer_PutByte(USART_data_t * usart_data, uint8_t data)
{
uint8_t tempCTRLA;
uint8_t tempTX_Head;
bool TXBuffer_FreeSpace;
USART_Buffer_t * TXbufPtr;
TXbufPtr = &usart_data->buffer;
TXBuffer_FreeSpace = USART_TXBuffer_FreeSpace(usart_data);
if(TXBuffer_FreeSpace)
{
tempTX_Head = TXbufPtr->TX_Head;
TXbufPtr->TX[tempTX_Head]= data;
/* Advance buffer head. */
TXbufPtr->TX_Head = (tempTX_Head + 1) & USART_TX_BUFFER_MASK;
/* Enable DRE interrupt. */
tempCTRLA = usart_data->usart->CTRLA;
tempCTRLA = (tempCTRLA & ~USART_DREINTLVL_gm) | usart_data->dreIntLevel;
usart_data->usart->CTRLA = tempCTRLA;
}
return TXBuffer_FreeSpace;
}
/*! \brief Test if there is data in the receive software buffer.
*
* This function can be used to test if there is data in the receive software
* buffer.
*
* \param usart_data The USART_data_t struct instance
*
* \retval true There is data in the receive buffer.
* \retval false The receive buffer is empty.
*/
bool USART_RXBufferData_Available(USART_data_t * usart_data)
{
/* Make copies to make sure that volatile access is specified. */
uint8_t tempHead = usart_data->buffer.RX_Head;
uint8_t tempTail = usart_data->buffer.RX_Tail;
/* There are data left in the buffer unless Head and Tail are equal. */
return (tempHead != tempTail);
}
/*! \brief Get received data (5-8 bit character).
*
* The function USART_RXBufferData_Available should be used before this
* function is used to ensure that data is available.
*
* Returns data from RX software buffer.
*
* \param usart_data The USART_data_t struct instance.
*
* \return Received data.
*/
uint8_t USART_RXBuffer_GetByte(USART_data_t * usart_data)
{
USART_Buffer_t * bufPtr;
uint8_t ans;
bufPtr = &usart_data->buffer;
ans = (bufPtr->RX[bufPtr->RX_Tail]);
/* Advance buffer tail. */
bufPtr->RX_Tail = (bufPtr->RX_Tail + 1) & USART_RX_BUFFER_MASK;
return ans;
}
/*! \brief RX Complete Interrupt Service Routine.
*
* RX Complete Interrupt Service Routine.
* Stores received data in RX software buffer.
*
* \param usart_data The USART_data_t struct instance.
*/
bool USART_RXComplete(USART_data_t * usart_data)
{
USART_Buffer_t * bufPtr;
bool ans;
bufPtr = &usart_data->buffer;
/* Advance buffer head. */
uint8_t tempRX_Head = (bufPtr->RX_Head + 1) & USART_RX_BUFFER_MASK;
/* Check for overflow. */
uint8_t tempRX_Tail = bufPtr->RX_Tail;
uint8_t data = usart_data->usart->DATA;
if (tempRX_Head == tempRX_Tail) {
ans = false;
}else{
ans = true;
usart_data->buffer.RX[usart_data->buffer.RX_Head] = data;
usart_data->buffer.RX_Head = tempRX_Head;
}
return ans;
}
/*! \brief Data Register Empty Interrupt Service Routine.
*
* Data Register Empty Interrupt Service Routine.
* Transmits one byte from TX software buffer. Disables DRE interrupt if buffer
* is empty. Argument is pointer to USART (USART_data_t).
*
* \param usart_data The USART_data_t struct instance.
*/
void USART_DataRegEmpty(USART_data_t * usart_data)
{
USART_Buffer_t * bufPtr;
bufPtr = &usart_data->buffer;
/* Check if all data is transmitted. */
uint8_t tempTX_Tail = usart_data->buffer.TX_Tail;
if (bufPtr->TX_Head == tempTX_Tail){
/* Disable DRE interrupts. */
uint8_t tempCTRLA = usart_data->usart->CTRLA;
tempCTRLA = (tempCTRLA & ~USART_DREINTLVL_gm) | USART_DREINTLVL_OFF_gc;
usart_data->usart->CTRLA = tempCTRLA;
}else{
/* Start transmitting. */
uint8_t data = bufPtr->TX[usart_data->buffer.TX_Tail];
usart_data->usart->DATA = data;
/* Advance buffer tail. */
bufPtr->TX_Tail = (bufPtr->TX_Tail + 1) & USART_TX_BUFFER_MASK;
}
}
/*! \brief Put data (9 bit character).
*
* Use the function USART_IsTXDataRegisterEmpty before using this function to
* put 9 bit character to the TX register.
*
* \param usart The USART module.
* \param data The data to send.
*/
void USART_NineBits_PutChar(USART_t * usart, uint16_t data)
{
if(data & 0x0100) {
usart->CTRLB |= USART_TXB8_bm;
}else {
usart->CTRLB &= ~USART_TXB8_bm;
}
usart->DATA = (data & 0x00FF);
}
/*! \brief Get received data (9 bit character).
*
* This function reads out the received 9 bit character (uint16_t).
* Use the function USART_IsRXComplete to check if anything is received.
*
* \param usart The USART module.
*
* \retval Received data.
*/
uint16_t USART_NineBits_GetChar(USART_t * usart)
{
if(usart->CTRLB & USART_RXB8_bm) {
return(0x0100 | usart->DATA);
}else {
return(usart->DATA);
}
}

View File

@@ -0,0 +1,306 @@
/* This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief XMEGA USART driver header file.
*
* This file contains the function prototypes and enumerator definitions
* for various configuration parameters for the XMEGA USART driver.
*
* The driver is not intended for size and/or speed critical code, since
* most functions are just a few lines of code, and the function call
* overhead would decrease code performance. The driver is intended for
* rapid prototyping and documentation purposes for getting started with
* the XMEGA ADC module.
*
* For size and/or speed critical code, it is recommended to copy the
* function contents directly into your application instead of making
* a function call.
*
* \par Application note:
* AVR1307: Using the XMEGA USART
*
* \par Documentation
* For comprehensive code documentation, supported compilers, compiler
* settings and supported devices see readme.html
*
* \author
* Atmel Corporation: http://www.atmel.com \n
* Support email: avr@atmel.com
*
* $Revision: 1694 $
* $Date: 2008-07-29 14:21:58 +0200 (ti, 29 jul 2008) $ \n
*
* Copyright (c) 2008, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef USART_DRIVER_H
#define USART_DRIVER_H
#include "avr_compiler.h"
/* USART buffer defines. */
/* \brief Receive buffer size: 2,4,8,16,32,64,128 or 256 bytes. */
#define USART_RX_BUFFER_SIZE 4
/* \brief Transmit buffer size: 2,4,8,16,32,64,128 or 256 bytes */
#define USART_TX_BUFFER_SIZE 4
/* \brief Receive buffer mask. */
#define USART_RX_BUFFER_MASK ( USART_RX_BUFFER_SIZE - 1 )
/* \brief Transmit buffer mask. */
#define USART_TX_BUFFER_MASK ( USART_TX_BUFFER_SIZE - 1 )
#if ( USART_RX_BUFFER_SIZE & USART_RX_BUFFER_MASK )
#error RX buffer size is not a power of 2
#endif
#if ( USART_TX_BUFFER_SIZE & USART_TX_BUFFER_MASK )
#error TX buffer size is not a power of 2
#endif
/* \brief USART transmit and receive ring buffer. */
typedef struct USART_Buffer
{
/* \brief Receive buffer. */
volatile uint8_t RX[USART_RX_BUFFER_SIZE];
/* \brief Transmit buffer. */
volatile uint8_t TX[USART_TX_BUFFER_SIZE];
/* \brief Receive buffer head. */
volatile uint8_t RX_Head;
/* \brief Receive buffer tail. */
volatile uint8_t RX_Tail;
/* \brief Transmit buffer head. */
volatile uint8_t TX_Head;
/* \brief Transmit buffer tail. */
volatile uint8_t TX_Tail;
} USART_Buffer_t;
/*! \brief Struct used when interrupt driven driver is used.
*
* Struct containing pointer to a usart, a buffer and a location to store Data
* register interrupt level temporary.
*/
typedef struct Usart_and_buffer
{
/* \brief Pointer to USART module to use. */
USART_t * usart;
/* \brief Data register empty interrupt level. */
USART_DREINTLVL_t dreIntLevel;
/* \brief Data buffer. */
USART_Buffer_t buffer;
} USART_data_t;
/* Macros. */
/*! \brief Macro that sets the USART frame format.
*
* Sets the frame format, Frame Size, parity mode and number of stop bits.
*
* \param _usart Pointer to the USART module
* \param _charSize The character size. Use USART_CHSIZE_t type.
* \param _parityMode The parity Mode. Use USART_PMODE_t type.
* \param _twoStopBits Enable two stop bit mode. Use bool type.
*/
#define USART_Format_Set(_usart, _charSize, _parityMode, _twoStopBits) \
(_usart)->CTRLC = (uint8_t) _charSize | _parityMode | \
(_twoStopBits ? USART_SBMODE_bm : 0)
/*! \brief Set USART baud rate.
*
* Sets the USART's baud rate register.
*
* UBRR_Value : Value written to UBRR
* ScaleFactor : Time Base Generator Scale Factor
*
* Equation for calculation of BSEL value in asynchronous normal speed mode:
* If ScaleFactor >= 0
* BSEL = ((I/O clock frequency)/(2^(ScaleFactor)*16*Baudrate))-1
* If ScaleFactor < 0
* BSEL = (1/(2^(ScaleFactor)*16))*(((I/O clock frequency)/Baudrate)-1)
*
* \note See XMEGA manual for equations for calculation of BSEL value in other
* modes.
*
* \param _usart Pointer to the USART module.
* \param _bselValue Value to write to BSEL part of Baud control register.
* Use uint16_t type.
* \param _bScaleFactor USART baud rate scale factor.
* Use uint8_t type
*/
#define USART_Baudrate_Set(_usart, _bselValue, _bScaleFactor) \
(_usart)->BAUDCTRLA =(uint8_t)_bselValue; \
(_usart)->BAUDCTRLB =(_bScaleFactor << USART_BSCALE0_bp)|(_bselValue >> 8)
/*! \brief Enable USART receiver.
*
* \param _usart Pointer to the USART module
*/
#define USART_Rx_Enable(_usart) ((_usart)->CTRLB |= USART_RXEN_bm)
/*! \brief Disable USART receiver.
*
* \param _usart Pointer to the USART module.
*/
#define USART_Rx_Disable(_usart) ((_usart)->CTRLB &= ~USART_RXEN_bm)
/*! \brief Enable USART transmitter.
*
* \param _usart Pointer to the USART module.
*/
#define USART_Tx_Enable(_usart) ((_usart)->CTRLB |= USART_TXEN_bm)
/*! \brief Disable USART transmitter.
*
* \param _usart Pointer to the USART module.
*/
#define USART_Tx_Disable(_usart) ((_usart)->CTRLB &= ~USART_TXEN_bm)
/*! \brief Set USART RXD interrupt level.
*
* Sets the interrupt level on RX Complete interrupt.
*
* \param _usart Pointer to the USART module.
* \param _rxdIntLevel Interrupt level of the RXD interrupt.
* Use USART_RXCINTLVL_t type.
*/
#define USART_RxdInterruptLevel_Set(_usart, _rxdIntLevel) \
((_usart)->CTRLA = ((_usart)->CTRLA & ~USART_RXCINTLVL_gm) | _rxdIntLevel)
/*! \brief Set USART TXD interrupt level.
*
* Sets the interrupt level on TX Complete interrupt.
*
* \param _usart Pointer to the USART module.
* \param _txdIntLevel Interrupt level of the TXD interrupt.
* Use USART_TXCINTLVL_t type.
*/
#define USART_TxdInterruptLevel_Set(_usart, _txdIntLevel) \
(_usart)->CTRLA = ((_usart)->CTRLA & ~USART_TXCINTLVL_gm) | _txdIntLevel
/*! \brief Set USART DRE interrupt level.
*
* Sets the interrupt level on Data Register interrupt.
*
* \param _usart Pointer to the USART module.
* \param _dreIntLevel Interrupt level of the DRE interrupt.
* Use USART_DREINTLVL_t type.
*/
#define USART_DreInterruptLevel_Set(_usart, _dreIntLevel) \
(_usart)->CTRLA = ((_usart)->CTRLA & ~USART_DREINTLVL_gm) | _dreIntLevel
/*! \brief Set the mode the USART run in.
*
* Set the mode the USART run in. The default mode is asynchronous mode.
*
* \param _usart Pointer to the USART module register section.
* \param _usartMode Selects the USART mode. Use USART_CMODE_t type.
*
* USART modes:
* - 0x0 : Asynchronous mode.
* - 0x1 : Synchronous mode.
* - 0x2 : IrDA mode.
* - 0x3 : Master SPI mode.
*/
#define USART_SetMode(_usart, _usartMode) \
((_usart)->CTRLC = ((_usart)->CTRLC & (~USART_CMODE_gm)) | _usartMode)
/*! \brief Check if data register empty flag is set.
*
* \param _usart The USART module.
*/
#define USART_IsTXDataRegisterEmpty(_usart) (((_usart)->STATUS & USART_DREIF_bm) != 0)
/*! \brief Put data (5-8 bit character).
*
* Use the macro USART_IsTXDataRegisterEmpty before using this function to
* put data to the TX register.
*
* \param _usart The USART module.
* \param _data The data to send.
*/
#define USART_PutChar(_usart, _data) ((_usart)->DATA = _data)
/*! \brief Checks if the RX complete interrupt flag is set.
*
* Checks if the RX complete interrupt flag is set.
*
* \param _usart The USART module.
*/
#define USART_IsRXComplete(_usart) (((_usart)->STATUS & USART_RXCIF_bm) != 0)
/*! \brief Get received data (5-8 bit character).
*
* This macro reads out the RX register.
* Use the macro USART_RX_Complete to check if anything is received.
*
* \param _usart The USART module.
*
* \retval Received data.
*/
#define USART_GetChar(_usart) ((_usart)->DATA)
/* Functions for interrupt driven driver. */
void USART_InterruptDriver_Initialize(USART_data_t * usart_data,
USART_t * usart,
USART_DREINTLVL_t dreIntLevel );
void USART_InterruptDriver_DreInterruptLevel_Set(USART_data_t * usart_data,
USART_DREINTLVL_t dreIntLevel);
bool USART_TXBuffer_FreeSpace(USART_data_t * usart_data);
bool USART_TXBuffer_PutByte(USART_data_t * usart_data, uint8_t data);
bool USART_RXBufferData_Available(USART_data_t * usart_data);
uint8_t USART_RXBuffer_GetByte(USART_data_t * usart_data);
bool USART_RXComplete(USART_data_t * usart_data);
void USART_DataRegEmpty(USART_data_t * usart_data);
/* Functions for polled driver. */
void USART_NineBits_PutChar(USART_t * usart, uint16_t data);
uint16_t USART_NineBits_GetChar(USART_t * usart);
#endif