Created
December 16, 2014 02:53
-
-
Save baragona/e5798d0f694fe1a9fe1b to your computer and use it in GitHub Desktop.
CNC machine control on bare metal - serial port communication...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <math.h> | |
#include <stdio.h> | |
#define TMR0STEPS REGISTER(TIMERSBASE,4) | |
#define TMR0DESIRED REGISTER(TIMERSBASE,5) | |
#define TMR0QUAD REGISTER(TIMERSBASE,6) | |
#define TMR0MAXOVERSHOOT REGISTER(TIMERSBASE,7) | |
#define tim1off 64 | |
#define tim2off 128 | |
#define tim3off 192 | |
#define TMR2CTL REGISTER(TIMERSBASE,tim2off+0) | |
#define TMR2CNT REGISTER(TIMERSBASE,tim2off+1) | |
#define TMR2CMP REGISTER(TIMERSBASE,tim2off+2) | |
#define TMR2STEPS REGISTER(TIMERSBASE,tim2off+4) | |
#define TMR2DESIRED REGISTER(TIMERSBASE,tim2off+5) | |
#define TMR2QUAD REGISTER(TIMERSBASE,tim2off+6) | |
#define TMR2MAXOVERSHOOT REGISTER(TIMERSBASE,tim2off+7) | |
#define TMR2PWMLOW(x) REGISTER(TIMERSBASE, tim2off+32+(4*x)) | |
#define TMR2PWMHIGH(x) REGISTER(TIMERSBASE, tim2off+33+(4*x)) | |
#define TMR2PWMCTL(x) REGISTER(TIMERSBASE, tim2off+34+(4*x)) | |
#define TMR3CTL REGISTER(TIMERSBASE,tim3off+0) | |
#define TMR3CNT REGISTER(TIMERSBASE,tim3off+1) | |
#define TMR3CMP REGISTER(TIMERSBASE,tim3off+2) | |
#define TMR3STEPS REGISTER(TIMERSBASE,tim3off+4) | |
#define TMR3DESIRED REGISTER(TIMERSBASE,tim3off+5) | |
#define TMR3QUAD REGISTER(TIMERSBASE,tim3off+6) | |
#define TMR3MAXOVERSHOOT REGISTER(TIMERSBASE,tim3off+7) | |
#define TMR3PWMLOW(x) REGISTER(TIMERSBASE, tim3off+32+(4*x)) | |
#define TMR3PWMHIGH(x) REGISTER(TIMERSBASE, tim3off+33+(4*x)) | |
#define TMR3PWMCTL(x) REGISTER(TIMERSBASE, tim3off+34+(4*x)) | |
struct frameCommand{ | |
int desiredPos[3]; | |
}; | |
#include "wing_buffer.h" | |
const int TimerRingBufSize = 600; | |
struct frameCommand wing_buffer_data[TimerRingBufSize]; | |
wing_buffer wingBuf1; | |
unsigned idum=0; | |
uint16_t lastPsc=1024; | |
uint16_t lastCmp=65535;//Assume worst possible initially | |
int curfreq=50; | |
int freqdir=1; | |
int desired=0; | |
int framerate; | |
double microsPerFrame=1; | |
double fudgeFactor = 1.1; | |
double microsPerFrameFudged=1; | |
int maxOvershoot[3]={800,800,800}; | |
// undefine stdlib's abs if encountered | |
#ifdef abs | |
#undef abs | |
#endif | |
#define min(a,b) ((a)<(b)?(a):(b)) | |
#define max(a,b) ((a)>(b)?(a):(b)) | |
#define abs(x) ((x)>0?(x):-(x)) | |
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) | |
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) | |
inline void store_u32(unsigned char *dest, uint32_t value) | |
{ | |
*dest++=(value>>24); | |
*dest++=(value>>16); | |
*dest++=(value>>8); | |
*dest=value; | |
} | |
inline uint32_t read_u32(unsigned char *src){ | |
uint32_t v1=src[0]; | |
uint32_t v2=src[1]; | |
uint32_t v3=src[2]; | |
uint32_t v4=src[3]; | |
return (v1<<24) | (v2<<16) | (v3<<8) | v4; | |
} | |
uint8_t digitalReadBool(int pin){ | |
if(digitalRead(pin)>0){ | |
return 1; | |
} | |
return 0; | |
} | |
void setFrameRate(int fr){ | |
fr=max(fr,6); | |
fr=min(fr,10000); | |
framerate=fr; | |
int cmp = round(96000000.0/fr); | |
microsPerFrame=cmp/96.0; | |
microsPerFrameFudged=microsPerFrame*fudgeFactor; | |
TMR1CNT = 0; | |
TMR1CMP = cmp-1; | |
} | |
float sine(float x) | |
{ | |
const float pi = 3.1415926535; | |
const float B = 4/pi; | |
const float C = -4/(pi*pi); | |
float y = B * x + C * x * abs(x); | |
return y; | |
} | |
struct stepperConstants { | |
volatile unsigned * ctl; | |
volatile unsigned * cnt; | |
volatile unsigned * steps; | |
volatile unsigned * desired; | |
volatile unsigned * cmp; | |
volatile unsigned * pwmh; | |
volatile unsigned * pwml; | |
volatile unsigned * pwmctl; | |
volatile unsigned * maxovershoot; | |
int steppps; | |
int dirpps; | |
int steppin; | |
int dirpin; | |
int sleeppin; | |
}; | |
struct stepperVars{ | |
uint16_t lastPsc; | |
}; | |
struct stepperVars stepvars[3]; | |
const struct stepperConstants steppers[3]={ | |
{ | |
&TMR0CTL, | |
&TMR0CNT, | |
&TMR0STEPS, | |
&TMR0DESIRED, | |
&TMR0CMP, | |
&TMR0PWMHIGH(0), | |
&TMR0PWMLOW(0), | |
&TMR0PWMCTL(0), | |
&TMR0MAXOVERSHOOT, | |
IOPIN_TIMER0_OC, | |
7, | |
WING_A_0, | |
WING_B_15, | |
WING_B_9 | |
}, | |
{ | |
&TMR2CTL, | |
&TMR2CNT, | |
&TMR2STEPS, | |
&TMR2DESIRED, | |
&TMR2CMP, | |
&TMR2PWMHIGH(0), | |
&TMR2PWMLOW(0), | |
&TMR2PWMCTL(0), | |
&TMR2MAXOVERSHOOT, | |
10, | |
8, | |
WING_A_1, | |
WING_B_14, | |
WING_B_8 | |
}, | |
{ | |
&TMR3CTL, | |
&TMR3CNT, | |
&TMR3STEPS, | |
&TMR3DESIRED, | |
&TMR3CMP, | |
&TMR3PWMHIGH(0), | |
&TMR3PWMLOW(0), | |
&TMR3PWMCTL(0), | |
&TMR3MAXOVERSHOOT, | |
11, | |
9, | |
WING_A_2, | |
WING_B_13, | |
WING_B_7 | |
} | |
}; | |
const int nSwitches = 3; | |
//int switchPins[nSwitches]={WING_A_3, WING_A_4, WING_A_5};//, WING_A_6, WING_B_12, WING_B_11, WING_B_10, WING_B_9}; //the real one | |
int switchPins[nSwitches]={WING_A_7, WING_A_8, WING_A_5};//, WING_A_6, WING_B_12, WING_B_11, WING_B_10, WING_B_9};//test one | |
char switchStates[nSwitches]; | |
unsigned int switchTimeLastChanged[nSwitches]; | |
int switchHasSettled[nSwitches]; | |
void setup() { | |
Serial.begin(115200); | |
wb_init(&wingBuf1,TimerRingBufSize,wing_buffer_data); | |
unsigned frequency = 100000; | |
reset_integrator(); | |
for(int i =0;i<3;i++){ | |
*steppers[i].cnt = 0; | |
//TMR0CMP = (CLK_FREQ/frequency) - 1 ; | |
*steppers[i].ctl = _BV(TCTLENA)|_BV(TCTLCCM)|_BV(TCTLDIR)|_BV(TCTLCP0)|_BV(TCTLCP1)|_BV(TCTLCP2); | |
*steppers[i].pwml = 0; | |
*steppers[i].pwmh=10; | |
//*steppers[i].pwmctl=1; | |
//const int pin = WING_A_0; | |
//const int dirpin0 = WING_A_1; | |
pinMode(steppers[i].steppin, OUTPUT); | |
pinModePPS(steppers[i].steppin,HIGH); | |
outputPinForFunction(steppers[i].steppin,steppers[i].steppps); | |
pinMode(steppers[i].dirpin, OUTPUT); | |
pinModePPS(steppers[i].dirpin,HIGH); | |
outputPinForFunction(steppers[i].dirpin,steppers[i].dirpps); | |
pinMode(steppers[i].sleeppin, OUTPUT); | |
stepvars[i].lastPsc=1024; | |
} | |
setSteppersEnabled(1); | |
for(int i=0;i<nSwitches;i++){ | |
int pin =switchPins[i]; | |
pinMode(pin,INPUT); | |
//inputPinForFunction(pin,i); | |
switchStates[i]=0; | |
switchTimeLastChanged[i]=TIMERTSC; | |
} | |
pinMode(WING_A_7,INPUT); | |
pinMode(WING_A_8,INPUT); | |
pinMode(WING_A_9,INPUT); | |
pinMode(WING_A_10,INPUT); | |
pinMode(WING_A_11,INPUT); | |
pinMode(WING_A_12,INPUT); | |
TMR1CNT = 0; | |
//TMR1CMP = 4000000;//should be 24hz //Set in setFrameRate | |
setFrameRate(24); | |
TMR1CTL = _BV(TCTLENA)|_BV(TCTLCCM)|_BV(TCTLDIR)|_BV(TCTLIEN); | |
INTRMASK = _BV(INTRLINE_TIMER1); | |
INTRCTL = 1;//enable interrupts | |
} | |
const int debounceMicros = 1000000; | |
int checkSwitches(){ | |
for(int i=0;i<nSwitches;i++){ | |
//Serial.println(read); | |
if(switchHasSettled[i]||((TIMERTSC - switchTimeLastChanged[i]) > debounceMicros*96)){ | |
int read =digitalReadBool(switchPins[i]); | |
if(switchStates[i] != read){ | |
switchTimeLastChanged[i]=TIMERTSC; | |
switchHasSettled[i]=0; | |
switchStates[i]=read; | |
uint8_t buffer[8]; | |
uint8_t * buf_ptr= buffer; | |
store_u32(buf_ptr ,i);buf_ptr+=4;//Which Switch | |
store_u32(buf_ptr, read);buf_ptr+=4;//New Value | |
send_message(2,buffer,8); | |
break; | |
}else{ | |
switchHasSettled[i]=1; | |
} | |
}else{ | |
//Nothing. | |
} | |
} | |
} | |
volatile unsigned cycles(){ | |
return *(unsigned*) &TIMERTSC; | |
} | |
void setSteppersEnabled(int enabled){ | |
for(int i =0;i<3;i++){ | |
int old = *(steppers[i].pwmctl); | |
if(enabled){ | |
old |= _BV(TPWMEN); | |
}else{ | |
old &= ~_BV(TPWMEN); | |
} | |
*(steppers[i].pwmctl)=old; | |
} | |
} | |
int readStringWithTimeout(void * buf, int len, unsigned timeoutMicros){ | |
//Serial.println("read"); | |
unsigned start_t = TIMERTSC; | |
for(int i=0;i<len;i++){ | |
if(TIMERTSC-start_t > timeoutMicros*96){ | |
//read failed timeout. | |
return 0; | |
} | |
while(!Serial.available()){ | |
if(TIMERTSC-start_t > timeoutMicros*96){ | |
//read failed timeout. | |
return 0; | |
} | |
} | |
unsigned char read = Serial.read(); | |
*(((unsigned char*)buf)+i)=read; | |
} | |
//purge buffer | |
//Serial.flush(); | |
return 1; | |
} | |
unsigned char check_byte(unsigned char *buf, unsigned char n_bites){ | |
unsigned sum = 0; | |
for (unsigned char i=1;i<=n_bites;i++){ | |
sum+= i * buf[i-1]; | |
} | |
unsigned char ck_bite = sum & 0xFF; | |
return ck_bite; | |
} | |
unsigned char check_sum (unsigned char *buf, unsigned char n_bites) {//Consider the last byte in the buffer to be the check byte. | |
return check_byte_is(buf,n_bites) == check_byte_shouldbe(buf,n_bites); | |
} | |
unsigned char check_byte_is(unsigned char *buf, unsigned char n_bites) {//Consider the last byte in the buffer to be the check byte. | |
return buf[n_bites-1]; | |
} | |
unsigned char check_byte_shouldbe(unsigned char *buf, unsigned char n_bites) {//Consider the last byte in the buffer to be the check byte. | |
return check_byte(buf, n_bites-1); | |
} | |
inline int prescalerToRegValue(uint16_t psc){ | |
if(psc ==1){ | |
return 0; | |
}else if(psc==2){ | |
return 1; | |
}else if(psc==4){ | |
return 2; | |
}else if(psc==8){ | |
return 3; | |
}else if(psc==16){ | |
return 4; | |
}else if(psc==64){ | |
return 5; | |
}else if(psc==256){ | |
return 6; | |
}else if(psc==1024){ | |
return 7; | |
}else{ | |
return 0; | |
} | |
} | |
inline uint16_t regValueToPrescaler(int psc){ | |
if(psc ==0){ | |
return 1; | |
}else if(psc==1){ | |
return 2; | |
}else if(psc==2){ | |
return 4; | |
}else if(psc==3){ | |
return 8; | |
}else if(psc==4){ | |
return 16; | |
}else if(psc==5){ | |
return 64; | |
}else if(psc==6){ | |
return 256; | |
}else if(psc==7){ | |
return 1024; | |
}else{ | |
return 0; | |
} | |
} | |
inline void setPrescaler(volatile unsigned int * tctl, uint16_t psc){ | |
int regvalue = prescalerToRegValue(psc); | |
int old = *tctl; | |
old &= ~ (7*_BV(TCTLCP0)); | |
old |= regvalue*_BV(TCTLCP0); | |
*tctl = old; | |
} | |
inline uint16_t getPrescaler(volatile unsigned int * tctl){ | |
int val = *tctl; | |
val &= (7*_BV(TCTLCP0)); | |
val /= _BV(TCTLCP0); | |
return regValueToPrescaler(val); | |
} | |
inline void setTimerSyncImmediately(volatile unsigned int * tctl,int on){ | |
int old = *tctl; | |
if(on){ | |
old &= ~ TCTL_UPDATE_ZERO_SYNC; | |
}else{ | |
old |= TCTL_UPDATE_ZERO_SYNC; | |
} | |
*tctl = old; | |
} | |
inline uint16_t calcPrescaler(double period){ | |
// If[time < 1/1100, 0, Clip[Floor[72000000 time/(2^16)], {0, (2^16) - 1}]] | |
int ideal= 1+(int)(min(96*period/(65536.0),65534.0)); | |
//1 | |
//2 | |
//4 | |
//8 | |
//16 | |
//64 | |
//256 | |
//1024 | |
if(ideal<3){ | |
}else if(ideal==3){ | |
ideal=4; | |
}else if(ideal >4 && ideal <=8){ | |
ideal=8; | |
}else if(ideal >8 && ideal <= 16){ | |
ideal=16; | |
}else if(ideal >16 && ideal <= 64){ | |
ideal=64; | |
}else if(ideal >64 && ideal <= 256){ | |
ideal=256; | |
}else if(ideal >256){ | |
ideal=1024; | |
} | |
return ideal; | |
} | |
inline uint16_t calcDivGivenClk(double period, double clk){ | |
//findBestDiv[desired_, clk_, range_] := Clip[Round[desired clk], {1, (2^16) - 1}]; | |
return round(min(max(period * clk,1.0),65535.0)); | |
} | |
inline uint16_t calcDivGivenPsc (double period, uint16_t psc){ | |
// bestWithPrescaler[desired_, psc_] := Module[{clk = 72000000}, | |
// findBestDiv[desired, clk/(psc + 1), 1] | |
return calcDivGivenClk(period,96.0/psc); | |
} | |
inline double periodGivenPscDiv(int psc, int div){ | |
return psc*div/96.0; | |
} | |
inline struct frameCommand getNextPosition(){ | |
if(curfreq==100 && freqdir==1){freqdir = (-1);} | |
if(curfreq==0 && freqdir==-1){freqdir= 1;} | |
curfreq+=freqdir*5; | |
desired+=(curfreq*50 -2500); | |
struct frameCommand cmd; | |
cmd.desiredPos[0]=desired; | |
return cmd; | |
} | |
unsigned timeToWaitBeforeResendingMicros = 2000*1000; | |
unsigned timeToShutUpForMicros = 2000*1000; | |
volatile unsigned lastFrameStartedAt=0; | |
unsigned waitingSince=0; | |
unsigned timeShutUp=0; | |
unsigned nextFrameIdToRecieve=0; | |
unsigned lastFrameIdProcessed=0; | |
int waiting=0; | |
int connected=0; | |
inline void setStepperMoving(int stepper,int onoff){ | |
if(onoff){ | |
*steppers[stepper].maxovershoot=maxOvershoot[stepper]; | |
digitalWrite(steppers[stepper].sleeppin,0); | |
}else{ | |
*steppers[stepper].maxovershoot=0; | |
digitalWrite(steppers[stepper].sleeppin,1); | |
} | |
} | |
void _zpu_interrupt(){ | |
if(TMR1CTL & _BV(TCTLIF)){ | |
idum = 1664525L*idum + 1013904223L; | |
unsigned frequency = idum >> 24; | |
double freq = idum >>26; | |
if(!wb_is_empty(&wingBuf1)){ | |
struct frameCommand cmd = wb_remove(&wingBuf1); | |
lastFrameIdProcessed++; | |
for(int i =0;i<3;i++){ | |
int desired = cmd.desiredPos[i]; | |
int current = *steppers[i].steps; | |
int needed =current - desired; | |
needed=abs(needed); | |
freq = curfreq*500; | |
double perd = 1000000.0/freq; | |
if(needed){ | |
setStepperMoving(i,1); | |
perd = microsPerFrameFudged/needed; | |
//perd /=2; | |
//perd *= fudgeFactor; | |
uint16_t psc = calcPrescaler(perd); | |
unsigned cmp = calcDivGivenPsc(perd,psc); | |
//if(cmp != lastCmp){ | |
*steppers[i].cmp = cmp; | |
*steppers[i].pwmh = cmp/2; | |
lastCmp=cmp; | |
//} | |
if(psc != stepvars[i].lastPsc){ | |
setPrescaler(steppers[i].ctl,psc); | |
stepvars[i].lastPsc=psc; | |
} | |
}else{ | |
//no movement needed on this axis | |
setStepperMoving(i,0); | |
} | |
*steppers[i].desired=desired; | |
/* | |
Serial.print(desired); | |
Serial.print(" "); | |
Serial.print(needed); | |
Serial.print(" "); | |
Serial.print(lastPsc); | |
Serial.print(" "); | |
Serial.print(lastCmp); | |
Serial.print(" "); | |
Serial.println(current); | |
*/ | |
} | |
}else{ | |
//buffer empty | |
for(int i =0;i<3;i++){ | |
setStepperMoving(i,0); | |
} | |
} | |
TMR1CTL &= ~_BV(TCTLIF); | |
} | |
} | |
inline int from_bits(int val, int bits){ | |
int x=1; | |
x<<=(bits); | |
x = val - (x/2) + 1; | |
return x; | |
} | |
inline int read_bit_from_byte(unsigned char * bytes, int bit){ | |
int bite=bit/8; | |
bit = bit % 8; | |
bit = 1<<(7-bit); | |
bite = bytes[bite]; | |
bit = bite & bit; | |
if(bit){return 1 ;} | |
return 0; | |
} | |
inline int read_num_from_bytes(unsigned char * bytes, int index,int bits){ | |
int num=0; | |
//for my $bit (1 .. $bits){ | |
for(int bit=1;bit<=bits;bit++){ | |
num |= read_bit_from_byte(bytes,index+bit-1)<<(bits-bit); | |
} | |
return num; | |
} | |
inline struct frameCommand add_frames(struct frameCommand f1, struct frameCommand f2){ | |
struct frameCommand cmd; | |
for(int i =0;i<3;i++){ | |
cmd.desiredPos[i]=f1.desiredPos[i]+f2.desiredPos[i]; | |
} | |
return cmd; | |
} | |
const int nMaxIntFrames=8; | |
struct frameCommand previous_frames[nMaxIntFrames]; | |
struct frameCommand startingPosition; | |
struct frameCommand acc_frame(struct frameCommand new_frame, int level){ | |
previous_frames[0]=new_frame; | |
for(int i=1;i<=level;i++){ | |
previous_frames[i]=add_frames(previous_frames[i-1],previous_frames[i]); | |
} | |
return add_frames(previous_frames[level],startingPosition); | |
} | |
void reset_integrator(){ | |
for(int i=0;i<nMaxIntFrames;i++){ | |
struct frameCommand empty; | |
empty.desiredPos[0]=0; | |
empty.desiredPos[1]=0; | |
empty.desiredPos[2]=0; | |
previous_frames[i]=empty; | |
} | |
} | |
void setStepperPositions(int * positions){ | |
setSteppersEnabled(0); | |
struct frameCommand pretendFrame; | |
for(int i=0;i<3;i++){ | |
*steppers[i].desired=positions[i]; | |
*steppers[i].steps=positions[i]; | |
pretendFrame.desiredPos[i]=positions[i]; | |
} | |
setSteppersEnabled(1); | |
startingPosition = pretendFrame; | |
} | |
void sendStepperPositions(){ | |
uint8_t output_buf[63]; | |
uint8_t * buf_ptr= output_buf; | |
for(int i=0;i<3;i++){ | |
store_u32(buf_ptr ,*steppers[i].desired);buf_ptr+=4; | |
} | |
send_message(4,output_buf,20); //4=readout positions | |
} | |
uint8_t msgid=0; | |
void send_message(uint8_t ctlCode, const uint8_t * data, int nBytes){ | |
if(!waiting){ | |
uint8_t output_buf [63]; | |
uint8_t * buf_ptr= output_buf; | |
*buf_ptr = ctlCode;buf_ptr++; | |
*buf_ptr = msgid;buf_ptr++;msgid++; | |
int i=0; | |
for(;i<nBytes;i++){ | |
*buf_ptr = data[i];buf_ptr++; | |
} | |
for(;i<=61;i++){ | |
*buf_ptr = ' ';buf_ptr++; | |
} | |
output_buf[62]=check_byte((uint8_t*)output_buf,62); | |
int human=0; | |
if(human){ | |
for(int j=0;j<=62;j++){ | |
if(output_buf[j]<100) | |
Serial.print(' '); | |
if(output_buf[j]<10) | |
Serial.print(' '); | |
Serial.print(output_buf[j]); | |
Serial.print(' '); | |
} | |
Serial.print('\n'); | |
}else{ | |
Serial.write(output_buf,63); | |
} | |
waiting=1; | |
waitingSince=TIMERTSC; | |
} | |
} | |
void send_debug(const char* msg){ | |
int len=0; | |
for(int i=0;i<62;i++){ | |
if(msg[i]!=0){ | |
len=i; | |
}else{ | |
break; | |
} | |
} | |
send_message(3,(const uint8_t*)msg,len+1); | |
} | |
int iWasToldToShutUp=0; | |
struct frameCommand lastInsertedFrameCopy; | |
void loop() { | |
if( Serial.available()){ | |
static unsigned char cmd_buf [255]; | |
unsigned char * cmd_idx = cmd_buf; | |
if(readStringWithTimeout(cmd_buf,255,30*1000)){ | |
//Serial.println(" good read"); | |
waiting=0; | |
iWasToldToShutUp=0; | |
if(check_sum((unsigned char*)cmd_buf,255)){ | |
//Serial.println("checksum passed"); | |
unsigned char controlCode=*(unsigned char *) cmd_idx; | |
cmd_idx++; | |
switch(controlCode){ | |
case 0: connected=0;break;//Got Nothing | |
case 1: //Connect Signal | |
connected=1; | |
send_debug("penetrated"); | |
break; | |
case 2: //Reset Yourself | |
{ | |
iWasToldToShutUp=0; | |
wb_reset(&wingBuf1);//Empty buffer | |
nextFrameIdToRecieve=0; | |
lastFrameIdProcessed=0; | |
reset_integrator(); | |
//Dont set position to 0 | |
//int positions[3]={0,0,0}; | |
//setStepperPositions(positions); | |
//But do read out the current position. | |
sendStepperPositions(); | |
} | |
break; | |
case 3: //Feed frames | |
{ | |
int int_sent = read_u32( cmd_idx);cmd_idx += 4; | |
unsigned framesStartingFrom = read_u32( cmd_idx);cmd_idx += 4; | |
if(framesStartingFrom != nextFrameIdToRecieve){ | |
//host sent us the wrong data or something | |
/*Serial.println("wrong data");*/ | |
goto endcase; | |
} | |
int axisSizes[3]; | |
for(int i =0;i<3;i++){ | |
axisSizes[i]= read_num_from_bytes(cmd_idx,i*5,5); | |
} | |
cmd_idx += 2; | |
int bit_ptr=0; | |
for(int i=0;i<int_sent;i++){ | |
if(!wb_is_full(&wingBuf1)){ | |
struct frameCommand cmd; | |
/* | |
uint32_t * b = (uint32_t *) &cmd; | |
for(int j=0;j<sizeof(struct frameCommand);j+=4){ | |
*b=read_u32(cmd_idx+j); | |
b++; | |
} | |
*/ | |
//unsigned pos = read_u32(cmd_idx); | |
for(int j =0;j<3;j++){ | |
//cmd.desiredPos[j]=pos/(j+1); | |
int length=axisSizes[j]; | |
int data = read_num_from_bytes(cmd_idx,bit_ptr,length); | |
bit_ptr+=length; | |
data = from_bits(data,length); | |
cmd.desiredPos[j]=data; | |
} | |
cmd = acc_frame(cmd,3); | |
wb_insert(&wingBuf1, cmd); | |
lastInsertedFrameCopy=cmd; | |
nextFrameIdToRecieve++; | |
}else{ | |
/*Serial.println("buffer full");*/ | |
goto endcase; | |
} | |
//cmd_idx+=sizeof(struct frameCommand); | |
//cmd_idx += 4; | |
} | |
} | |
endcase:0; | |
break; | |
case 4: //Set Frame Rate, Fudge Factor | |
{ | |
int new_rate = read_u32( cmd_idx); | |
cmd_idx+=4; | |
fudgeFactor = (double)read_u32( cmd_idx)/1000000.0; | |
cmd_idx+=4; | |
wb_reset(&wingBuf1);//Empty buffer | |
setFrameRate(new_rate); | |
} | |
break; | |
case 5: //Purge Buffer. (stop executing frames.) | |
{ | |
wb_reset(&wingBuf1);//Empty buffer | |
} | |
break; | |
case 6: //Acknowledge. | |
break; | |
case 7: //I don't have any data for you, stop asking. | |
{ | |
iWasToldToShutUp=1; | |
timeShutUp=TIMERTSC; | |
} | |
break; | |
case 8: //Define where you are currently at as an XYZ coordinate. | |
{ | |
int positions[3]; | |
for(int i=0;i<3;i++){ | |
positions[i] =read_u32(cmd_idx);cmd_idx+=4; | |
} | |
setStepperPositions(positions); | |
} | |
break; | |
case 9: //sendStepperPositions | |
{ | |
sendStepperPositions(); | |
}break; | |
default:/*Serial.print("ControlCode");Serial.println(controlCode);*/ break; | |
} | |
}else{ | |
send_debug((char *)cmd_buf); | |
//send_debug("checksum fail"); | |
} | |
}else{ | |
//send_debug("failed read"); | |
} | |
} | |
if(!waiting){ | |
checkSwitches(); | |
} | |
if(!waiting && (wb_room_left(&wingBuf1) > 200) && !iWasToldToShutUp){ | |
uint8_t output_buf[63]; | |
uint8_t * buf_ptr= output_buf; | |
store_u32(buf_ptr ,nextFrameIdToRecieve);buf_ptr+=4; | |
store_u32(buf_ptr, lastFrameIdProcessed);buf_ptr+=4; | |
store_u32(buf_ptr, TMR0QUAD);buf_ptr+=4; | |
*buf_ptr=111;buf_ptr++; | |
*buf_ptr=digitalReadBool(WING_A_7);buf_ptr++; | |
*buf_ptr=digitalReadBool(WING_A_8);buf_ptr++; | |
send_message(1,output_buf,20); | |
} | |
if(waiting && (TIMERTSC-waitingSince) > (timeToWaitBeforeResendingMicros*96)){ | |
waiting=0; | |
} | |
if(iWasToldToShutUp && (TIMERTSC-timeShutUp) > (timeToShutUpForMicros*96) ){ | |
iWasToldToShutUp=0;//Decide that you have shut up for long enough. Time to beg again. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment