mirror of
https://github.com/caperren/school_archives.git
synced 2025-11-09 13:41:13 +00:00
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:
@@ -0,0 +1,829 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Includes, Defines, Instantiations, and Global Variables//////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Includes
|
||||
#include "DualVNH5019MotorShield.h" //Library for the motor driver shield
|
||||
#include <EEPROM.h> //EEPROM Storage Library for storing config changes
|
||||
#include <SoftwareSerial.h> //Software Serial Library needed for lcd communications
|
||||
#include <StopWatch.h> //Stopwatch library for timing purposes
|
||||
#include <avr/pgmspace.h> //PROGMEM library for storage of config
|
||||
#include <String.h>
|
||||
|
||||
//Pin Definitions (Arduino Suggested Method)
|
||||
const unsigned char LcdTX = 5; //Pin connected to LCD RX Line
|
||||
|
||||
const unsigned char StartSwitch = 11; //Pin connected to start switch
|
||||
const unsigned char StopSwitch = 13; //Pin connected to stop switch
|
||||
|
||||
const unsigned char EncoderLed = A2; //Pin connected to rotary encoder led
|
||||
const unsigned char EncoderButton = A3; //Pin connected to rotary encoder led
|
||||
const unsigned char EncoderChannelB = A4; //Pin connected to channel A of the rotary encoder
|
||||
const unsigned char EncoderChannelA = A5; //Pin connected to channel B of the rotary encoder
|
||||
|
||||
//Instantiations
|
||||
SoftwareSerial LcdSerial(3, LcdTX); //Software Serial Instantiation with Pin 3 as dummy for RX
|
||||
DualVNH5019MotorShield MotorDriver; //Motor Driver Library Instantiation
|
||||
StopWatch MyStopWatch(StopWatch::SECONDS); //StopWatch Instantiation for measuring time
|
||||
|
||||
enum ArduinoPrograms{ //Enumeration for defining the arduino program states
|
||||
StandardDechorionation = 0, //This is the standard Dechorianation Program
|
||||
TwoFourDechorionation = 1, //Used for embryo's 24 hours old
|
||||
PronaseAndRinse = 2, //This is an alternating pronase and rinse cycle
|
||||
RinseOnly = 3, //This only does the rinse cycle
|
||||
SDConfig = 4, //Config page for the standard dechorionation
|
||||
TFConfig = 5, //Config page for the 24 hour
|
||||
PnRConfig = 6, //Config page for Pronase and Rinse
|
||||
ROConfig = 7, //Config page for Rinse Only
|
||||
ProgramSelection = 8 //Presents a program selection screen
|
||||
} ArduinoProgram = ProgramSelection; //This selects the arduino program to run
|
||||
|
||||
//Global Variables and Constants and Configs
|
||||
const unsigned char TitleTimeout = 2; //Time in seconds to display the main device title
|
||||
const unsigned char LcdPageDelay = 3; //Seconds to wait before the lcd changes pages.
|
||||
const unsigned char ConfigPageTimeout = 5; //Time in seconds to wait before dropping the user back to the program selection screen
|
||||
const unsigned int DebounceTimeout = 300; //Timeout in milliseconds of the button debounce delay
|
||||
|
||||
unsigned char DoneOnce = 0; //Variable to store whether something has happened or not.
|
||||
unsigned char EStop = 0; //Variable to store the status of the system's estop button
|
||||
unsigned char CycleSkip = 0; //Variable to store whether the user wants to skip the current cycle of a program.
|
||||
|
||||
signed char SelectedProgram = 0; //Holds the current program selection. This is not the currently active program.
|
||||
signed char SelectedConfig = 0; //Hold the current config selection.
|
||||
unsigned char PreviousConfig = 0; //A value to hold the previous config value. Used for smoothing the rotary encoder reading.
|
||||
|
||||
unsigned char EncoderChannelALastValue = LOW; //This variable stores the previous state of channel a on the rotary encoder. This is needed to determine direction.
|
||||
unsigned char EncoderReferenceVariable = LOW; //This is a dummy varaible for direction determination on for the rotary encoder.
|
||||
|
||||
String ConfigVal; //This is used to store the value returned from PROGMEM and converting it to a char array.
|
||||
int NewVal; //This holds the new value
|
||||
int PrevVal; //This holds the previous value when changing configs
|
||||
|
||||
const unsigned int MaxDriveSpeed = 400; //Max drive speed value given by the motor driver library
|
||||
const unsigned int RotationMinDriveSpeed = 75; //Minimum value to get the motor to turn
|
||||
const unsigned int PumpMinDriveSpeed = 75; //Minimum value to get the motor to turn
|
||||
const unsigned int PumpMaxDriveSpeed = 180;
|
||||
unsigned int MaxRampValue = 300; //The maximum reasonable value used when ramping the motors
|
||||
unsigned int MaxPumpRampValue = 150;
|
||||
unsigned int MinRampValue = 1; //The minimum reasonable value used when ramping the motors
|
||||
unsigned int CycleSeconds; //Stores the seconds that each cycle should run for.
|
||||
unsigned int DriveLoop; //Looping variable for driving motors
|
||||
|
||||
|
||||
//| Program List Top | Program List Bottom |
|
||||
PROGMEM prog_char* ProgramNames[][2] = { //Strings for program names shown on the LCD
|
||||
{"1: Standard ", " Dechorionation"},
|
||||
{"2: 24 Hour Old ", " Dechorionation"},
|
||||
{"3: 6 Hour HPF ", " Dechorionation"}, //Note that "Pronase and Rinse" has been changed to this.
|
||||
{"4: Rinse Cycle ", " Only "}
|
||||
};
|
||||
|
||||
// | Main Page Top | Main Page Bottom | Adjust Page Top | Max Value | EEPROM Address |
|
||||
PROGMEM const prog_char* StandardDechorionationConfig[][5] = {
|
||||
{"Pronase Cycle 1 ", " Minutes ", " Minutes ", (const prog_char*)256, (const prog_char*)0},
|
||||
{"Pronase Cycle 1 ", " Seconds ", " Seconds ", (const prog_char*)60, (const prog_char*)1},
|
||||
{" Rinse Cycle ", " Minutes ", " Minutes ", (const prog_char*)256, (const prog_char*)2},
|
||||
{" Rinse Cycle ", " Seconds ", " Seconds ", (const prog_char*)60, (const prog_char*)3},
|
||||
{"Pronase Cycle 2 ", " Minutes ", " Minutes ", (const prog_char*)256, (const prog_char*)4},
|
||||
{"Pronase Cycle 2 ", " Seconds ", " Seconds ", (const prog_char*)60, (const prog_char*)5},
|
||||
{" Rotation Speed ", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)7},
|
||||
{"Rotation Ramping", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)6},
|
||||
{" Pump Speed ", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)8},
|
||||
{" Pump Ramp ", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)9}
|
||||
};
|
||||
|
||||
const unsigned char NumSDConfig = 10; //Stores the maximum number of available configs
|
||||
|
||||
unsigned char EEPROMConfigSD[NumSDConfig] = { //User Modifiable Standard Dechorionation Config Array
|
||||
6, //Values correspond to each cycle above, in same array order
|
||||
30, //Default values here are for initial EEPROM Programming
|
||||
1,
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
50,
|
||||
75,
|
||||
100,
|
||||
100
|
||||
};
|
||||
|
||||
// | Main Page Top | Main Page Bottom | Adjust Page Top | Max Value | EEPROM Address |
|
||||
PROGMEM const prog_char* TwoFourDechorionationConfig[][5] = {
|
||||
{"Pronase Cycle 1 ", " Minutes ", " Minutes ", (const prog_char*)256, (const prog_char*)10},
|
||||
{"Pronase Cycle 1 ", " Seconds ", " Seconds ", (const prog_char*)60, (const prog_char*)11},
|
||||
{" Rinse Cycle ", " Minutes ", " Minutes ", (const prog_char*)256, (const prog_char*)12},
|
||||
{" Rinse Cycle ", " Seconds ", " Seconds ", (const prog_char*)60, (const prog_char*)13},
|
||||
{"Pronase Cycle 2 ", " Minutes ", " Minutes ", (const prog_char*)256, (const prog_char*)14},
|
||||
{"Pronase Cycle 2 ", " Seconds ", " Seconds ", (const prog_char*)60, (const prog_char*)15},
|
||||
{" Rotation Speed ", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)16},
|
||||
{"Rotation Ramping", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)17},
|
||||
{" Pump Speed ", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)18},
|
||||
{" Pump Ramp ", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)19}
|
||||
};
|
||||
|
||||
const unsigned char NumTFConfig = 10; //Stores the maximum number of available configs
|
||||
|
||||
unsigned char EEPROMConfigTF[NumTFConfig] = { //User Modifiable 24 Hour Dechorionation Config Array
|
||||
3, //Values correspond to each cycle above, in same array order
|
||||
0, //Default values here are for initial EEPROM Programming
|
||||
1,
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
85,
|
||||
85,
|
||||
85,
|
||||
85
|
||||
};
|
||||
|
||||
// | Main Page Top | Main Page Bottom | Adjust Page Top | Max Value | EEPROM Address |
|
||||
PROGMEM const prog_char* PronaseAndRinseConfig[][5] = {
|
||||
{"Pronase Cycle 1 ", " Minutes ", " Minutes ", (const prog_char*)256, (const prog_char*)10},
|
||||
{"Pronase Cycle 1 ", " Seconds ", " Seconds ", (const prog_char*)60, (const prog_char*)11},
|
||||
{" Rinse Cycle ", " Minutes ", " Minutes ", (const prog_char*)256, (const prog_char*)12},
|
||||
{" Rinse Cycle ", " Seconds ", " Seconds ", (const prog_char*)60, (const prog_char*)13},
|
||||
{"Pronase Cycle 2 ", " Minutes ", " Minutes ", (const prog_char*)256, (const prog_char*)14},
|
||||
{"Pronase Cycle 2 ", " Seconds ", " Seconds ", (const prog_char*)60, (const prog_char*)15},
|
||||
{" Rotation Speed ", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)16},
|
||||
{"Rotation Ramping", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)17},
|
||||
{" Pump Speed ", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)18},
|
||||
{" Pump Ramp ", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)19}
|
||||
};
|
||||
|
||||
const unsigned char NumPnRConfig = 10;
|
||||
|
||||
unsigned char EEPROMConfigPnR[NumPnRConfig] = { //User Modifiable Pronase and Rinse Config Array
|
||||
6, //Values correspond to each cycle above, in same array order
|
||||
30, //Default values here are for initial EEPROM Programming
|
||||
1,
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
85,
|
||||
85,
|
||||
85,
|
||||
85
|
||||
};
|
||||
|
||||
// | Main Page Top | Main Page Bottom | Adjust Page Top | Max Value | EEPROM Address |
|
||||
PROGMEM const prog_char* RinseOnlyConfig[][5] = {
|
||||
{" Rinse Cycle ", " Minutes ", " Minutes ", (const prog_char*)256, (const prog_char*)30},
|
||||
{" Rinse Cycle ", " Seconds ", " Seconds ", (const prog_char*)60, (const prog_char*)31},
|
||||
{" Pump Speed ", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)32},
|
||||
{" Pump Ramp ", " Percentage ", " Percent ", (const prog_char*)100, (const prog_char*)33}
|
||||
};
|
||||
|
||||
const unsigned char NumROConfig = 4;
|
||||
|
||||
unsigned char EEPROMConfigRO[NumROConfig] = { //User Modifiable Standard Dechorionation Config Array
|
||||
1, //Values correspond to each cycle above, in same array order
|
||||
0, //Default values here are for initial EEPROM Programming
|
||||
85,
|
||||
85
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Arduino Setup////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setup(){
|
||||
MotorDriver.init(); //Initialize the VNH5019 Motor Driving Shield
|
||||
InitializePins(); //Initialize pins for switches, rotary encoder, and leds
|
||||
Serial.begin(115200); //Start communicating to PC at 115200 baud
|
||||
LcdSerial.begin(9600); //Start communicating with LCD dispaly at 9600 buad
|
||||
delay(TitleTimeout* 500); //Wait for Lcd to initialize
|
||||
FullLcdClear(); //Clear the LCD to remove artifacts
|
||||
FullLcdWrite((unsigned char*)" Tanguay Labs ", (unsigned char*)"Dechorionator #2"); //Show the device name
|
||||
Serial.println("Dechorionator Initialized"); //Debug on Serial
|
||||
delay(TitleTimeout* 1000); //Wait on name screen
|
||||
FullLcdClear(); //Clear the LCD
|
||||
//SaveToEEPROM(); //Used to write initial EEPROM configuration. It should no longer be needed.
|
||||
ReadFromEEPROM(); //Reads user configured settings from EEPROM into config arrays
|
||||
GetInitialEncoderData();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Main Arduino Program Loop////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void loop(){
|
||||
switch(ArduinoProgram){
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
case ProgramSelection:
|
||||
if(DoneOnce != 1){ ShowProgramListIntro();} //Show an intro screen if the device has just turned on
|
||||
DisplayProgramList(); //Show the currently selected program title
|
||||
if(CheckProgramStart() | CheckConfigButton()){ //If the start button or configuration button are pressed, immediately switch to the new program
|
||||
SelectedConfig = PreviousConfig = 0; //Set config variables to 0 in preperation
|
||||
break; //Immediately break if a button has been pressed
|
||||
}
|
||||
SelectedProgram = ConstrainProgramList(SelectedProgram + ReturnEncoderDirection());//Determine if the encoder has moved, and change the program display if it has
|
||||
break;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
case StandardDechorionation:
|
||||
EStop = 0;
|
||||
|
||||
//Pronase Cycle 1
|
||||
FullLcdWrite((unsigned char*)" Starting ",(unsigned char*)"Pronase Cycle 1 ");
|
||||
delay(LcdPageDelay*500);
|
||||
CycleSkip = 0;
|
||||
ClearAndRestartStopWatch();
|
||||
CycleSeconds = ((60*EEPROMConfigSD[0]) + EEPROMConfigSD[1]);
|
||||
while(MyStopWatch.elapsed() < CycleSeconds & !EStop & !CycleSkip){
|
||||
for(DriveLoop = RotationMinDriveSpeed ; DriveLoop < MaxDriveSpeed ; DriveLoop = DriveLoop + ((EEPROMConfigSD[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigSD[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( ; DriveLoop > RotationMinDriveSpeed ; DriveLoop = DriveLoop - ((EEPROMConfigSD[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigSD[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
SoftStopMotor(1); //Stops Motor 1, rotation motor
|
||||
|
||||
//Rinse Cycle
|
||||
if(!EStop){
|
||||
FullLcdWrite((unsigned char*)" Starting ",(unsigned char*)" Rinse Cycle ");
|
||||
delay(LcdPageDelay*500);
|
||||
CycleSkip = 0;
|
||||
ClearAndRestartStopWatch();
|
||||
CycleSeconds = ((60*EEPROMConfigSD[2]) + EEPROMConfigSD[3]);
|
||||
|
||||
for(DriveLoop = PumpMinDriveSpeed ; DriveLoop < PumpMaxDriveSpeed ; DriveLoop = DriveLoop + (((EEPROMConfigSD[9]/4)*MaxPumpRampValue)/100)){
|
||||
MotorDriver.setM2Speed((EEPROMConfigSD[8]*DriveLoop)/100);
|
||||
delay(250);
|
||||
}
|
||||
MotorDriver.setM2Speed((EEPROMConfigSD[8]*PumpMaxDriveSpeed)/100);
|
||||
}
|
||||
while(MyStopWatch.elapsed() < CycleSeconds & !EStop & !CycleSkip){
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SoftStopMotor(2);
|
||||
|
||||
//Pronase Cycle 2
|
||||
if(!EStop){
|
||||
FullLcdWrite((unsigned char*)" Starting ",(unsigned char*)"Pronase Cycle 2 ");
|
||||
delay(LcdPageDelay*500);
|
||||
CycleSkip = 0;
|
||||
ClearAndRestartStopWatch();
|
||||
CycleSeconds = ((60*EEPROMConfigSD[4]) + EEPROMConfigSD[5]);
|
||||
}
|
||||
while(MyStopWatch.elapsed() < CycleSeconds & !EStop & !CycleSkip){
|
||||
for(DriveLoop = RotationMinDriveSpeed ; DriveLoop < MaxDriveSpeed ; DriveLoop = DriveLoop + ((EEPROMConfigSD[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigSD[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( ; DriveLoop > RotationMinDriveSpeed ; DriveLoop = DriveLoop - ((EEPROMConfigSD[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigSD[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
SoftStopMotor(1); //Stops Motor 1, rotation motor
|
||||
|
||||
|
||||
EStop = 0;
|
||||
GoToProgramSelection();
|
||||
break;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
case TwoFourDechorionation:
|
||||
|
||||
EStop = 0;
|
||||
|
||||
//Pronase Cycle 1
|
||||
FullLcdWrite((unsigned char*)" Starting ",(unsigned char*)"Pronase Cycle 1 ");
|
||||
delay(LcdPageDelay*500);
|
||||
CycleSkip = 0;
|
||||
ClearAndRestartStopWatch();
|
||||
CycleSeconds = ((60*EEPROMConfigTF[0]) + EEPROMConfigTF[1]);
|
||||
while(MyStopWatch.elapsed() < CycleSeconds & !EStop & !CycleSkip){
|
||||
for(DriveLoop = RotationMinDriveSpeed ; DriveLoop < MaxDriveSpeed ; DriveLoop = DriveLoop + ((EEPROMConfigTF[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigTF[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( ; DriveLoop > RotationMinDriveSpeed ; DriveLoop = DriveLoop - ((EEPROMConfigTF[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigTF[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
SoftStopMotor(1); //Stops Motor 1, rotation motor
|
||||
|
||||
//Rinse Cycle
|
||||
if(!EStop){
|
||||
FullLcdWrite((unsigned char*)" Starting ",(unsigned char*)" Rinse Cycle ");
|
||||
delay(LcdPageDelay*500);
|
||||
CycleSkip = 0;
|
||||
ClearAndRestartStopWatch();
|
||||
CycleSeconds = ((60*EEPROMConfigTF[2]) + EEPROMConfigTF[3]);
|
||||
|
||||
for(DriveLoop = PumpMinDriveSpeed ; DriveLoop < PumpMaxDriveSpeed ; DriveLoop = DriveLoop + ((EEPROMConfigTF[9]*MaxPumpRampValue)/100)){
|
||||
MotorDriver.setM2Speed((EEPROMConfigTF[8]*DriveLoop)/100);
|
||||
}
|
||||
MotorDriver.setM2Speed((EEPROMConfigTF[8]*PumpMaxDriveSpeed)/100);
|
||||
}
|
||||
while(MyStopWatch.elapsed() < CycleSeconds & !EStop & !CycleSkip){
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SoftStopMotor(2);
|
||||
|
||||
//Pronase Cycle 2
|
||||
if(!EStop){
|
||||
FullLcdWrite((unsigned char*)" Starting ",(unsigned char*)"Pronase Cycle 2 ");
|
||||
delay(LcdPageDelay*500);
|
||||
CycleSkip = 0;
|
||||
ClearAndRestartStopWatch();
|
||||
CycleSeconds = ((60*EEPROMConfigTF[4]) + EEPROMConfigTF[5]);
|
||||
}
|
||||
while(MyStopWatch.elapsed() < CycleSeconds & !EStop & !CycleSkip){
|
||||
for(DriveLoop = RotationMinDriveSpeed ; DriveLoop < MaxDriveSpeed ; DriveLoop = DriveLoop + ((EEPROMConfigTF[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigTF[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( ; DriveLoop > RotationMinDriveSpeed ; DriveLoop = DriveLoop - ((EEPROMConfigTF[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigTF[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
SoftStopMotor(1); //Stops Motor 1, rotation motor
|
||||
|
||||
|
||||
EStop = 0;
|
||||
GoToProgramSelection();
|
||||
break;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
case PronaseAndRinse:
|
||||
EStop = 0;
|
||||
|
||||
//Pronase Cycle 1
|
||||
FullLcdWrite((unsigned char*)" Starting ",(unsigned char*)"Pronase Cycle 1 ");
|
||||
delay(LcdPageDelay*500);
|
||||
CycleSkip = 0;
|
||||
ClearAndRestartStopWatch();
|
||||
CycleSeconds = ((60*EEPROMConfigPnR[0]) + EEPROMConfigPnR[1]);
|
||||
while(MyStopWatch.elapsed() < CycleSeconds & !EStop & !CycleSkip){
|
||||
for(DriveLoop = RotationMinDriveSpeed ; DriveLoop < MaxDriveSpeed ; DriveLoop = DriveLoop + ((EEPROMConfigPnR[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigPnR[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( ; DriveLoop > RotationMinDriveSpeed ; DriveLoop = DriveLoop - ((EEPROMConfigPnR[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigPnR[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
SoftStopMotor(1); //Stops Motor 1, rotation motor
|
||||
|
||||
//Rinse Cycle
|
||||
if(!EStop){
|
||||
FullLcdWrite((unsigned char*)" Starting ",(unsigned char*)" Rinse Cycle ");
|
||||
delay(LcdPageDelay*500);
|
||||
CycleSkip = 0;
|
||||
ClearAndRestartStopWatch();
|
||||
CycleSeconds = ((60*EEPROMConfigPnR[2]) + EEPROMConfigPnR[3]);
|
||||
|
||||
for(DriveLoop = PumpMinDriveSpeed ; DriveLoop < PumpMaxDriveSpeed ; DriveLoop = DriveLoop + ((EEPROMConfigPnR[9]*MaxPumpRampValue)/100)){
|
||||
MotorDriver.setM2Speed((EEPROMConfigPnR[8]*DriveLoop)/100);
|
||||
}
|
||||
MotorDriver.setM2Speed((EEPROMConfigPnR[8]*PumpMaxDriveSpeed)/100);
|
||||
}
|
||||
while(MyStopWatch.elapsed() < CycleSeconds & !EStop & !CycleSkip){
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SoftStopMotor(2);
|
||||
|
||||
//Pronase Cycle 2
|
||||
if(!EStop){
|
||||
FullLcdWrite((unsigned char*)" Starting ",(unsigned char*)"Pronase Cycle 2 ");
|
||||
delay(LcdPageDelay*500);
|
||||
CycleSkip = 0;
|
||||
ClearAndRestartStopWatch();
|
||||
CycleSeconds = ((60*EEPROMConfigPnR[4]) + EEPROMConfigPnR[5]);
|
||||
}
|
||||
while(MyStopWatch.elapsed() < CycleSeconds & !EStop & !CycleSkip){
|
||||
for(DriveLoop = RotationMinDriveSpeed ; DriveLoop < MaxDriveSpeed ; DriveLoop = DriveLoop + ((EEPROMConfigPnR[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigPnR[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( ; DriveLoop > RotationMinDriveSpeed ; DriveLoop = DriveLoop - ((EEPROMConfigPnR[7]*MaxRampValue)/100)){
|
||||
MotorDriver.setM1Speed((DriveLoop * EEPROMConfigPnR[6])/100);
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
SoftStopMotor(1); //Stops Motor 1, rotation motor
|
||||
|
||||
|
||||
EStop = 0;
|
||||
GoToProgramSelection();
|
||||
break;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
case RinseOnly:
|
||||
EStop = 0;
|
||||
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
FullLcdWrite((unsigned char*)" Starting ",(unsigned char*)" Rinse Cycle ");
|
||||
|
||||
if(!EStop){
|
||||
delay(LcdPageDelay*500);
|
||||
CycleSkip = 0;
|
||||
ClearAndRestartStopWatch();
|
||||
CycleSeconds = ((60*EEPROMConfigRO[0]) + EEPROMConfigRO[1]);
|
||||
|
||||
for(DriveLoop = PumpMinDriveSpeed ; DriveLoop < PumpMaxDriveSpeed ; DriveLoop = DriveLoop + ((EEPROMConfigRO[3]*MaxPumpRampValue)/100)){
|
||||
MotorDriver.setM2Speed((EEPROMConfigRO[2]*DriveLoop)/100);
|
||||
}
|
||||
MotorDriver.setM2Speed((EEPROMConfigRO[8]*PumpMaxDriveSpeed)/100);
|
||||
}
|
||||
while(MyStopWatch.elapsed() < CycleSeconds & !EStop & !CycleSkip){
|
||||
LcdFullWriteString((unsigned char*)" Time Remaining ",(" " + String((CycleSeconds - MyStopWatch.elapsed()), DEC) + " "));
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
SoftStopMotor(1);
|
||||
GoToProgramSelection();
|
||||
EStop = 1;
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
CycleSkip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SoftStopMotor(2);
|
||||
|
||||
EStop = 0;
|
||||
GoToProgramSelection();
|
||||
break;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
case SDConfig:
|
||||
ClearAndRestartStopWatch();;
|
||||
|
||||
while(MyStopWatch.elapsed() < (ConfigPageTimeout)){
|
||||
if(PreviousConfig != SelectedConfig ){
|
||||
ClearAndRestartStopWatch();
|
||||
|
||||
}
|
||||
|
||||
ShowSDConfigMainScreen();
|
||||
if(digitalRead(EncoderButton) == LOW){
|
||||
MyStopWatch.stop();
|
||||
delay(DebounceTimeout);
|
||||
PrevVal = NewVal = (int)EEPROMConfigSD[SelectedConfig];
|
||||
ConfigVal = " " + String(NewVal, DEC) + " ";
|
||||
ShowSDConfigIndividualConfigScreen();
|
||||
while(digitalRead(EncoderButton) == HIGH){
|
||||
NewVal = SDConfigIndividualConstrain(NewVal + ReturnEncoderDirection());
|
||||
if(NewVal != PrevVal){
|
||||
PrevVal = NewVal;
|
||||
ConfigVal = " " + String(NewVal, DEC) + " ";
|
||||
ShowSDConfigIndividualConfigScreen();
|
||||
}
|
||||
}
|
||||
EEPROMConfigSD[SelectedConfig] = NewVal;
|
||||
delay(DebounceTimeout);
|
||||
ClearAndRestartStopWatch();
|
||||
|
||||
}
|
||||
PreviousConfig = SelectedConfig;
|
||||
SelectedConfig = SDConfigMainConstrain(SelectedConfig += ReturnEncoderDirection());
|
||||
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
GoToProgramSelection();
|
||||
SDConfigSaveToEEPROM();
|
||||
LcdWriteSavingScreen();
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
GoToProgramSelection();
|
||||
break;
|
||||
}
|
||||
}
|
||||
GoToProgramSelection();
|
||||
|
||||
break;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
case TFConfig:
|
||||
ClearAndRestartStopWatch();
|
||||
|
||||
while(MyStopWatch.elapsed() < (ConfigPageTimeout)){
|
||||
if(PreviousConfig != SelectedConfig ){
|
||||
ClearAndRestartStopWatch();
|
||||
|
||||
}
|
||||
|
||||
ShowTFConfigMainScreen();
|
||||
if(digitalRead(EncoderButton) == LOW){
|
||||
MyStopWatch.stop();
|
||||
delay(DebounceTimeout);
|
||||
PrevVal = NewVal = (int)EEPROMConfigTF[SelectedConfig];
|
||||
ConfigVal = " " + String(NewVal, DEC) + " ";
|
||||
ShowTFConfigIndividualConfigScreen();
|
||||
while(digitalRead(EncoderButton) == HIGH){
|
||||
NewVal = TFConfigIndividualConstrain(NewVal + ReturnEncoderDirection());
|
||||
if(NewVal != PrevVal){
|
||||
PrevVal = NewVal;
|
||||
ConfigVal = " " + String(NewVal, DEC) + " ";
|
||||
ShowTFConfigIndividualConfigScreen();
|
||||
}
|
||||
}
|
||||
EEPROMConfigTF[SelectedConfig] = NewVal;
|
||||
delay(DebounceTimeout);
|
||||
ClearAndRestartStopWatch();
|
||||
|
||||
}
|
||||
PreviousConfig = SelectedConfig;
|
||||
SelectedConfig = TFConfigMainConstrain(SelectedConfig += ReturnEncoderDirection());
|
||||
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
GoToProgramSelection();
|
||||
TFConfigSaveToEEPROM();
|
||||
LcdWriteSavingScreen();
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
GoToProgramSelection();
|
||||
break;
|
||||
}
|
||||
}
|
||||
GoToProgramSelection();
|
||||
|
||||
break;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
case PnRConfig:
|
||||
ClearAndRestartStopWatch();
|
||||
|
||||
while(MyStopWatch.elapsed() < (ConfigPageTimeout)){
|
||||
if(PreviousConfig != SelectedConfig ){
|
||||
ClearAndRestartStopWatch();
|
||||
|
||||
}
|
||||
|
||||
ShowPnRConfigMainScreen();
|
||||
if(digitalRead(EncoderButton) == LOW){
|
||||
MyStopWatch.stop();
|
||||
delay(DebounceTimeout);
|
||||
PrevVal = NewVal = (int)EEPROMConfigPnR[SelectedConfig];
|
||||
ConfigVal = " " + String(NewVal, DEC) + " ";
|
||||
ShowPnRConfigIndividualConfigScreen();
|
||||
while(digitalRead(EncoderButton) == HIGH){
|
||||
NewVal = PnRConfigIndividualConstrain(NewVal + ReturnEncoderDirection());
|
||||
if(NewVal != PrevVal){
|
||||
PrevVal = NewVal;
|
||||
ConfigVal = " " + String(NewVal, DEC) + " ";
|
||||
ShowPnRConfigIndividualConfigScreen();
|
||||
}
|
||||
}
|
||||
EEPROMConfigPnR[SelectedConfig] = NewVal;
|
||||
delay(DebounceTimeout);
|
||||
ClearAndRestartStopWatch();
|
||||
|
||||
}
|
||||
PreviousConfig = SelectedConfig;
|
||||
SelectedConfig = PnRConfigMainConstrain(SelectedConfig += ReturnEncoderDirection());
|
||||
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
GoToProgramSelection();
|
||||
PnRConfigSaveToEEPROM();
|
||||
LcdWriteSavingScreen();
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
GoToProgramSelection();
|
||||
break;
|
||||
}
|
||||
}
|
||||
GoToProgramSelection();
|
||||
|
||||
break;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
case ROConfig:
|
||||
ClearAndRestartStopWatch();
|
||||
|
||||
while(MyStopWatch.elapsed() < (ConfigPageTimeout)){
|
||||
if(PreviousConfig != SelectedConfig ){
|
||||
ClearAndRestartStopWatch();
|
||||
|
||||
}
|
||||
|
||||
ShowROConfigMainScreen();
|
||||
if(digitalRead(EncoderButton) == LOW){
|
||||
MyStopWatch.stop();
|
||||
delay(DebounceTimeout);
|
||||
PrevVal = NewVal = (int)EEPROMConfigRO[SelectedConfig];
|
||||
ConfigVal = " " + String(NewVal, DEC) + " ";
|
||||
ShowROConfigIndividualConfigScreen();
|
||||
while(digitalRead(EncoderButton) == HIGH){
|
||||
NewVal = ROConfigIndividualConstrain(NewVal + ReturnEncoderDirection());
|
||||
if(NewVal != PrevVal){
|
||||
PrevVal = NewVal;
|
||||
ConfigVal = " " + String(NewVal, DEC) + " ";
|
||||
ShowROConfigIndividualConfigScreen();
|
||||
}
|
||||
}
|
||||
EEPROMConfigRO[SelectedConfig] = NewVal;
|
||||
delay(DebounceTimeout);
|
||||
ClearAndRestartStopWatch();
|
||||
|
||||
}
|
||||
PreviousConfig = SelectedConfig;
|
||||
SelectedConfig = ROConfigMainConstrain(SelectedConfig += ReturnEncoderDirection());
|
||||
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
GoToProgramSelection();
|
||||
ROConfigSaveToEEPROM();
|
||||
LcdWriteSavingScreen();
|
||||
break;
|
||||
}
|
||||
if(digitalRead(StopSwitch) == LOW){
|
||||
GoToProgramSelection();
|
||||
break;
|
||||
}
|
||||
}
|
||||
GoToProgramSelection();
|
||||
break;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
default:
|
||||
FullLcdWrite((unsigned char*)"Fatal Error ", (unsigned char*)"Contact Support ");
|
||||
while(1);
|
||||
break;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
void LcdMoveToTop(){
|
||||
LcdSerial.write(254); //Put LCD into move mode
|
||||
LcdSerial.write(128); //Move to the first character of the first row
|
||||
}
|
||||
|
||||
void LcdMoveToBottom(){
|
||||
LcdSerial.write(254); //Put LCD into move mode
|
||||
LcdSerial.write(192); //Move to the first character of the second row
|
||||
}
|
||||
|
||||
void FullLcdClear(){
|
||||
LcdSerial.write(254); //Send special command character
|
||||
LcdSerial.write(1); //Send Clear Screen Command
|
||||
}
|
||||
|
||||
void TopLcdClear(){
|
||||
LcdMoveToTop();
|
||||
LcdSerial.write(" "); //Write a blank 16 character string
|
||||
}
|
||||
|
||||
void BottomLcdClear(){
|
||||
LcdMoveToBottom();
|
||||
LcdSerial.write(" "); //Write a blank 16 character string
|
||||
}
|
||||
|
||||
void FullLcdWrite(unsigned char* TopLcd, unsigned char* BottomLcd){
|
||||
TopLcdWrite(TopLcd);
|
||||
BottomLcdWrite(BottomLcd);
|
||||
}
|
||||
|
||||
void TopLcdWrite(unsigned char *TopLcd){
|
||||
LcdMoveToTop();
|
||||
LcdSerial.write((const char*)TopLcd); //Write string
|
||||
|
||||
}
|
||||
|
||||
void BottomLcdWrite(unsigned char *BottomLcd){
|
||||
LcdMoveToBottom();
|
||||
LcdSerial.write((const char*)BottomLcd); //Write string
|
||||
}
|
||||
|
||||
void LcdFullWriteString(unsigned char* TopLcd, String BottomLcd){
|
||||
TopLcdWrite(TopLcd);
|
||||
LcdMoveToBottom();
|
||||
LcdSerial.print(BottomLcd);
|
||||
}
|
||||
|
||||
void LcdWriteSavingScreen(){
|
||||
FullLcdWrite((unsigned char*)" Settings Saved ",(unsigned char*)" Sucessfully ");
|
||||
delay(1500);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
void ReadFromEEPROM(){
|
||||
SDConfigLoadFromEEPROM();
|
||||
TFConfigLoadFromEEPROM();
|
||||
PnRConfigLoadFromEEPROM();
|
||||
ROConfigLoadFromEEPROM();
|
||||
}
|
||||
|
||||
void SaveToEEPROM(){
|
||||
SDConfigSaveToEEPROM();
|
||||
TFConfigSaveToEEPROM();
|
||||
PnRConfigSaveToEEPROM();
|
||||
ROConfigSaveToEEPROM();
|
||||
}
|
||||
|
||||
void DisplayProgramList(){
|
||||
FullLcdWrite((unsigned char*)pgm_read_word(&ProgramNames[SelectedProgram][0]), (unsigned char*)pgm_read_word(&ProgramNames[SelectedProgram][1]));
|
||||
}
|
||||
|
||||
void GetInitialEncoderData(){
|
||||
EncoderChannelALastValue = EncoderReferenceVariable = digitalRead(EncoderChannelA);
|
||||
}
|
||||
|
||||
signed char ReturnEncoderDirection(){
|
||||
EncoderReferenceVariable = digitalRead(EncoderChannelA);
|
||||
if((EncoderChannelALastValue == LOW) && (EncoderReferenceVariable == HIGH)){
|
||||
if(digitalRead(EncoderChannelB) == LOW){
|
||||
EncoderChannelALastValue = EncoderReferenceVariable;;
|
||||
return 1;
|
||||
}else{
|
||||
EncoderChannelALastValue = EncoderReferenceVariable;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
EncoderChannelALastValue = EncoderReferenceVariable;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ClearAndRestartStopWatch(){
|
||||
MyStopWatch.reset();
|
||||
MyStopWatch.start();
|
||||
}
|
||||
|
||||
void SoftStopMotor(unsigned char Motor){
|
||||
if(Motor == 1){
|
||||
for( ; DriveLoop != RotationMinDriveSpeed ; DriveLoop--){
|
||||
MotorDriver.setM1Speed(DriveLoop);
|
||||
}
|
||||
MotorDriver.setM1Speed(0);
|
||||
}
|
||||
else if(Motor == 2){
|
||||
for( ; DriveLoop != PumpMinDriveSpeed ; DriveLoop--){
|
||||
MotorDriver.setM2Speed(DriveLoop);
|
||||
}
|
||||
MotorDriver.setM2Speed(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
void ShowProgramListIntro(){
|
||||
FullLcdWrite((unsigned char*)"Select Program, ",(unsigned char*)"Press Start "); //Show the start screen
|
||||
delay(TitleTimeout* 1000); //Wait for three seconds
|
||||
FullLcdClear();
|
||||
DoneOnce = 1; //Set DoneOnce to 1 so we know it's been started for the first time
|
||||
EStop = 0;
|
||||
}
|
||||
|
||||
signed char ConstrainProgramList(signed char ProgramList){
|
||||
if(ProgramList == -1){
|
||||
return 3;
|
||||
}else if(ProgramList == 4){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char CheckConfigButton(){
|
||||
if(digitalRead(EncoderButton) == LOW){
|
||||
delay(DebounceTimeout);
|
||||
SelectedConfig = 0;
|
||||
ArduinoProgram = ArduinoPrograms((char)SelectedProgram + 4);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char CheckProgramStart(){
|
||||
if(digitalRead(StartSwitch) == LOW){
|
||||
ArduinoProgram = (ArduinoPrograms)SelectedProgram; //Change arduino program selector to the new one
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GoToProgramSelection(){
|
||||
delay(DebounceTimeout);
|
||||
ArduinoProgram = ProgramSelection;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
void ShowPnRConfigMainScreen(){
|
||||
FullLcdWrite((unsigned char*)pgm_read_word(&PronaseAndRinseConfig[SelectedConfig][0]), (unsigned char*)pgm_read_word(&PronaseAndRinseConfig[SelectedConfig][1]));
|
||||
}
|
||||
|
||||
void ShowPnRConfigIndividualConfigScreen(){
|
||||
LcdFullWriteString((unsigned char*)pgm_read_word(&PronaseAndRinseConfig[SelectedConfig][2]), ConfigVal);
|
||||
}
|
||||
|
||||
int PnRConfigMainConstrain(signed int Constrain){
|
||||
int Constraint = NumPnRConfig - 1;
|
||||
if(Constrain > Constraint){
|
||||
Constrain = (NumPnRConfig - 1);
|
||||
}else if(Constrain < 0){
|
||||
Constrain = 0;
|
||||
}
|
||||
return Constrain;
|
||||
}
|
||||
|
||||
int PnRConfigIndividualConstrain(signed int Constrain){
|
||||
int Constraint = (int)pgm_read_word(&PronaseAndRinseConfig[SelectedConfig][3]);
|
||||
if(Constrain > Constraint){
|
||||
Constrain = (int)pgm_read_word(&PronaseAndRinseConfig[SelectedConfig][3]);
|
||||
}else if(Constrain < 0){
|
||||
Constrain = 0;
|
||||
}
|
||||
return Constrain;
|
||||
}
|
||||
|
||||
void PnRConfigLoadFromEEPROM(){
|
||||
for(int i = 0 ; i < NumPnRConfig ; i++){
|
||||
EEPROMConfigPnR[i] = EEPROM.read(pgm_read_word(&PronaseAndRinseConfig[i][4]));
|
||||
}
|
||||
}
|
||||
|
||||
void PnRConfigSaveToEEPROM(){
|
||||
for(int i = 0 ; i < NumPnRConfig ; i++){
|
||||
EEPROM.write(pgm_read_word(&PronaseAndRinseConfig[i][4]),EEPROMConfigPnR[i]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
void ShowROConfigMainScreen(){
|
||||
FullLcdWrite((unsigned char*)pgm_read_word(&RinseOnlyConfig[SelectedConfig][0]), (unsigned char*)pgm_read_word(&RinseOnlyConfig[SelectedConfig][1]));
|
||||
}
|
||||
|
||||
void ShowROConfigIndividualConfigScreen(){
|
||||
LcdFullWriteString((unsigned char*)pgm_read_word(&RinseOnlyConfig[SelectedConfig][2]), ConfigVal);
|
||||
}
|
||||
|
||||
int ROConfigMainConstrain(signed int Constrain){
|
||||
int Constraint = NumROConfig - 1;
|
||||
if(Constrain > Constraint){
|
||||
Constrain = (NumROConfig - 1);
|
||||
}else if(Constrain < 0){
|
||||
Constrain = 0;
|
||||
}
|
||||
return Constrain;
|
||||
}
|
||||
|
||||
int ROConfigIndividualConstrain(signed int Constrain){
|
||||
int Constraint = (int)pgm_read_word(&RinseOnlyConfig[SelectedConfig][3]);
|
||||
if(Constrain > Constraint){
|
||||
Constrain = (int)pgm_read_word(&RinseOnlyConfig[SelectedConfig][3]);
|
||||
}else if(Constrain < 0){
|
||||
Constrain = 0;
|
||||
}
|
||||
return Constrain;
|
||||
}
|
||||
|
||||
void ROConfigLoadFromEEPROM(){
|
||||
for(int i = 0 ; i < NumROConfig ; i++){
|
||||
EEPROMConfigRO[i] = EEPROM.read(pgm_read_word(&RinseOnlyConfig[i][4]));
|
||||
}
|
||||
}
|
||||
|
||||
void ROConfigSaveToEEPROM(){
|
||||
for(int i = 0 ; i < NumROConfig ; i++){
|
||||
EEPROM.write(pgm_read_word(&RinseOnlyConfig[i][4]),EEPROMConfigRO[i]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
void InitializePins(){
|
||||
pinMode(StartSwitch, INPUT); //Set Start Switch Pin to Input
|
||||
pinMode(StopSwitch, INPUT); //Set Stop Switch Pin to Input
|
||||
digitalWrite(StartSwitch, HIGH); //Set the internal pullup resistor for the switch
|
||||
digitalWrite(StopSwitch, HIGH); //Set the internal pullup resistor for the switch
|
||||
|
||||
pinMode(EncoderLed, OUTPUT); //Set LED Pin to Output
|
||||
pinMode(EncoderButton, INPUT); //Set Encoder Button Pin to Input
|
||||
pinMode(EncoderChannelA, INPUT); //Set Encoder Channel A Pin to Input
|
||||
pinMode(EncoderChannelB, INPUT); //Set Encoder Channel B Pin to Input
|
||||
digitalWrite(EncoderLed, HIGH);
|
||||
digitalWrite(EncoderButton, HIGH); //Set the internal pullup resistor for the switch
|
||||
digitalWrite(EncoderChannelA, HIGH); //Set the internal pullup resistor for the switch
|
||||
digitalWrite(EncoderChannelB, HIGH); //Set the internal pullup resistor for the switch
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Program Functions////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Config Functions/////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void ShowSDConfigMainScreen(){
|
||||
FullLcdWrite((unsigned char*)pgm_read_word(&StandardDechorionationConfig[SelectedConfig][0]), (unsigned char*)pgm_read_word(&StandardDechorionationConfig[SelectedConfig][1]));
|
||||
}
|
||||
|
||||
void ShowSDConfigIndividualConfigScreen(){
|
||||
LcdFullWriteString((unsigned char*)pgm_read_word(&StandardDechorionationConfig[SelectedConfig][2]), ConfigVal);
|
||||
}
|
||||
|
||||
int SDConfigMainConstrain(signed int Constrain){
|
||||
int Constraint = NumSDConfig - 1;
|
||||
if(Constrain > Constraint){
|
||||
Constrain = (NumSDConfig - 1);
|
||||
}else if(Constrain < 0){
|
||||
Constrain = 0;
|
||||
}
|
||||
return Constrain;
|
||||
}
|
||||
|
||||
int SDConfigIndividualConstrain(signed int Constrain){
|
||||
int Constraint = (int)pgm_read_word(&StandardDechorionationConfig[SelectedConfig][3]);
|
||||
if(Constrain > Constraint){
|
||||
Constrain = (int)pgm_read_word(&StandardDechorionationConfig[SelectedConfig][3]);
|
||||
}else if(Constrain < 0){
|
||||
Constrain = 0;
|
||||
}
|
||||
return Constrain;
|
||||
}
|
||||
|
||||
void SDConfigLoadFromEEPROM(){
|
||||
for(int i = 0 ; i < NumSDConfig ; i++){
|
||||
EEPROMConfigSD[i] = EEPROM.read(pgm_read_word(&StandardDechorionationConfig[i][4]));
|
||||
}
|
||||
}
|
||||
|
||||
void SDConfigSaveToEEPROM(){
|
||||
for(int i = 0 ; i < NumSDConfig ; i++){
|
||||
EEPROM.write(pgm_read_word(&StandardDechorionationConfig[i][4]),EEPROMConfigSD[i]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
void ShowTFConfigMainScreen(){
|
||||
FullLcdWrite((unsigned char*)pgm_read_word(&TwoFourDechorionationConfig[SelectedConfig][0]), (unsigned char*)pgm_read_word(&TwoFourDechorionationConfig[SelectedConfig][1]));
|
||||
}
|
||||
|
||||
void ShowTFConfigIndividualConfigScreen(){
|
||||
LcdFullWriteString((unsigned char*)pgm_read_word(&TwoFourDechorionationConfig[SelectedConfig][2]), ConfigVal);
|
||||
}
|
||||
|
||||
int TFConfigMainConstrain(signed int Constrain){
|
||||
int Constraint = NumTFConfig - 1;
|
||||
if(Constrain > Constraint){
|
||||
Constrain = (NumTFConfig - 1);
|
||||
}else if(Constrain < 0){
|
||||
Constrain = 0;
|
||||
}
|
||||
return Constrain;
|
||||
}
|
||||
|
||||
int TFConfigIndividualConstrain(signed int Constrain){
|
||||
int Constraint = (int)pgm_read_word(&TwoFourDechorionationConfig[SelectedConfig][3]);
|
||||
if(Constrain > Constraint){
|
||||
Constrain = (int)pgm_read_word(&TwoFourDechorionationConfig[SelectedConfig][3]);
|
||||
}else if(Constrain < 0){
|
||||
Constrain = 0;
|
||||
}
|
||||
return Constrain;
|
||||
}
|
||||
|
||||
void TFConfigLoadFromEEPROM(){
|
||||
for(int i = 0 ; i < NumTFConfig ; i++){
|
||||
EEPROMConfigTF[i] = EEPROM.read(pgm_read_word(&TwoFourDechorionationConfig[i][4]));
|
||||
}
|
||||
}
|
||||
|
||||
void TFConfigSaveToEEPROM(){
|
||||
for(int i = 0 ; i < NumTFConfig ; i++){
|
||||
EEPROM.write(pgm_read_word(&TwoFourDechorionationConfig[i][4]),EEPROMConfigTF[i]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,528 @@
|
||||
#LyX 2.0 created this file. For more info see http://www.lyx.org/
|
||||
\lyxformat 413
|
||||
\begin_document
|
||||
\begin_header
|
||||
\textclass article
|
||||
\use_default_options true
|
||||
\maintain_unincluded_children false
|
||||
\language english
|
||||
\language_package default
|
||||
\inputencoding auto
|
||||
\fontencoding global
|
||||
\font_roman default
|
||||
\font_sans default
|
||||
\font_typewriter default
|
||||
\font_default_family default
|
||||
\use_non_tex_fonts false
|
||||
\font_sc false
|
||||
\font_osf false
|
||||
\font_sf_scale 100
|
||||
\font_tt_scale 100
|
||||
|
||||
\graphics default
|
||||
\default_output_format default
|
||||
\output_sync 0
|
||||
\bibtex_command default
|
||||
\index_command default
|
||||
\paperfontsize default
|
||||
\spacing single
|
||||
\use_hyperref false
|
||||
\papersize default
|
||||
\use_geometry false
|
||||
\use_amsmath 1
|
||||
\use_esint 1
|
||||
\use_mhchem 1
|
||||
\use_mathdots 1
|
||||
\cite_engine basic
|
||||
\use_bibtopic false
|
||||
\use_indices false
|
||||
\paperorientation portrait
|
||||
\suppress_date true
|
||||
\use_refstyle 1
|
||||
\index Index
|
||||
\shortcut idx
|
||||
\color #008000
|
||||
\end_index
|
||||
\secnumdepth 3
|
||||
\tocdepth 3
|
||||
\paragraph_separation indent
|
||||
\paragraph_indentation default
|
||||
\quotes_language english
|
||||
\papercolumns 1
|
||||
\papersides 1
|
||||
\paperpagestyle default
|
||||
\tracking_changes false
|
||||
\output_changes false
|
||||
\html_math_output 0
|
||||
\html_css_as_file 0
|
||||
\html_be_strict false
|
||||
\end_header
|
||||
|
||||
\begin_body
|
||||
|
||||
\begin_layout Title
|
||||
|
||||
\series bold
|
||||
Dechorionation Table User Manual - Draft
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
\align center
|
||||
Sinhubber Aquatic Research Laboratory
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
\align center
|
||||
Oregon State University
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
\align center
|
||||
Corwin Perren
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
\begin_inset Newpage pagebreak
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Part*
|
||||
Firmware Rev 1.0
|
||||
\end_layout
|
||||
|
||||
\begin_layout Section*
|
||||
Using the Dechorionator
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Turn on the Dechorionator using the power switch located on the rear of
|
||||
the unit.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Wait until the device has finished powering up and shows the program selection
|
||||
screen.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rotate the selection knob until the desired program is shown.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Press the green start button to begin the program.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
To skip a particular cycle in a program, press the start button.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Press the stop button at any time to immediately end the currently running
|
||||
program and return to the selection screen.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Section*
|
||||
Changing Settings
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rotate the selection knob until the program containing the settings you
|
||||
would like to modify is shown.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Press the knob to enter the settings editor for that program.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rotate the selection knob until the setting you would like to change is
|
||||
shown.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Press the knob to enter the setting's edit screen.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rotate the selection knob until the desired value is displayed.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Press the knob to save the new value and return to the settings selection
|
||||
screen.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Repeat for any other settings you would like to change for the selected
|
||||
program.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Saving Settings
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Save settings temporarily (Does not persist through reboots).
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Return to the settings selection screen.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Press the stop button or wait for a few seconds for it to timeout.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
You will be returned to the main program selection screen and any modified
|
||||
settings will be applied until a reboot.
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
Save settings permanently (Settings will persist through reboots).
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Return to the settings selection screen.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Press the start button.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
Settings Saved Sucessfully
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
should display breifly before returning to the main program selection screen.
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\end_deeper
|
||||
\begin_layout Section*
|
||||
Program Cycle Information and Settings Defaults
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
\shape italic
|
||||
Note that cycles are in order and motor settings apply to all cycles for
|
||||
a given program.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection*
|
||||
Standard Dechorionation Cycles
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 1
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 1 - Minutes :
|
||||
\series bold
|
||||
6
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 1 - Seconds :
|
||||
\series bold
|
||||
30
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle - Minutes :
|
||||
\series bold
|
||||
1
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle - Seconds :
|
||||
\series bold
|
||||
0
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 2
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 2 - Minutes :
|
||||
\series bold
|
||||
10
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 2 - Seconds :
|
||||
\series bold
|
||||
0
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
Motor Settings
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Rotation Speed - Percentage :
|
||||
\series bold
|
||||
85
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rotation Ramping Percentage :
|
||||
\series bold
|
||||
85
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pump Speed :
|
||||
\series bold
|
||||
50
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pump ramp :
|
||||
\series bold
|
||||
85
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Subsubsection*
|
||||
24 Hour Dechorionation Cycles
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 1
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 1 - Minutes :
|
||||
\series bold
|
||||
3
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 1 - Seconds :
|
||||
\series bold
|
||||
0
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle - Minutes :
|
||||
\series bold
|
||||
1
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle - Seconds :
|
||||
\series bold
|
||||
0
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 2
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 2 - Minutes :
|
||||
\series bold
|
||||
10
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 2 - Seconds :
|
||||
\series bold
|
||||
0
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
Motor Settings
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Rotation Speed - Percentage :
|
||||
\series bold
|
||||
85
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rotation Ramping Percentage :
|
||||
\series bold
|
||||
85
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pump Speed :
|
||||
\series bold
|
||||
50
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pump ramp :
|
||||
\series bold
|
||||
85
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Subsubsection*
|
||||
6 Hour HPF Dechorionation Cycles
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 1
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 1 - Minutes :
|
||||
\series bold
|
||||
6
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 1 - Seconds :
|
||||
\series bold
|
||||
30
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle - Minutes :
|
||||
\series bold
|
||||
1
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle - Seconds :
|
||||
\series bold
|
||||
0
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 2
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 2 - Minutes :
|
||||
\series bold
|
||||
10
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pronase Cycle 2 - Seconds :
|
||||
\series bold
|
||||
0
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
Motor Settings
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Rotation Speed - Percentage :
|
||||
\series bold
|
||||
85
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rotation Ramping Percentage :
|
||||
\series bold
|
||||
85
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pump Speed :
|
||||
\series bold
|
||||
50
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pump ramp :
|
||||
\series bold
|
||||
85
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Subsubsection*
|
||||
Rinse Cycle
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle - Minutes :
|
||||
\series bold
|
||||
1
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Rinse Cycle - Seconds :
|
||||
\series bold
|
||||
0
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\begin_layout Enumerate
|
||||
Motor Settings
|
||||
\end_layout
|
||||
|
||||
\begin_deeper
|
||||
\begin_layout Enumerate
|
||||
Pump Speed :
|
||||
\series bold
|
||||
50
|
||||
\end_layout
|
||||
|
||||
\begin_layout Enumerate
|
||||
Pump ramp :
|
||||
\series bold
|
||||
85
|
||||
\end_layout
|
||||
|
||||
\end_deeper
|
||||
\end_body
|
||||
\end_document
|
||||
@@ -0,0 +1,134 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Includes, Defines, Instantiations, and Global Variables//////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Includes
|
||||
#include "DualVNH5019MotorShield.h"
|
||||
#include <SoftwareSerial.h>
|
||||
#include <StopWatch.h>
|
||||
|
||||
//Pin Definitions (Arduino Suggested Method)
|
||||
const unsigned char LcdTX = 5; //Pin connected to LCD RX Line
|
||||
const unsigned char LedGreen = A2; //Pin connected to rotary encoder led
|
||||
const unsigned char LedRed = A3; //Pin connected to rotary encoder led
|
||||
|
||||
|
||||
const unsigned char StartSwitch = 11; //Pin connected to start switch
|
||||
const unsigned char StopSwitch = 13; //Pin connected to stop switch
|
||||
|
||||
const unsigned char EncoderChannelA = A4; //Pin connected to channel A of the rotary encoder
|
||||
const unsigned char EncoderChannelB = A5; //Pin connected to channel B of the rotary encoder
|
||||
|
||||
//Instantiations
|
||||
SoftwareSerial LcdSerial(3, LcdTX); //Software Serial Instantiation with Pin 3 as dummy for RX
|
||||
DualVNH5019MotorShield MotorDriver; //Motor Driver Library Instantiation
|
||||
StopWatch MyStopWatch(StopWatch::SECONDS); //StopWatch Instantiation for measuring time
|
||||
|
||||
enum ArduinoStates{ //Enumeration for defining the arduino program states
|
||||
WaitToStart,
|
||||
ChangeConfig,
|
||||
MainProg
|
||||
} ArduinoState = WaitToStart;
|
||||
|
||||
//Global Variables and Constants
|
||||
unsigned char DoneOnce = 0; //Variable to store whether something has happened or not.
|
||||
|
||||
const unsigned int LcdPageDelay = 2; //Seconds to wait before the lcd changes pages.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Arduino Setup////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setup(){
|
||||
MotorDriver.init(); //Initialize the VNH5019 Motor Driving Shield
|
||||
InitializePins(); //Initialize pins for switches, rotary encoder, and leds
|
||||
|
||||
Serial.begin(115200); //Start communicating to PC at 115200 baud
|
||||
|
||||
LcdSerial.begin(9600); //Start communicating with LCD dispaly at 9600 buad
|
||||
FullLcdClear();
|
||||
FullLcdWrite("Tanguay Labs", "Dechlorinator"); //Show the device name
|
||||
Serial.print("Dechlorinator Initialized");
|
||||
delay(5000); //Wait on name screen for five seconds
|
||||
FullLcdClear(); //Clear the LCD
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Main Arduino Program Loop////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void loop(){
|
||||
switch(ArduinoState){
|
||||
case WaitToStart:
|
||||
if(DoneOnce != 1){ //Check to see if the stopwatch needs to be started
|
||||
MyStopWatch.reset(); //Reset the stopwatch
|
||||
MyStopWatch.start(); //Start the stopwatch
|
||||
DoneOnce = 1; //Set DoneOnce to 1 so we know it's been started for the first time
|
||||
}
|
||||
|
||||
if(MyStopWatch.elapsed() < LcdPageDelay){ //Check if the time on the stopwatch is longer than our page delay
|
||||
FullLcdWrite(" Press Start To "," Begin "); //Show the start screen
|
||||
}else{ //If the time is over the page delay, switch to the config info screen
|
||||
FullLcdWrite(" Press Knob To ","Change Settings "); //Show the config info screen
|
||||
if(MyStopWatch.elapsed() > (2 * LcdPageDelay)){ //Check to see if the time is longer than two page delays
|
||||
MyStopWatch.reset(); //Reset the stopwatch to 0
|
||||
MyStopWatch.start(); //Start the stopwatch again
|
||||
}
|
||||
}
|
||||
|
||||
if(digitalRead(StartSwitch) == 0){ //Check to see if start button has been pressed
|
||||
ArduinoState = MainProg; //Switch to the main dechlorinator program
|
||||
}
|
||||
|
||||
if(digitalRead(StartSwitch) == 0){ //Check to see if start button has been pressed
|
||||
ArduinoState = MainProg; //Switch to the main dechlorinator program
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
/*
|
||||
lcdSerial.write(254);
|
||||
lcdSerial.write(128);
|
||||
lcdSerial.write("Press Start");
|
||||
lcdSerial.write(254);
|
||||
lcdSerial.write(192);
|
||||
lcdSerial.print("To Begin");
|
||||
if(digitalRead(11) == 0){
|
||||
for (int i = 0; i <= 400; i++)
|
||||
{
|
||||
md.setM1Speed(i);
|
||||
if (i%200 == 100)
|
||||
{
|
||||
Serial.print("M1 current: ");
|
||||
Serial.println(md.getM1CurrentMilliamps());
|
||||
lcdClear();
|
||||
lcdSerial.write(254);
|
||||
lcdSerial.write(128);
|
||||
lcdSerial.write("Motor 1 Current:");
|
||||
lcdSerial.write(254);
|
||||
lcdSerial.write(192);
|
||||
lcdSerial.print(md.getM1CurrentMilliamps());
|
||||
}
|
||||
delay(5);
|
||||
if(i == 400){
|
||||
while(1){
|
||||
Serial.print("M1 current: ");
|
||||
Serial.println(md.getM1CurrentMilliamps());
|
||||
lcdClear();
|
||||
lcdSerial.write(254);
|
||||
lcdSerial.write(128);
|
||||
lcdSerial.write("Motor 1 Current:");
|
||||
lcdSerial.write(254);
|
||||
lcdSerial.write(192);
|
||||
lcdSerial.print(md.getM1CurrentMilliamps());
|
||||
delay(100);
|
||||
if(digitalRead(3) == 0){
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
void LcdMoveToTop(){
|
||||
LcdSerial.write(254); //Put LCD into move mode
|
||||
LcdSerial.write(128); //Move to the first character of the first row
|
||||
}
|
||||
|
||||
void LcdMoveToBottom(){
|
||||
LcdSerial.write(254); //Put LCD into move mode
|
||||
LcdSerial.write(192); //Move to the first character of the second row
|
||||
}
|
||||
|
||||
void FullLcdClear(){
|
||||
LcdSerial.write(254); //Send special command character
|
||||
LcdSerial.write(1); //Send Clear Screen Command
|
||||
}
|
||||
|
||||
void TopLcdClear(){
|
||||
LcdMoveToTop();
|
||||
LcdSerial.write(" "); //Write a blank 16 character string
|
||||
}
|
||||
|
||||
void BottomLcdClear(){
|
||||
LcdMoveToBottom();
|
||||
LcdSerial.write(" "); //Write a blank 16 character string
|
||||
}
|
||||
|
||||
void FullLcdWrite(const char* TopLcd, const char* BottomLcd){
|
||||
TopLcdWrite(TopLcd);
|
||||
BottomLcdWrite(BottomLcd);
|
||||
}
|
||||
|
||||
void TopLcdWrite(const char *TopLcd){
|
||||
/*
|
||||
unsigned char string[16];
|
||||
Serial.write("Size of string: ");
|
||||
Serial.write(sizeof(TopLcd));
|
||||
delay(5000);
|
||||
for(int i = 0 ; i < sizeof(TopLcd) ; i++){
|
||||
string[i] = TopLcd[i];
|
||||
}
|
||||
|
||||
if(sizeof(TopLcd) < 16){
|
||||
for(int i = sizeof(TopLcd) ; i < 16 ; i++){
|
||||
string[i] = 32;
|
||||
}
|
||||
}
|
||||
*/
|
||||
LcdMoveToTop();
|
||||
LcdSerial.write(TopLcd); //Write string
|
||||
|
||||
}
|
||||
|
||||
void BottomLcdWrite(const char *BottomLcd){
|
||||
LcdMoveToBottom();
|
||||
LcdSerial.write(BottomLcd); //Write string
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
I was very new to programming at the time. Also, I had no clue how to spell dechorionator. XD
|
||||
@@ -0,0 +1,12 @@
|
||||
void InitializePins(){
|
||||
pinMode(LedGreen, OUTPUT); //Set Green LED Pin to Output
|
||||
pinMode(LedRed, OUTPUT); //Set Red LED Pin to Output
|
||||
|
||||
pinMode(StartSwitch, INPUT); //Set Start Switch Pin to Input
|
||||
pinMode(StopSwitch, INPUT); //Set Stop Switch Pin to Input
|
||||
digitalWrite(StartSwitch, HIGH); //Set the internal pullup resistor for the switch
|
||||
digitalWrite(StopSwitch, HIGH); //Same for this one
|
||||
|
||||
pinMode(EncoderChannelA, INPUT); //Set Encoder Channel A Pin to Input
|
||||
pinMode(EncoderChannelB, INPUT); //Set Encoder Channel B Pin to Input
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Atmel Studio Solution File, Format Version 11.00
|
||||
Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "DechorionatorV1.1", "DechorionatorV1.1.cppproj", "{C0A89A51-65B6-4173-AE27-4E91C9089ABF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|AVR = Debug|AVR
|
||||
Release|AVR = Release|AVR
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C0A89A51-65B6-4173-AE27-4E91C9089ABF}.Debug|AVR.ActiveCfg = Debug|AVR
|
||||
{C0A89A51-65B6-4173-AE27-4E91C9089ABF}.Debug|AVR.Build.0 = Debug|AVR
|
||||
{C0A89A51-65B6-4173-AE27-4E91C9089ABF}.Release|AVR.ActiveCfg = Release|AVR
|
||||
{C0A89A51-65B6-4173-AE27-4E91C9089ABF}.Release|AVR.Build.0 = Release|AVR
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Binary file not shown.
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* DechorionatorV1.cpp
|
||||
*
|
||||
* Created: 7/30/2014 4:55:13 PM
|
||||
* Author: corwin
|
||||
*/
|
||||
#define F_CPU 16000000UL
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#include "DefineMacrosAndPinDefs.h"
|
||||
#include "SoftLCD.h"
|
||||
#include "StepperClass.h"
|
||||
#include "PumpClass.h"
|
||||
#include "EncoderClass.h"
|
||||
#include "InterruptServiceRoutines.h"
|
||||
|
||||
SoftLCD LCD(&LCD_TX_PORT, &LCD_TX_DDR, P_LCD_TX, &LCD_PWR_PORT, &LCD_PWR_DDR, P_LCD_PWR);
|
||||
StepperClass Stepper(&STEPPER_EN_PORT, &STEPPER_EN_DDR, P_STEPPER_EN,
|
||||
&STEPPER_DIR_PORT, &STEPPER_DIR_DDR, P_STEPPER_DIR,
|
||||
&STEPPER_STEP_PORT, &STEPPER_STEP_DDR, P_STEPPER_STEP,
|
||||
&STEPPER_FAULT_PORT, &STEPPER_FAULT_DDR, P_STEPPER_FAULT,
|
||||
&STEPPER_M0_PORT, &STEPPER_M0_DDR, P_STEPPER_M0,
|
||||
&STEPPER_M1_PORT, &STEPPER_M1_DDR, P_STEPPER_M1,
|
||||
&STEPPER_M2_PORT, &STEPPER_M2_DDR, P_STEPPER_M2
|
||||
);
|
||||
|
||||
char TopTemp[17];
|
||||
char BottomTemp[17];
|
||||
|
||||
void TemporaryInit(){
|
||||
//////////Pump Initialization//////////
|
||||
PUMP_PWR_INIT();
|
||||
//////////End Pump Initialization//////////
|
||||
|
||||
//////////Rotary Encoder Initialization//////////
|
||||
ENCODER_A_INIT();
|
||||
|
||||
ENCODER_B_INIT();
|
||||
|
||||
ENCODER_BUTTON_INIT();
|
||||
//////////End Rotary Encoder Initialization//////////
|
||||
|
||||
|
||||
//////////Hardware Serial Initialization//////////
|
||||
UART_TX_INIT();
|
||||
UART_RX_INIT();
|
||||
//////////End Hardware Serial Initialization//////////
|
||||
|
||||
|
||||
//////////Control Switch Initialization//////////
|
||||
SWITCH_TOP_INIT();
|
||||
SWITCH_BOTTOM_INIT();
|
||||
//////////End Control Switch Initilization//////////
|
||||
|
||||
}
|
||||
|
||||
int TimeCount = 0;
|
||||
|
||||
int i = 0;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
TemporaryInit();
|
||||
TCCR2A = 0;
|
||||
TCCR2B = ((1 << CS22) | (1 << CS21) | (1 << CS20));
|
||||
TCNT2 = 0;
|
||||
TIMSK2 = (1 << TOIE0);
|
||||
|
||||
sei(); //Enable all system interrupts
|
||||
|
||||
//////////Startup Display and System Initialization//////////
|
||||
LCD.showNameScreen();
|
||||
|
||||
LCD.setTopText(" Time ");
|
||||
STEPPER_EN_SET();
|
||||
while(1)
|
||||
{
|
||||
for(int i = 2000 ; i > 1200 ; i--){
|
||||
LCD.show();
|
||||
snprintf(BottomTemp, 16, "%d", TimeCount);
|
||||
LCD.setBottomText(BottomTemp);
|
||||
OCR1A = i;
|
||||
_delay_us(2000);
|
||||
if(SWITCH_TOP_GET() || SWITCH_BOTTOM_GET()){
|
||||
STEPPER_EN_SET();
|
||||
}else{
|
||||
STEPPER_EN_CLR();
|
||||
}
|
||||
}
|
||||
for(int i = 1200 ; i < 2000 ; i++){
|
||||
LCD.show();
|
||||
snprintf(BottomTemp, 16, "%d", TimeCount);
|
||||
LCD.setBottomText(BottomTemp);
|
||||
OCR1A = i;
|
||||
_delay_us(2000);
|
||||
if(SWITCH_TOP_GET() || SWITCH_BOTTOM_GET()){
|
||||
STEPPER_EN_SET();
|
||||
}else{
|
||||
STEPPER_EN_CLR();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
<?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.CPP</ToolchainName>
|
||||
<ProjectGuid>{c0a89a51-65b6-4173-ae27-4e91c9089abf}</ProjectGuid>
|
||||
<avrdevice>ATmega328</avrdevice>
|
||||
<avrdeviceseries>none</avrdeviceseries>
|
||||
<OutputType>Executable</OutputType>
|
||||
<Language>CPP</Language>
|
||||
<OutputFileName>$(MSBuildProjectName)</OutputFileName>
|
||||
<OutputFileExtension>.elf</OutputFileExtension>
|
||||
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
|
||||
<AssemblyName>DechorionatorV1.1</AssemblyName>
|
||||
<Name>DechorionatorV1.1</Name>
|
||||
<RootNamespace>DechorionatorV1.1</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>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<ToolchainSettings>
|
||||
<AvrGccCpp>
|
||||
<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>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcccpp.compiler.symbols.DefSymbols>
|
||||
<ListValues>
|
||||
<Value>NDEBUG</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.compiler.symbols.DefSymbols>
|
||||
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
|
||||
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
|
||||
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
|
||||
<avrgcccpp.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>libm</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.linker.libraries.Libraries>
|
||||
</AvrGccCpp>
|
||||
</ToolchainSettings>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<ToolchainSettings>
|
||||
<AvrGccCpp>
|
||||
<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>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||
<avrgcccpp.compiler.symbols.DefSymbols>
|
||||
<ListValues>
|
||||
<Value>DEBUG</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.compiler.symbols.DefSymbols>
|
||||
<avrgcccpp.compiler.optimization.level>Optimize (-O1)</avrgcccpp.compiler.optimization.level>
|
||||
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
|
||||
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
|
||||
<avrgcccpp.compiler.optimization.DebugLevel>Default (-g2)</avrgcccpp.compiler.optimization.DebugLevel>
|
||||
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
|
||||
<avrgcccpp.linker.libraries.Libraries>
|
||||
<ListValues>
|
||||
<Value>libm</Value>
|
||||
</ListValues>
|
||||
</avrgcccpp.linker.libraries.Libraries>
|
||||
<avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel>
|
||||
</AvrGccCpp>
|
||||
</ToolchainSettings>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DechorionatorV1.1.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DefineMacrosAndPinDefs.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="EncoderClass.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="EncoderClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="InterruptServiceRoutines.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MegaUART.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MegaUART.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="PumpClass.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="PumpClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SoftLCD.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SoftLCD.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="StepperClass.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="StepperClass.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* DefineMacrosAndPinDefs.h
|
||||
*
|
||||
* Created: 7/30/2014 4:56:56 PM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DEFINEMACROSANDPINDEFS_H_
|
||||
#define DEFINEMACROSANDPINDEFS_H_
|
||||
|
||||
//////////LCD Definitions//////////
|
||||
#define P_LCD_TX PORTB0 //Pin B0 runs tx pin for serial lcd
|
||||
#define LCD_TX_PORT PORTB //Port that the tx lcd pin is on
|
||||
#define LCD_TX_DDR DDRB //Direction port that the tx lcd pin is on
|
||||
#define LCD_TX_BM (1 << P_LCD_TX) //Bit mask for pin
|
||||
#define LCD_TX_INIT() DDRB |= LCD_TX_BM //Sets tx pin to output
|
||||
#define LCD_TX_SET() PORTB |= LCD_TX_BM //Macro for setting pin high
|
||||
#define LCD_TX_CLR() PORTB &= ~LCD_TX_BM //Macro for setting pin low
|
||||
|
||||
|
||||
#define P_LCD_PWR PORTC5 //Pin C5 controls the power to the lcd through a mosfet
|
||||
#define LCD_PWR_PORT PORTC //Port that the lcd power pin is on
|
||||
#define LCD_PWR_DDR DDRC //Direction port that the lcd power pin is on
|
||||
#define LCD_PWR_BM (1 << P_LCD_PWR) //Bit mask for pin
|
||||
#define LCD_PWR_INIT() DDRC |= LCD_PWR_BM //Sets lcd power control pin to an output
|
||||
#define LCD_PWR_SET() PORTC |= LCD_PWR_BM //Macro for setting pin high
|
||||
#define LCD_PWR_CLR() PORTC &= ~LCD_PWR_BM //Macro for setting pin low
|
||||
//////////End LCD Definitions
|
||||
|
||||
//////////Pump Definitions//////////
|
||||
#define P_PUMP_PWR PORTD5 //Pin D5 controls power to the water pump through a mosfet
|
||||
#define PUMP_PWR_BM (1 << P_PUMP_PWR) //Bit mask for pin
|
||||
#define PUMP_PWR_INIT() DDRD |= PUMP_PWR_BM //Sets pump power control pin to an output
|
||||
#define PUMP_PWR_SET() PORTD |= PUMP_PWR_BM //Macro for setting pin high
|
||||
#define PUMP_PWR_CLR() PORTD &= ~PUMP_PWR_BM //Macro for setting pin low
|
||||
//////////End Pump Definitions//////////
|
||||
|
||||
//////////DRV8825 Stepper Motor Driver Definitions//////////
|
||||
#define P_STEPPER_DIR PORTD6 //Pin D6 controls the direction of the stepper motor
|
||||
#define STEPPER_DIR_PORT PORTD
|
||||
#define STEPPER_DIR_DDR DDRD
|
||||
#define STEPPER_DIR_BM (1 << P_STEPPER_DIR) //Bit mask for pin
|
||||
#define STEPPER_DIR_INIT() DDRD |= STEPPER_DIR_BM //Sets stepper direction pin to an output
|
||||
#define STEPPER_DIR_SET() PORTD |= STEPPER_DIR_BM //Macro for setting pin high
|
||||
#define STEPPER_DIR_CLR() PORTD &= ~STEPPER_DIR_BM //Macro for setting pin low
|
||||
|
||||
|
||||
#define P_STEPPER_STEP PORTD7 //Pin D7 controls the step pin of the driver
|
||||
#define STEPPER_STEP_PORT PORTD
|
||||
#define STEPPER_STEP_DDR DDRD
|
||||
#define STEPPER_STEP_BM (1 << P_STEPPER_STEP) //Bit mask for pin
|
||||
#define STEPPER_STEP_INIT() DDRD |= STEPPER_STEP_BM //Sets the step pin to an output
|
||||
#define STEPPER_STEP_SET() PORTD |= STEPPER_STEP_BM //Macro for setting pin high
|
||||
#define STEPPER_STEP_CLR() PORTD &= ~STEPPER_STEP_BM //Macro for setting pin low
|
||||
|
||||
|
||||
#define P_STEPPER_EN PORTC1 //Pin C1 controls whether the stepper motor is enabled and running or not
|
||||
#define STEPPER_EN_PORT PORTC
|
||||
#define STEPPER_EN_DDR DDRC
|
||||
#define STEPPER_EN_BM (1 << P_STEPPER_EN) //Bit mask for pin
|
||||
#define STEPPER_EN_INIT() DDRC |= STEPPER_EN_BM //Sets stepper enable control pin to an output
|
||||
#define STEPPER_EN_SET() PORTC &= ~STEPPER_EN_BM //Macro for setting pin high (Note inverted logic!!!)
|
||||
#define STEPPER_EN_CLR() PORTC |= STEPPER_EN_BM //Macro for setting pin low (Note inverted logic!!!)
|
||||
|
||||
|
||||
#define P_STEPPER_FAULT PORTC0 //Pin C0 senses whether the stepper driver is in a fault state due to over current or over temp conditions
|
||||
#define STEPPER_FAULT_PORT PORTC
|
||||
#define STEPPER_FAULT_DDR DDRC
|
||||
#define STEPPER_FAULT_BM (1 << P_STEPPER_FAULT) //Bit mask for pin
|
||||
#define STEPPER_FAULT_INIT() DDRC &= ~STEPPER_FAULT_BM //Sets stepper fault check pin to an input (May need to enable internal pull up?)
|
||||
#define STEPPER_FAULT_GET() !(PINC & STEPPER_FAULT_BM) //Returns true if in fault state (0 is fault, 1 is non-fault)
|
||||
|
||||
|
||||
|
||||
#define P_STEPPER_M0 PORTC2 //Pin C2 sets the lowest bit of the driver micro-stepping
|
||||
#define STEPPER_M0_PORT PORTC
|
||||
#define STEPPER_M0_DDR DDRC
|
||||
#define STEPPER_M0_BM (1 << P_STEPPER_M0) //Bit mask for pin
|
||||
#define STEPPER_M0_INIT() DDRC |= STEPPER_M0_BM //Sets the micro-step pin to an output
|
||||
#define STEPPER_M0_SET() PORTC |= STEPPER_M0_BM //Macro for setting pin high
|
||||
#define STEPPER_M0_CLR() PORTC &= ~STEPPER_M0_BM //Macro for setting pin low
|
||||
|
||||
|
||||
#define P_STEPPER_M1 PORTC3 //Pin C3 sets the middle bit of the driver micro-stepping
|
||||
#define STEPPER_M1_PORT PORTC
|
||||
#define STEPPER_M1_DDR DDRC
|
||||
#define STEPPER_M1_BM (1 << P_STEPPER_M1) //Bit mask for pin
|
||||
#define STEPPER_M1_INIT() DDRC |= STEPPER_M1_BM //Sets the micro-step pin to an output
|
||||
#define STEPPER_M1_SET() PORTC |= STEPPER_M1_BM //Macro for setting pin high
|
||||
#define STEPPER_M1_CLR() PORTC &= ~STEPPER_M1_BM //Macro for setting pin low
|
||||
|
||||
|
||||
#define P_STEPPER_M2 PORTC4 //Pin C4 sets the upper bit of the driver micro-stepping
|
||||
#define STEPPER_M2_PORT PORTC
|
||||
#define STEPPER_M2_DDR DDRC
|
||||
#define STEPPER_M2_BM (1 << P_STEPPER_M2) //Bit mask for pin
|
||||
#define STEPPER_M2_INIT() DDRC |= STEPPER_M2_BM //Sets the micro-step pin to an output
|
||||
#define STEPPER_M2_SET() PORTC |= STEPPER_M2_BM //Macro for setting pin high
|
||||
#define STEPPER_M2_CLR() PORTC &= ~STEPPER_M2_BM //Macro for setting pin low
|
||||
//////////End DRV8825 Stepper Motor Driver Definitions//////////
|
||||
|
||||
//////////Rotary Encoder Definitions//////////
|
||||
#define P_ENCODER_A PORTD2 //Pin D2 senses the state for channel A on the rotary encoder
|
||||
#define ENCODER_A_BM (1 << P_ENCODER_A) //Bit mask for pin
|
||||
#define ENCODER_A_INIT() {DDRD &= ~ENCODER_A_BM; PORTD |= ENCODER_A_BM;} //Sets channel A pin to an input and enables the internal pull up resistor
|
||||
#define ENCODER_A_GET() !(PIND & ENCODER_A_BM) //Returns state of the pin (Note inverted logic!!! Makes gray code logic less confusing...)
|
||||
|
||||
|
||||
#define P_ENCODER_B PORTD3 //Pin D3 sense the state for channel B on the rotary encoder
|
||||
#define ENCODER_B_BM (1 << P_ENCODER_B) //Bit mask for pin
|
||||
#define ENCODER_B_INIT() {DDRD &= ~ENCODER_B_BM; PORTD |= ENCODER_B_BM;} //Sets channel B pin to an input and enables the internal pull up resistor
|
||||
#define ENCODER_B_GET() !(PIND & ENCODER_B_BM) //Returns state of the pin (Note inverted logic!!! Makes gray code logic less confusing...)
|
||||
|
||||
|
||||
#define P_ENCODER_BUTTON PORTD4 //Pin D4 senses whether the tactile button on the rotary encoder has been pushed
|
||||
#define ENCODER_BUTTON_BM (1 << P_ENCODER_BUTTON) //Bit mask for pin
|
||||
#define ENCODER_BUTTON_INIT() {DDRD &= ~ENCODER_BUTTON_BM; PORTD |= ENCODER_BUTTON_BM;} //Sets encoder button pin to an input and enables the internal pull up resistor
|
||||
#define ENCODER_BUTTON_GET() !(PIND & ENCODER_BUTTON_BM) //Returns whether the button has been pushed (Note inverted logic!!!)
|
||||
//////////End Rotary Encoder Definitions//////////
|
||||
|
||||
//////////Hardware Serial Definitions//////////
|
||||
#define P_UART_TX PORTD1 //Pin D1 is the transmit line for the hardware uart
|
||||
#define UART_TX_BM (1 << P_UART_TX) //Bit mask for pin
|
||||
#define UART_TX_INIT() DDRD |= UART_TX_BM //Sets the transmit line to an output
|
||||
|
||||
|
||||
#define P_UART_RX PORTD0 //Pin D0 is the receive line for the hardware uart
|
||||
#define UART_RX_BM (1 << P_UART_RX) //Bit mask for pin
|
||||
#define UART_RX_INIT() DDRD &= ~UART_RX_BM //Sets the receive line to an input
|
||||
//////////End Hardware Serial Definitions//////////
|
||||
|
||||
//////////Control Switch Definitions//////////
|
||||
#define P_SWITCH_TOP PORTB2 //Pin B1 senses whether the top button on the control switch has been pushed (RINSE)
|
||||
#define SWITCH_TOP_BM (1 << P_SWITCH_TOP) //Bit mask for pin
|
||||
#define SWITCH_TOP_INIT() {DDRB |= SWITCH_TOP_BM; PORTB |= SWITCH_TOP_BM;} //Sets the button to an input and enables the internal pull up resistor
|
||||
#define SWITCH_TOP_GET() !(PINB & SWITCH_TOP_BM) //Returns whether the button has been pushed (Note inverted logic!!!)
|
||||
|
||||
|
||||
#define P_SWITCH_BOTTOM PORTB1 //Pin B2 senses whether the bottom button on the control switch has been pushed (ESTOP)
|
||||
#define SWITCH_BOTTOM_BM (1 << P_SWITCH_BOTTOM) //Bit mask for pin
|
||||
#define SWITCH_BOTTOM_INIT() {DDRB |= SWITCH_BOTTOM_BM; PORTB |= SWITCH_BOTTOM_BM;} //Sets the button to an input and enables the internal pull up resistor
|
||||
#define SWITCH_BOTTOM_GET() !(PINB & SWITCH_BOTTOM_BM) //Returns whether the button has been pushed (Note inverted logic!!!)
|
||||
//////////Control Switch Definitions//////////
|
||||
|
||||
|
||||
#endif /* DEFINEMACROSANDPINDEFS_H_ */
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* EncoderClass.cpp
|
||||
*
|
||||
* Created: 8/6/2014 9:20:23 AM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
|
||||
#include "EncoderClass.h"
|
||||
|
||||
// default constructor
|
||||
EncoderClass::EncoderClass()
|
||||
{
|
||||
} //EncoderClass
|
||||
|
||||
// default destructor
|
||||
EncoderClass::~EncoderClass()
|
||||
{
|
||||
} //~EncoderClass
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* EncoderClass.h
|
||||
*
|
||||
* Created: 8/6/2014 9:20:23 AM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __ENCODERCLASS_H__
|
||||
#define __ENCODERCLASS_H__
|
||||
|
||||
|
||||
class EncoderClass
|
||||
{
|
||||
//variables
|
||||
public:
|
||||
protected:
|
||||
private:
|
||||
|
||||
//functions
|
||||
public:
|
||||
EncoderClass();
|
||||
~EncoderClass();
|
||||
protected:
|
||||
private:
|
||||
EncoderClass( const EncoderClass &c );
|
||||
EncoderClass& operator=( const EncoderClass &c );
|
||||
|
||||
}; //EncoderClass
|
||||
|
||||
#endif //__ENCODERCLASS_H__
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* InterruptServiceRoutines.h
|
||||
*
|
||||
* Created: 8/4/2014 4:55:26 PM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INTERRUPTSERVICEROUTINES_H_
|
||||
#define INTERRUPTSERVICEROUTINES_H_
|
||||
|
||||
extern SoftLCD LCD;
|
||||
extern StepperClass Stepper;
|
||||
extern int i;
|
||||
extern int TimeCount;
|
||||
|
||||
ISR(TIMER2_OVF_vect){
|
||||
static int CountDelay = 0;
|
||||
CountDelay++;
|
||||
if(CountDelay >= 61){
|
||||
TimeCount++;
|
||||
CountDelay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ISR(TIMER1_COMPA_vect){
|
||||
Stepper.OneStep();
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
////////Pin change interrupt 2 is for pins pcint 23 to 16
|
||||
////////
|
||||
//Pin change interrupt 18 is on pin PORTD2
|
||||
//ISR(){
|
||||
|
||||
//}
|
||||
|
||||
//Pin change interrupt 19 is on pin PORTD3
|
||||
//ISR(){
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
#endif /* INTERRUPTSERVICEROUTINES_H_ */
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* MegaUART.cpp
|
||||
*
|
||||
* Created: 7/31/2014 12:00:58 PM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
|
||||
#include "MegaUART.h"
|
||||
|
||||
// default constructor
|
||||
MegaUART::MegaUART()
|
||||
{
|
||||
} //MegaUART
|
||||
|
||||
// default destructor
|
||||
MegaUART::~MegaUART()
|
||||
{
|
||||
} //~MegaUART
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* MegaUART.h
|
||||
*
|
||||
* Created: 7/31/2014 12:00:58 PM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __MEGAUART_H__
|
||||
#define __MEGAUART_H__
|
||||
|
||||
|
||||
class MegaUART
|
||||
{
|
||||
//variables
|
||||
public:
|
||||
protected:
|
||||
private:
|
||||
|
||||
//functions
|
||||
public:
|
||||
MegaUART();
|
||||
~MegaUART();
|
||||
protected:
|
||||
private:
|
||||
MegaUART( const MegaUART &c );
|
||||
MegaUART& operator=( const MegaUART &c );
|
||||
|
||||
}; //MegaUART
|
||||
|
||||
#endif //__MEGAUART_H__
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* PumpClass.cpp
|
||||
*
|
||||
* Created: 8/6/2014 9:16:05 AM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
|
||||
#include "PumpClass.h"
|
||||
|
||||
// default constructor
|
||||
PumpClass::PumpClass()
|
||||
{
|
||||
} //PumpClass
|
||||
|
||||
// default destructor
|
||||
PumpClass::~PumpClass()
|
||||
{
|
||||
} //~PumpClass
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* PumpClass.h
|
||||
*
|
||||
* Created: 8/6/2014 9:16:05 AM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __PUMPCLASS_H__
|
||||
#define __PUMPCLASS_H__
|
||||
|
||||
|
||||
class PumpClass
|
||||
{
|
||||
//variables
|
||||
public:
|
||||
protected:
|
||||
private:
|
||||
|
||||
//functions
|
||||
public:
|
||||
PumpClass();
|
||||
~PumpClass();
|
||||
protected:
|
||||
private:
|
||||
PumpClass( const PumpClass &c );
|
||||
PumpClass& operator=( const PumpClass &c );
|
||||
|
||||
}; //PumpClass
|
||||
|
||||
#endif //__PUMPCLASS_H__
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* SoftLCD.cpp
|
||||
*
|
||||
* Created: 7/31/2014 11:20:02 AM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
|
||||
#include "SoftLCD.h"
|
||||
|
||||
// default constructor
|
||||
SoftLCD::SoftLCD(volatile uint8_t *txport, volatile uint8_t *txddr, int txpin, volatile uint8_t *pwrport, volatile uint8_t *pwrddr, int pwrpin)
|
||||
{
|
||||
//Set up public variables
|
||||
//strncpy(TopLine, "Test", 16);
|
||||
snprintf(TopLine, 16, " ");
|
||||
snprintf(BottomLine, 16, " ");
|
||||
|
||||
strcpy(TopLinePrev, TopLine);
|
||||
strcpy(BottomLinePrev, BottomLine);
|
||||
|
||||
//Set up private variables
|
||||
serPort = txport;
|
||||
serDDR = txddr;
|
||||
serPin = txpin;
|
||||
|
||||
pwrPort = pwrport;
|
||||
pwrDDR = pwrddr;
|
||||
pwrPin = pwrpin;
|
||||
|
||||
//Set up tx pin for transmission
|
||||
*serDDR |= (1 << serPin);
|
||||
*serPort |= (1 << serPin);
|
||||
|
||||
//Set up power control pin for output
|
||||
*pwrDDR |= (1 << pwrPin);
|
||||
setLCDOn(true); //On by default
|
||||
putChar(124);
|
||||
putChar(157);
|
||||
|
||||
setRefreshRate(5); //Keep at 10fps or lower to keep screen looking nice. 5 fps seems like a good middle ground
|
||||
|
||||
|
||||
} //SoftLCD
|
||||
|
||||
// default destructor
|
||||
SoftLCD::~SoftLCD()
|
||||
{
|
||||
} //~SoftLCD
|
||||
|
||||
void SoftLCD::putChar(char c) {
|
||||
//TCCR1B &= ~((1 << CS10) | (1 << CS11) | (1 << CS12));
|
||||
//Start bit
|
||||
*serPort &= ~(1 << serPin); //Write a zero for the start bit
|
||||
_delay_us(MICROSECONDS_PER_BIT); //Wait one bit period
|
||||
|
||||
//Begin data bits
|
||||
for (uint8_t bit_mask = 0x01; bit_mask ; bit_mask <<= 1) { //Move through each bit in the char starting with the least significant bit
|
||||
if (c & bit_mask) { //If that position contains a 1
|
||||
*serPort |= (1 << serPin); //Write a 1 to the tx pin
|
||||
}else { //Otherwise...
|
||||
*serPort &= ~(1 << serPin); //Write a 0 to the tx pin
|
||||
}
|
||||
_delay_us(MICROSECONDS_PER_BIT); //Delay for the correct period of time for one bit
|
||||
}
|
||||
|
||||
//Stop bit(s)
|
||||
*serPort |= (1<<serPin); //Write a one for the stop bit
|
||||
_delay_us(MICROSECONDS_PER_BIT * STOP_BITS); //Wait the period of time required for the number of stop bits desired
|
||||
//TCCR1B |= ((1 << CS10) | (1 << CS11));
|
||||
}
|
||||
|
||||
|
||||
void SoftLCD::setLCDOn(bool on)
|
||||
{
|
||||
if(on == true){
|
||||
*pwrPort |= (1 << pwrPin);
|
||||
}else if(on == false){
|
||||
*pwrPort &= ~(1 << pwrPin);
|
||||
}
|
||||
}
|
||||
|
||||
void SoftLCD::setRefreshRate(int rate)
|
||||
{/*
|
||||
TCCR0A = 0;
|
||||
TCCR0B = ((1 << CS10) | (1 << CS12));
|
||||
TCNT0 = 0;
|
||||
TIMSK0 = (1 << TOIE0);
|
||||
*/
|
||||
}
|
||||
|
||||
void SoftLCD::show()
|
||||
{
|
||||
if(strcmp(TopLine, TopLinePrev) != 0){
|
||||
_moveToTop();
|
||||
_printLine((char *)" ");
|
||||
_moveToTop();
|
||||
_printLine(TopLine);
|
||||
strcpy(TopLinePrev, TopLine);
|
||||
}
|
||||
|
||||
if(strcmp(BottomLine, BottomLinePrev) != 0){
|
||||
_moveToBottom();
|
||||
_printLine((char *)" ");
|
||||
_moveToBottom();
|
||||
_printLine(BottomLine);
|
||||
strcpy(BottomLinePrev, BottomLine);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SoftLCD::_moveToTop()
|
||||
{
|
||||
putChar(254); //Puts lcd into command mode
|
||||
putChar(128); //Moves to first character on top
|
||||
}
|
||||
|
||||
void SoftLCD::_moveToBottom()
|
||||
{
|
||||
putChar(254); //Puts lcd into command mode
|
||||
putChar(192); //Moves to first character on bottom
|
||||
}
|
||||
|
||||
void SoftLCD::_printLine(char *text)
|
||||
{
|
||||
for(int i = 0 ; ((i < 16) && (text[i] != '\0')) ; i++){
|
||||
putChar(text[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void SoftLCD::setTopText(char *top)
|
||||
{
|
||||
snprintf(TopLine, 16, top);
|
||||
}
|
||||
|
||||
void SoftLCD::setTopText(const char *top)
|
||||
{
|
||||
snprintf(TopLine, 16, top);
|
||||
}
|
||||
|
||||
void SoftLCD::setBottomText(char *bottom)
|
||||
{
|
||||
snprintf(BottomLine, 16, bottom);
|
||||
}
|
||||
|
||||
void SoftLCD::setBottomText(const char *bottom)
|
||||
{
|
||||
snprintf(BottomLine, 16, bottom);
|
||||
}
|
||||
|
||||
void SoftLCD::showNameScreen()
|
||||
{
|
||||
_delay_ms(2000); //Delay for LCD
|
||||
setTopText(" Dechorionator"); //Startup Text Top
|
||||
setBottomText(" Revision 2.0"); //Startup Text Bottom
|
||||
show();
|
||||
_delay_ms(2750); //Pause for effect
|
||||
}
|
||||
|
||||
void SoftLCD::disableSparkfunLogo()
|
||||
{
|
||||
putChar(124);
|
||||
putChar(9);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* SoftLCD.h
|
||||
*
|
||||
* Created: 7/31/2014 11:20:02 AM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __SOFTLCD_H__
|
||||
#define __SOFTLCD_H__
|
||||
#define F_CPU 16000000UL
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <inttypes.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "DefineMacrosAndPinDefs.h"
|
||||
|
||||
#define REFRESH_RATE_CONSTANT (16000000ul/1024)
|
||||
|
||||
#define BAUD 9600
|
||||
#define STOP_BITS 1
|
||||
|
||||
#define MICROSECONDS_OVERHEAD_ADJUST 0
|
||||
#define MICROSECONDS_PER_BIT ((1000000ul / BAUD) - MICROSECONDS_OVERHEAD_ADJUST)
|
||||
|
||||
class SoftLCD
|
||||
{
|
||||
//variables
|
||||
public:
|
||||
protected:
|
||||
private:
|
||||
FILE static usartout;
|
||||
|
||||
volatile uint8_t *serPort;
|
||||
volatile uint8_t *serDDR;
|
||||
int serPin;
|
||||
|
||||
volatile uint8_t *pwrPort;
|
||||
volatile uint8_t *pwrDDR;
|
||||
int pwrPin;
|
||||
|
||||
char TopLine[17];
|
||||
char BottomLine[17];
|
||||
|
||||
char TopLinePrev[17];
|
||||
char BottomLinePrev[17];
|
||||
//functions
|
||||
public:
|
||||
SoftLCD(volatile uint8_t *txport, volatile uint8_t *txddr, int txpin, volatile uint8_t *pwrport, volatile uint8_t *pwrddr, int pwrpin);
|
||||
|
||||
void disableSparkfunLogo();
|
||||
void showNameScreen();
|
||||
|
||||
void putChar(char c);
|
||||
void setLCDOn(bool on);
|
||||
void setRefreshRate(int rate);
|
||||
void show();
|
||||
|
||||
void setTopText(char *top);
|
||||
void setBottomText(char *bottom);
|
||||
void setTopText(const char *top);
|
||||
void setBottomText(const char *bottom);
|
||||
|
||||
~SoftLCD();
|
||||
protected:
|
||||
private:
|
||||
SoftLCD(const SoftLCD & c);
|
||||
SoftLCD& operator=( const SoftLCD &c );
|
||||
void _printLine(char *text);
|
||||
void _moveToTop();
|
||||
void _moveToBottom();
|
||||
|
||||
}; //SoftLCD
|
||||
|
||||
#endif //__SOFTLCD_H__
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* StepperClass.cpp
|
||||
*
|
||||
* Created: 8/1/2014 5:13:57 PM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
|
||||
#include "StepperClass.h"
|
||||
|
||||
// default constructor
|
||||
StepperClass::StepperClass(volatile uint8_t *enport, volatile uint8_t *enddr, int enpin,
|
||||
volatile uint8_t *dirport, volatile uint8_t *dirddr, int dirpin,
|
||||
volatile uint8_t *stepport, volatile uint8_t *stepddr, int steppin,
|
||||
volatile uint8_t *faultport, volatile uint8_t *faultddr, int faultpin,
|
||||
volatile uint8_t *m0port, volatile uint8_t *m0ddr, int m0pin,
|
||||
volatile uint8_t *m1port, volatile uint8_t *m1ddr, int m1pin,
|
||||
volatile uint8_t *m2port, volatile uint8_t *m2ddr, int m2pin
|
||||
)
|
||||
{
|
||||
enPort = enport;
|
||||
enDDR = enddr;
|
||||
enPin = enpin;
|
||||
_setupPinAsOutput(enDDR, enPin);
|
||||
_disableStepper();
|
||||
|
||||
dirPort = dirport;
|
||||
dirDDR = dirddr;
|
||||
dirPin = dirpin;
|
||||
_setupPinAsOutput(enDDR, enPin);
|
||||
_setPinLow(dirPort, dirPin);
|
||||
|
||||
stepPort = stepport;
|
||||
stepDDR = stepddr;
|
||||
stepPin = steppin;
|
||||
_setupPinAsOutput(enDDR, enPin);
|
||||
_setPinLow(stepPort, stepPin);
|
||||
|
||||
faultPort = faultport;
|
||||
faultDDR = faultddr;
|
||||
faultPin = faultpin;
|
||||
_setupPinAsInput(faultPort, faultDDR, faultPin, false);
|
||||
|
||||
m0Port = m0port;
|
||||
m0DDR = m0ddr;
|
||||
m0Pin = m0pin;
|
||||
_setupPinAsOutput(enDDR, enPin);
|
||||
_setPinHigh(m0Port, m0Pin);
|
||||
|
||||
m1Port = m1port;
|
||||
m1DDR = m1ddr;
|
||||
m1Pin = m1pin;
|
||||
_setupPinAsOutput(enDDR, enPin);
|
||||
_setPinLow(m1Port, m1Pin);
|
||||
|
||||
m2Port = m2port;
|
||||
m2DDR = m2ddr;
|
||||
m2Pin = m2pin;
|
||||
_setupPinAsOutput(enDDR, enPin);
|
||||
_setPinLow(m2Port, m2Pin);
|
||||
|
||||
|
||||
TCCR1A = 0; //Set output compare mode for channel A and B to normal operation and waveform generation to normal
|
||||
TCCR1B = ((1 << WGM12) | (1 << CS10) | (1 << CS11)); //Set clk prescalar for timer to clk/1024 and enable clear on timer compare match
|
||||
TCNT1 = 0; //Zero the count register
|
||||
TIMSK1 = (1 << OCIE1A); //Set interrupt flag to trigger on counter 1 overflow
|
||||
OCR1A = 2000; //Set the count value based on what's needed to update at a specific number of fps
|
||||
|
||||
} //StepperClass
|
||||
|
||||
// default destructor
|
||||
StepperClass::~StepperClass()
|
||||
{
|
||||
} //~StepperClass
|
||||
|
||||
void StepperClass::_setupPinAsOutput(volatile uint8_t *ddr, int pin)
|
||||
{
|
||||
*ddr |= (1 << pin);
|
||||
}
|
||||
|
||||
void StepperClass::_setupPinAsInput(volatile uint8_t *port, volatile uint8_t *ddr, int pin, bool enablePullup = false)
|
||||
{
|
||||
*ddr &= ~(1 << pin);
|
||||
if(enablePullup){
|
||||
*port |= (1 << pin);
|
||||
}
|
||||
}
|
||||
|
||||
void StepperClass::_enableStepper()
|
||||
{
|
||||
*enPort &= ~(1 << enPin);
|
||||
}
|
||||
|
||||
void StepperClass::_disableStepper()
|
||||
{
|
||||
*enPort |= (1 << enPin);
|
||||
}
|
||||
|
||||
void StepperClass::_setPinLow(volatile uint8_t *port, int pin)
|
||||
{
|
||||
*port &= ~(1 << pin);
|
||||
}
|
||||
|
||||
void StepperClass::_setPinHigh(volatile uint8_t *port, int pin)
|
||||
{
|
||||
*port |= (1 << pin);
|
||||
}
|
||||
|
||||
void StepperClass::OneStep()
|
||||
{
|
||||
_setPinHigh(stepPort, stepPin);
|
||||
_delay_us(2);
|
||||
_setPinLow(stepPort, stepPin);
|
||||
}
|
||||
|
||||
void StepperClass::SetRPM(int rpm)
|
||||
{
|
||||
OCR1B = 35000;//(long(STEPPER_RPM_CONSTANT)/rpm); //Set the count value based on what's needed to update at a specific number of fps
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* StepperClass.h
|
||||
*
|
||||
* Created: 8/1/2014 5:13:57 PM
|
||||
* Author: corwin
|
||||
*
|
||||
* MSTEP M2 M1 M0 DEC
|
||||
* 1 0 0 0 0
|
||||
* 2 0 0 1 1
|
||||
* 4 0 1 0 2
|
||||
* 8 0 1 1 3
|
||||
* 16 1 0 0 4
|
||||
* 32 1 0 1 5
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __STEPPERCLASS_H__
|
||||
#define __STEPPERCLASS_H__
|
||||
#define F_CPU 16000000UL
|
||||
|
||||
#include <util/delay.h>
|
||||
#include <avr/io.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define STEPPER_RPM_CONSTANT (16000000ul/1024)*60)
|
||||
|
||||
class StepperClass
|
||||
{
|
||||
//variables
|
||||
public:
|
||||
protected:
|
||||
private:
|
||||
volatile uint8_t *enPort;
|
||||
volatile uint8_t *enDDR;
|
||||
int enPin;
|
||||
|
||||
volatile uint8_t *dirPort;
|
||||
volatile uint8_t *dirDDR;
|
||||
int dirPin;
|
||||
|
||||
volatile uint8_t *stepPort;
|
||||
volatile uint8_t *stepDDR;
|
||||
int stepPin;
|
||||
|
||||
volatile uint8_t *faultPort;
|
||||
volatile uint8_t *faultDDR;
|
||||
int faultPin;
|
||||
|
||||
volatile uint8_t *m0Port;
|
||||
volatile uint8_t *m0DDR;
|
||||
int m0Pin;
|
||||
|
||||
volatile uint8_t *m1Port;
|
||||
volatile uint8_t *m1DDR;
|
||||
int m1Pin;
|
||||
|
||||
volatile uint8_t *m2Port;
|
||||
volatile uint8_t *m2DDR;
|
||||
int m2Pin;
|
||||
|
||||
//functions
|
||||
public:
|
||||
StepperClass(volatile uint8_t *enport, volatile uint8_t *enddr, int enpin,
|
||||
volatile uint8_t *dirport, volatile uint8_t *dirddr, int dirpin,
|
||||
volatile uint8_t *stepport, volatile uint8_t *stepddr, int steppin,
|
||||
volatile uint8_t *faultport, volatile uint8_t *faultddr, int faultpin,
|
||||
volatile uint8_t *m0port, volatile uint8_t *m0ddr, int m0pin,
|
||||
volatile uint8_t *m1port, volatile uint8_t *m1ddr, int m1pin,
|
||||
volatile uint8_t *m2port, volatile uint8_t *m2ddr, int m2pin
|
||||
);
|
||||
void SetRPM(int rpm);
|
||||
void OneStep();
|
||||
|
||||
~StepperClass();
|
||||
protected:
|
||||
private:
|
||||
StepperClass( const StepperClass &c );
|
||||
StepperClass& operator=( const StepperClass &c );
|
||||
void _setupPinAsOutput(volatile uint8_t *ddr, int pin);
|
||||
void _setupPinAsInput(volatile uint8_t *port, volatile uint8_t *ddr, int pin, bool enablePullup);
|
||||
|
||||
void _enableStepper();
|
||||
void _disableStepper();
|
||||
|
||||
void _setPinLow(volatile uint8_t *port, int pin);
|
||||
void _setPinHigh(volatile uint8_t *port, int pin);
|
||||
|
||||
}; //StepperClass
|
||||
|
||||
#endif //__STEPPERCLASS_H__
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_ */
|
||||
@@ -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
|
||||
Binary file not shown.
@@ -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//////////
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* SystemInputFunctions.c
|
||||
*
|
||||
* Created: 8/12/2014 3:31:50 PM
|
||||
* Author: corwin
|
||||
*/
|
||||
|
||||
#include "SystemInputFunctions.h"
|
||||
@@ -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_ */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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_ */
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
This was super simple. The speed control on a scientific rocker failed, so I build a replacement using an attiny, mosftet, and pot.
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
int mot = 0;
|
||||
int pot = A1;
|
||||
|
||||
|
||||
void setup() {
|
||||
pinMode(mot, OUTPUT);
|
||||
pinMode(pot, INPUT);
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
analogWrite(mot, analogRead(pot)/4);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user