Code to drive a CNC machine via a PC LPT port lookalike 25 pin 'D', experiment in 'PC/Mach3' replacement. Designed to compile and run on mbed LPC1768, Freescale KL25Z and Freescale KL46Z. Proved on LPC1768 and KL25Z, problem with serial port on KL46Z. Reads subset of 'G Codes' through usb/serial port and drives 3 stepper/servo drives for X, Y and Z, also similar Step/Dir outputs for spindle motor control. Emulates PC LPT, outputs 'charge pump', proved driving Seig KX3 CNC mill

Dependencies:   MODSERIAL mbed

Committer:
JonFreeman
Date:
Thu Feb 20 09:27:18 2014 +0000
Revision:
2:b3c668ec43ac
Parent:
1:66ee619f206b
Child:
3:7aaf0072cc22
As used to produce Lissajous patterns for EiM articles.  XYZ axis good, Axis A not implemented, spindle 'S' working.  Using MODSERIAL, therefore no longer compatible with KL46Z, good for KL25Z and Mbed LPC1768

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JonFreeman 0:5d0f270bfc87 1 #include "mbed.h"
JonFreeman 1:66ee619f206b 2 #include "rtos.h"
JonFreeman 2:b3c668ec43ac 3 #include "MODSERIAL.h"
JonFreeman 0:5d0f270bfc87 4 #include "cnc.h"
JonFreeman 0:5d0f270bfc87 5 using namespace std;
JonFreeman 1:66ee619f206b 6 extern void command_line_interpreter (void const *) ;
JonFreeman 2:b3c668ec43ac 7 //extern void lissajous (void const *) ;
JonFreeman 2:b3c668ec43ac 8 extern double feed_rate, spindle_rpm;
JonFreeman 1:66ee619f206b 9 extern void more_setup () ;
JonFreeman 2:b3c668ec43ac 10 extern struct Gparams last_position;
JonFreeman 0:5d0f270bfc87 11
JonFreeman 1:66ee619f206b 12 const int BAUD = 38400;
JonFreeman 2:b3c668ec43ac 13 MODSERIAL pc(USBTX, USBRX); // tx, rx to pc
JonFreeman 2:b3c668ec43ac 14 //Serial pc(USBTX, USBRX); // tx, rx to pc
JonFreeman 1:66ee619f206b 15 Ticker NCO_gen; // Ticker generating interrupts at "Kernel Speed", NCO updating frequency (about 40kHz)
JonFreeman 0:5d0f270bfc87 16
JonFreeman 1:66ee619f206b 17 bool running = false, new_run_pending = false, idle = false, move_ended = false;
JonFreeman 1:66ee619f206b 18 volatile unsigned long ticks = 0L; // 32 bit count of "interrupt_period_us" interrupts from time t=0
JonFreeman 1:66ee619f206b 19 unsigned long tickrun = 0L; // 32 bit effectively stores time in future when current movement to stop
JonFreeman 1:66ee619f206b 20 unsigned long ticks_next = 0L; // 32 bit effectively stores time in future when current movement to stop
JonFreeman 2:b3c668ec43ac 21 unsigned long millisecs = 0L; // 32 bit
JonFreeman 1:66ee619f206b 22 unsigned long pir_a = 0L, // Phase Increment Registers
JonFreeman 0:5d0f270bfc87 23 pir_x = 0L,
JonFreeman 0:5d0f270bfc87 24 pir_y = 0L,
JonFreeman 0:5d0f270bfc87 25 pir_z = 0L,
JonFreeman 1:66ee619f206b 26 pir_a_next = 0L, // Data for next move assembled here
JonFreeman 1:66ee619f206b 27 pir_x_next = 0L, // during a move.
JonFreeman 1:66ee619f206b 28 pir_y_next = 0L, // This way, next move can start immediately
JonFreeman 1:66ee619f206b 29 pir_z_next = 0L, // on end of current move - minimised jerking
JonFreeman 2:b3c668ec43ac 30 pir_spin = 0L; // Referenced only in command_interpreter as spindle speed setting
JonFreeman 1:66ee619f206b 31
JonFreeman 0:5d0f270bfc87 32
JonFreeman 1:66ee619f206b 33
JonFreeman 0:5d0f270bfc87 34 #if defined (TARGET_KL25Z)
JonFreeman 2:b3c668ec43ac 35 const char Target[] = "KL25Z";
JonFreeman 2:b3c668ec43ac 36 DigitalOut intled (PTE1); //J2p20
JonFreeman 2:b3c668ec43ac 37 DigitalOut charge_pumpD25pin1 (PTE0); //J2p18
JonFreeman 2:b3c668ec43ac 38 // InterruptIn D25pin10_EStop (PTE20); //j10p1 KL25 J10 is KL46 j4
JonFreeman 2:b3c668ec43ac 39 DigitalIn D25pin10_EStop (PTE20); //j10p1 KL25 J10 is KL46 j4
JonFreeman 2:b3c668ec43ac 40 DigitalIn D25pin11_XLim (PTE21); //j10p3
JonFreeman 2:b3c668ec43ac 41 DigitalIn D25pin12_YLim (PTE22); //j10p5
JonFreeman 2:b3c668ec43ac 42 DigitalIn D25pin13_ZLim (PTE23); //j10p7
JonFreeman 2:b3c668ec43ac 43 DigitalIn D25pin15_unkn (PTE30); //j10p11
JonFreeman 0:5d0f270bfc87 44 //SPISlave spidevice(PTD3, PTD2, PTD1, PTD0); // mosi, miso, sclk THIS TURNS LED ON BLUE ! (uses p11, p12, p13 on mbed LPC)
JonFreeman 0:5d0f270bfc87 45 SPISlave spidevice(PTD2, PTD3, PTD1, PTD0); // mosi, miso, sclk THIS TURNS LED ON BLUE ! (uses p11, p12, p13 on mbed LPC)
JonFreeman 0:5d0f270bfc87 46 // J2p08,J2p10,J2p12, J2p06
JonFreeman 0:5d0f270bfc87 47 //SPI spidevice(PTD2, PTD3, PTD1); // mosi, miso, sclk THIS TURNS LED ON BLUE ! (uses p11, p12, p13 on mbed LPC)
JonFreeman 0:5d0f270bfc87 48 //SPI spidevice(PTD3, PTD2, PTD1); // mosi, miso, sclk THIS TURNS LED ON BLUE ! (uses p11, p12, p13 on mbed LPC)
JonFreeman 0:5d0f270bfc87 49 //NOTE doubt possibly miso mosi in wrong order here, PTD3 and PTD2
JonFreeman 0:5d0f270bfc87 50 #define STEPPER_PORT PortC
JonFreeman 2:b3c668ec43ac 51 const int PortBitXSt = 3, // Port bit num X Step J1P05 D25pin 2
JonFreeman 2:b3c668ec43ac 52 PortBitXDi = 4, // Port bit num X Dir J1P07 D25pin 3
JonFreeman 2:b3c668ec43ac 53 PortBitYSt = 5, // Port bit num Y Step J1P09 D25pin 4
JonFreeman 2:b3c668ec43ac 54 PortBitYDi = 6, // Port bit num Y Dir J1P11 D25pin 5
JonFreeman 2:b3c668ec43ac 55 PortBitZSt = 10, // Port bit num Z Step J1P13 D25pin 6
JonFreeman 2:b3c668ec43ac 56 PortBitZDi = 11, // Port bit num Z Dir J1P15 D25pin 7
JonFreeman 2:b3c668ec43ac 57 PortBitASt = 12, // Port bit num A Step J2P01 D25pin 8
JonFreeman 2:b3c668ec43ac 58 PortBitADi = 13, // Port bit num A Dir J2P03 D25pin 9
JonFreeman 2:b3c668ec43ac 59 PortBitSSt = 8, // Port bit num Spin Step J1P14 D25pin 14
JonFreeman 2:b3c668ec43ac 60 PortBitSDi = 9; // Port bit num Spin Dir J1P16 D25pin 16
JonFreeman 0:5d0f270bfc87 61 #endif
JonFreeman 2:b3c668ec43ac 62
JonFreeman 2:b3c668ec43ac 63
JonFreeman 2:b3c668ec43ac 64
JonFreeman 0:5d0f270bfc87 65 #if defined (TARGET_KL46Z)
JonFreeman 2:b3c668ec43ac 66 const char Target[] = "KL46Z";
JonFreeman 2:b3c668ec43ac 67 DigitalOut intled (PTE1); //J2p20 checked
JonFreeman 2:b3c668ec43ac 68
JonFreeman 2:b3c668ec43ac 69
JonFreeman 2:b3c668ec43ac 70 DigitalOut charge_pumpD25pin1 (PTE0); //J2p18 checked
JonFreeman 2:b3c668ec43ac 71 // InterruptIn D25pin10_EStop (PTE20); // j4p1 KL46 J4 is KL25 J10
JonFreeman 2:b3c668ec43ac 72 DigitalIn D25pin10_EStop (PTE20); // j4p1 KL46 J4 is KL25 J10 checked
JonFreeman 2:b3c668ec43ac 73 DigitalIn D25pin11_XLim (PTE21); // j4p3 checked
JonFreeman 2:b3c668ec43ac 74 DigitalIn D25pin12_YLim (PTE22); // j4p5 checked
JonFreeman 2:b3c668ec43ac 75 DigitalIn D25pin13_ZLim (PTE23); // j4p7 checked
JonFreeman 2:b3c668ec43ac 76 DigitalIn D25pin15_unkn (PTE30); // j4p11 checked
JonFreeman 0:5d0f270bfc87 77 SPISlave spidevice(PTA16, PTA17, PTA15, PTA14); // mosi, miso, sclk, ssel (uses p11, p12, p13, p? on mbed LPC)
JonFreeman 0:5d0f270bfc87 78 // J2p13, J2p15, J2p11, J2p09
JonFreeman 2:b3c668ec43ac 79 // Easy way to allocate port bits for
JonFreeman 0:5d0f270bfc87 80 // output of stepper motor Step and DIR sigs
JonFreeman 0:5d0f270bfc87 81 #define STEPPER_PORT PortC
JonFreeman 2:b3c668ec43ac 82 const int PortBitXSt = 0, // Port bit num X Step J1P05 D25pin 2 checked
JonFreeman 2:b3c668ec43ac 83 PortBitXDi = 4, // Port bit num X Dir J1P07 D25pin 3 checked
JonFreeman 2:b3c668ec43ac 84 PortBitYSt = 6, // Port bit num Y Step J1P09 D25pin 4 checked
JonFreeman 2:b3c668ec43ac 85 PortBitYDi = 7, // Port bit num Y Dir J1P11 D25pin 5 checked
JonFreeman 2:b3c668ec43ac 86 PortBitZSt = 10, // Port bit num Z Step J1P13 D25pin 6 checked
JonFreeman 2:b3c668ec43ac 87 PortBitZDi = 11, // Port bit num Z Dir J1P15 D25pin 7 checked
JonFreeman 2:b3c668ec43ac 88 PortBitASt = 13, // Port bit num A Step J2P01 D25pin 8 checked
JonFreeman 2:b3c668ec43ac 89 PortBitADi = 16, // Port bit num A Dir J2P03 D25pin 9 checked
JonFreeman 2:b3c668ec43ac 90 PortBitSSt = 8, // Port bit num Spin Step J1P14 D25pin 14 checked
JonFreeman 2:b3c668ec43ac 91 PortBitSDi = 9; // Port bit num Spin Dir J1P16 D25pin 16 checked
JonFreeman 0:5d0f270bfc87 92 #endif
JonFreeman 0:5d0f270bfc87 93 #if defined (TARGET_MBED_LPC1768)
JonFreeman 2:b3c668ec43ac 94 const char Target[] = "MBED LPC1768";
JonFreeman 1:66ee619f206b 95 DigitalOut intled(LED2); // Correct
JonFreeman 2:b3c668ec43ac 96 DigitalOut charge_pumpD25pin1 (p25); //J2p18 Following 5 inputs all wrong - TO DO sort which pins
JonFreeman 2:b3c668ec43ac 97 // InterruptIn D25pin10_EStop (p26); //P2.0
JonFreeman 2:b3c668ec43ac 98 DigitalIn D25pin10_EStop (p26); //P2.0
JonFreeman 2:b3c668ec43ac 99 DigitalIn D25pin11_XLim (p24); //P2.2
JonFreeman 2:b3c668ec43ac 100 DigitalIn D25pin12_YLim (p23); //P2.3
JonFreeman 2:b3c668ec43ac 101 DigitalIn D25pin13_ZLim (p19); //P1.30
JonFreeman 2:b3c668ec43ac 102 DigitalIn D25pin15_unkn (p20); //P1.31
JonFreeman 0:5d0f270bfc87 103 SPISlave spidevice(p5, p6, p7, p8);
JonFreeman 0:5d0f270bfc87 104 // Easy way to allocate port bits for *** N O T CHECKED for MBED_LPC1768 ***
JonFreeman 0:5d0f270bfc87 105 // output of stepper motor Step and DIR sigs
JonFreeman 0:5d0f270bfc87 106 #define STEPPER_PORT Port0
JonFreeman 0:5d0f270bfc87 107 /* Port 0 bits routed to DIP pins as follows:-
JonFreeman 0:5d0f270bfc87 108 P0.00 p09 Reserve SDA
JonFreeman 0:5d0f270bfc87 109 P0.01 p10 Reserve SCL
JonFreeman 2:b3c668ec43ac 110 P0.04 p30 CAN rd - USE X Step D25pin 2
JonFreeman 2:b3c668ec43ac 111 P0.05 p29 CAN td - USE X Dir D25pin 3
JonFreeman 2:b3c668ec43ac 112 P0.10 p28 SDA - USE Y Step D25pin 4
JonFreeman 2:b3c668ec43ac 113 P0.11 p27 SCL - USE Y Dir D25pin 5
JonFreeman 2:b3c668ec43ac 114 P0.15 p13 Tx - USE Z Step D25pin 6
JonFreeman 2:b3c668ec43ac 115 P0.16 p14 Rx - USE Z Dir D25pin 7
JonFreeman 2:b3c668ec43ac 116 P0.17 p12 miso - USE A Step D25pin 8
JonFreeman 2:b3c668ec43ac 117 P0.18 p11 mosi - Use A Dir D25pin 9
JonFreeman 2:b3c668ec43ac 118 P0.23 p15 A In - Use S Step D25pin 14
JonFreeman 2:b3c668ec43ac 119 P0.24 p16 A In - Use S Dir D25pin 16
JonFreeman 2:b3c668ec43ac 120 P0.25 p17 Reserve A In
JonFreeman 0:5d0f270bfc87 121 P0.26 p18 Reserve A Out
JonFreeman 0:5d0f270bfc87 122 */
JonFreeman 2:b3c668ec43ac 123 const int PortBitXSt = 4, // Port bit num X Step
JonFreeman 2:b3c668ec43ac 124 PortBitXDi = 5, // Port bit num X Dir
JonFreeman 2:b3c668ec43ac 125 PortBitYSt = 10, // Port bit num Y Step
JonFreeman 2:b3c668ec43ac 126 PortBitYDi = 11, // Port bit num Y Dir
JonFreeman 2:b3c668ec43ac 127 PortBitZSt = 15, // Port bit num Z Step
JonFreeman 2:b3c668ec43ac 128 PortBitZDi = 16, // Port bit num Z Dir
JonFreeman 2:b3c668ec43ac 129 PortBitASt = 17, // Port bit num A Step
JonFreeman 2:b3c668ec43ac 130 PortBitADi = 18, // Port bit num A Dir
JonFreeman 2:b3c668ec43ac 131 PortBitSSt = 23, // Port bit num Spin Step
JonFreeman 2:b3c668ec43ac 132 PortBitSDi = 24; // Port bit num Spin Dir
JonFreeman 0:5d0f270bfc87 133 #endif
JonFreeman 0:5d0f270bfc87 134
JonFreeman 2:b3c668ec43ac 135 const long // Assemble mask bits from now known port bit positions
JonFreeman 2:b3c668ec43ac 136 XSt = 1 << PortBitXSt, // X axis Step signal
JonFreeman 2:b3c668ec43ac 137 XDi = 1 << PortBitXDi, // X axis Direction signal
JonFreeman 2:b3c668ec43ac 138 YSt = 1 << PortBitYSt, // Y axis Step, etc
JonFreeman 2:b3c668ec43ac 139 YDi = 1 << PortBitYDi,
JonFreeman 2:b3c668ec43ac 140 ZSt = 1 << PortBitZSt, // Z axis
JonFreeman 2:b3c668ec43ac 141 ZDi = 1 << PortBitZDi,
JonFreeman 2:b3c668ec43ac 142 ASt = 1 << PortBitASt, // A axis, not implemented in full, for e.g. rotary axis
JonFreeman 2:b3c668ec43ac 143 ADi = 1 << PortBitADi,
JonFreeman 2:b3c668ec43ac 144 SDi = 1 << PortBitSDi, // Spindle, also driven by Step and Dir signals up to 5kHz
JonFreeman 2:b3c668ec43ac 145 SSt = 1 << PortBitSSt, // for 5000 RPM
JonFreeman 2:b3c668ec43ac 146
JonFreeman 2:b3c668ec43ac 147 SM_MASK = (XSt | XDi | YSt | YDi | ZSt | ZDi | ASt | ADi | SDi | SSt);
JonFreeman 0:5d0f270bfc87 148
JonFreeman 2:b3c668ec43ac 149 PortOut Steppers (STEPPER_PORT, SM_MASK);
JonFreeman 2:b3c668ec43ac 150 const long direction_swappers = XDi | YDi | ZDi | SDi; // include bit to swap direction
JonFreeman 2:b3c668ec43ac 151 /*
JonFreeman 2:b3c668ec43ac 152 long read () {
JonFreeman 2:b3c668ec43ac 153 return mysteppers ^ direction_swappers;
JonFreeman 2:b3c668ec43ac 154 }
JonFreeman 2:b3c668ec43ac 155 void write (long val) {
JonFreeman 2:b3c668ec43ac 156 mysteppers = val ^ direction_swappers;
JonFreeman 2:b3c668ec43ac 157 }
JonFreeman 2:b3c668ec43ac 158 */
JonFreeman 2:b3c668ec43ac 159 class digital_readout_stuff { // class does not need to be named here
JonFreeman 2:b3c668ec43ac 160 private:
JonFreeman 2:b3c668ec43ac 161 char * readout (char * txt, long p) // p has running subtotal of all pulses issued to stepper driver
JonFreeman 2:b3c668ec43ac 162 {
JonFreeman 2:b3c668ec43ac 163 txt[0] = '+'; // constructs string e.g. "+123.456"
JonFreeman 2:b3c668ec43ac 164 txt[8] = 0; // null terminated
JonFreeman 2:b3c668ec43ac 165 if (p < 0) {
JonFreeman 2:b3c668ec43ac 166 txt[0] = '-';
JonFreeman 2:b3c668ec43ac 167 p = -p;
JonFreeman 2:b3c668ec43ac 168 }
JonFreeman 2:b3c668ec43ac 169 p *= 1000;
JonFreeman 2:b3c668ec43ac 170 p /= pulses_per_mm;
JonFreeman 2:b3c668ec43ac 171 if (p > 999999) {
JonFreeman 2:b3c668ec43ac 172 sprintf(txt + 1, "OVRANGE");
JonFreeman 2:b3c668ec43ac 173 return txt;
JonFreeman 2:b3c668ec43ac 174 }
JonFreeman 2:b3c668ec43ac 175 for(int k = 7; k > 0; k--) {
JonFreeman 2:b3c668ec43ac 176 if (k == 4)
JonFreeman 2:b3c668ec43ac 177 txt[k] = '.';
JonFreeman 2:b3c668ec43ac 178 else {
JonFreeman 2:b3c668ec43ac 179 txt[k] = '0' + (p % 10);
JonFreeman 2:b3c668ec43ac 180 p /= 10;
JonFreeman 2:b3c668ec43ac 181 }
JonFreeman 2:b3c668ec43ac 182 }
JonFreeman 2:b3c668ec43ac 183 return txt; // Returns pointer unaltered for subsequent use by e.g. cout
JonFreeman 2:b3c668ec43ac 184 }
JonFreeman 2:b3c668ec43ac 185 public:
JonFreeman 2:b3c668ec43ac 186 signed long x, y, z, a; // Could easily expand up to six or more dros
JonFreeman 2:b3c668ec43ac 187 bool dro_output; // To enabe / disable output to terminal
JonFreeman 2:b3c668ec43ac 188 void init () {
JonFreeman 2:b3c668ec43ac 189 x = y = z = a = 0; // These dro registers count pulses delivered to stepper motor driver
JonFreeman 2:b3c668ec43ac 190 dro_output = true;
JonFreeman 2:b3c668ec43ac 191 }
JonFreeman 2:b3c668ec43ac 192 void update () {
JonFreeman 2:b3c668ec43ac 193 static long t = 300; // Prevent display immediately upon startup
JonFreeman 2:b3c668ec43ac 194 if (millisecs < t)
JonFreeman 2:b3c668ec43ac 195 return;
JonFreeman 2:b3c668ec43ac 196 if(!idle && dro_output) {
JonFreeman 2:b3c668ec43ac 197 char txt[12];
JonFreeman 2:b3c668ec43ac 198 pc.printf("dros X %s,", readout(txt, x)); // dro.n has running subtotal of all pulses issued to stepper driver.n
JonFreeman 2:b3c668ec43ac 199 pc.printf(" Y %s, Z ", readout(txt, y));
JonFreeman 2:b3c668ec43ac 200 pc.printf("%s, %s\r\n", readout(txt, z), running ? "R":"idle");
JonFreeman 2:b3c668ec43ac 201 if(!running) idle = true; // Purpose of idle flag is to stop dro updates JUST AFTER run completes.
JonFreeman 2:b3c668ec43ac 202 t = millisecs + 350; // Schedule next update after this non-blocking delay
JonFreeman 2:b3c668ec43ac 203 }
JonFreeman 2:b3c668ec43ac 204 }
JonFreeman 2:b3c668ec43ac 205 } dro_out ;
JonFreeman 0:5d0f270bfc87 206
JonFreeman 2:b3c668ec43ac 207 const int PIRBUFFSIZE = 40; // pirbufgrain are 40 bytes each
JonFreeman 1:66ee619f206b 208 class circbuff {
JonFreeman 1:66ee619f206b 209 private:
JonFreeman 1:66ee619f206b 210 pirbufgrain grain [PIRBUFFSIZE + 1];
JonFreeman 1:66ee619f206b 211 int OnPtr, OffPtr;
JonFreeman 1:66ee619f206b 212 bool bufffull, buffempty, buffhalf;
JonFreeman 1:66ee619f206b 213 void setempty () {
JonFreeman 1:66ee619f206b 214 bufffull = false;
JonFreeman 1:66ee619f206b 215 buffhalf = false;
JonFreeman 1:66ee619f206b 216 buffempty = true;
JonFreeman 1:66ee619f206b 217 }
JonFreeman 1:66ee619f206b 218 void grain_copy (pirbufgrain & src, pirbufgrain & dest) {
JonFreeman 1:66ee619f206b 219 dest.x = src.x;
JonFreeman 1:66ee619f206b 220 dest.y = src.y;
JonFreeman 1:66ee619f206b 221 dest.z = src.z;
JonFreeman 1:66ee619f206b 222 dest.c = src.c;
JonFreeman 1:66ee619f206b 223 dest.f_rate = src.f_rate; // int feed rate mm per min * 1000
JonFreeman 1:66ee619f206b 224 }
JonFreeman 1:66ee619f206b 225 public:
JonFreeman 1:66ee619f206b 226 void init () {
JonFreeman 1:66ee619f206b 227 OnPtr = OffPtr = 0;
JonFreeman 1:66ee619f206b 228 setempty ();
JonFreeman 1:66ee619f206b 229 }
JonFreeman 1:66ee619f206b 230 int On_Q () {
JonFreeman 1:66ee619f206b 231 int k;
JonFreeman 1:66ee619f206b 232 if (bufffull) return PIRBUFFSIZE;
JonFreeman 1:66ee619f206b 233 k = OnPtr - OffPtr;
JonFreeman 1:66ee619f206b 234 if (k < 0) k += PIRBUFFSIZE;
JonFreeman 1:66ee619f206b 235 if (k > PIRBUFFSIZE / 2)
JonFreeman 1:66ee619f206b 236 buffhalf = true;
JonFreeman 1:66ee619f206b 237 else
JonFreeman 1:66ee619f206b 238 buffhalf = false;
JonFreeman 1:66ee619f206b 239 return k;
JonFreeman 1:66ee619f206b 240 }
JonFreeman 1:66ee619f206b 241 bool readable () {return !buffempty; }
JonFreeman 1:66ee619f206b 242 bool writeable () {return !bufffull; }
JonFreeman 1:66ee619f206b 243 bool read (pirbufgrain & g) {
JonFreeman 2:b3c668ec43ac 244 // if (buffempty) return false; // TO DO Fix problem with buffempty flag
JonFreeman 2:b3c668ec43ac 245 if (On_Q() == 0) return false;
JonFreeman 1:66ee619f206b 246 bufffull = false;
JonFreeman 1:66ee619f206b 247 grain_copy (grain[OffPtr++], g);
JonFreeman 1:66ee619f206b 248 if (OffPtr >= PIRBUFFSIZE)
JonFreeman 1:66ee619f206b 249 OffPtr = 0;
JonFreeman 1:66ee619f206b 250 if (OnPtr == OffPtr)
JonFreeman 1:66ee619f206b 251 buffempty = true;
JonFreeman 1:66ee619f206b 252 return true;
JonFreeman 1:66ee619f206b 253 }
JonFreeman 1:66ee619f206b 254 bool write (pirbufgrain & g) {
JonFreeman 1:66ee619f206b 255 if (bufffull) return false;
JonFreeman 1:66ee619f206b 256 buffempty = false;
JonFreeman 1:66ee619f206b 257 grain_copy (g, grain[OnPtr++]);
JonFreeman 1:66ee619f206b 258 if (OnPtr >= PIRBUFFSIZE)
JonFreeman 1:66ee619f206b 259 OnPtr = 0;
JonFreeman 1:66ee619f206b 260 if (OnPtr == OffPtr)
JonFreeman 1:66ee619f206b 261 bufffull = true;
JonFreeman 1:66ee619f206b 262 return true;
JonFreeman 1:66ee619f206b 263 }
JonFreeman 1:66ee619f206b 264 } CircBuff;
JonFreeman 1:66ee619f206b 265
JonFreeman 1:66ee619f206b 266 int PutMoveOnList (struct pirbufgrain & s) {
JonFreeman 1:66ee619f206b 267 while (!CircBuff.writeable())
JonFreeman 1:66ee619f206b 268 osThreadYield();
JonFreeman 1:66ee619f206b 269 CircBuff.write (s); // pc.printf("CircBuff, contains %d\r\n", CircBuff.On_Q());
JonFreeman 1:66ee619f206b 270 return 0;
JonFreeman 1:66ee619f206b 271 }
JonFreeman 1:66ee619f206b 272
JonFreeman 2:b3c668ec43ac 273 const double duration_multiplier = 60000000.0 / interrupt_period_us;
JonFreeman 1:66ee619f206b 274
JonFreeman 2:b3c668ec43ac 275 void move_to_XYZ (struct pirbufgrain & ins) {
JonFreeman 2:b3c668ec43ac 276 struct pirbufgrain outs;
JonFreeman 2:b3c668ec43ac 277 double distx = ins.x - last_position.x.dbl,
JonFreeman 2:b3c668ec43ac 278 disty = ins.y - last_position.y.dbl,
JonFreeman 2:b3c668ec43ac 279 distz = ins.z - last_position.z.dbl,
JonFreeman 2:b3c668ec43ac 280 distT = sqrt ((distx * distx) + (disty * disty) + (distz * distz)), // 3D Pythag !
JonFreeman 2:b3c668ec43ac 281 temp = n_for_onemmpermin / distT;
JonFreeman 2:b3c668ec43ac 282 if (distT < 0.01) {
JonFreeman 2:b3c668ec43ac 283 pc.printf("Very small move %.4f, Ignoring!\r\n", distT);
JonFreeman 2:b3c668ec43ac 284 return;
JonFreeman 2:b3c668ec43ac 285 }
JonFreeman 2:b3c668ec43ac 286 last_position.x.dbl = ins.x; // Update global last_position record
JonFreeman 2:b3c668ec43ac 287 last_position.y.dbl = ins.y;
JonFreeman 2:b3c668ec43ac 288 last_position.z.dbl = ins.z;
JonFreeman 2:b3c668ec43ac 289 outs.f_rate = ins.f_rate;
JonFreeman 2:b3c668ec43ac 290 outs.c = duration_multiplier * distT; // Duration ticks subject to feed rate compo
JonFreeman 2:b3c668ec43ac 291 outs.x = temp * distx;
JonFreeman 2:b3c668ec43ac 292 outs.y = temp * disty;
JonFreeman 2:b3c668ec43ac 293 outs.z = temp * distz; // Have assembled data ready to put onto queue of move instructions
JonFreeman 2:b3c668ec43ac 294 PutMoveOnList (outs);
JonFreeman 2:b3c668ec43ac 295 }
JonFreeman 2:b3c668ec43ac 296
JonFreeman 2:b3c668ec43ac 297 void target_cmd (struct singleGparam * a) {
JonFreeman 2:b3c668ec43ac 298 pc.printf("Computer is %s\r\n", Target);
JonFreeman 2:b3c668ec43ac 299 }
JonFreeman 0:5d0f270bfc87 300 /*
JonFreeman 0:5d0f270bfc87 301 * Interrupt Service Routine
JonFreeman 0:5d0f270bfc87 302 */
JonFreeman 2:b3c668ec43ac 303 /* **** UNBROKEN VERSION 6th Feb 2014 ******************
JonFreeman 0:5d0f270bfc87 304 void Numerically_Controlled_Oscillators_ISR () { // services Ticker 'NCO_gen' generated interrupts ***ISR***
JonFreeman 1:66ee619f206b 305 static const int millisec_countdown = 1000 / interrupt_period_us;
JonFreeman 0:5d0f270bfc87 306 const long bit_lutx[4] = {XSt0 | XDi0, XSt0 | XDi1, XSt1 | XDi1, XSt1 | XDi0}, // Used to look-up 'clk' and 'dir' signals from accum MSBs
JonFreeman 0:5d0f270bfc87 307 bit_luty[4] = {YSt0 | YDi0, YSt0 | YDi1, YSt1 | YDi1, YSt1 | YDi0}, // Used to look-up 'clk' and 'dir' signals from accum MSBs
JonFreeman 0:5d0f270bfc87 308 bit_lutz[4] = {ZSt0 | ZDi0, ZSt0 | ZDi1, ZSt1 | ZDi1, ZSt1 | ZDi0}, // Used to look-up 'clk' and 'dir' signals from accum MSBs
JonFreeman 0:5d0f270bfc87 309 bit_luta[4] = {ASt0 | ADi0, ASt0 | ADi1, ASt1 | ADi1, ASt1 | ADi0}, // Used to look-up 'clk' and 'dir' signals from accum MSBs
JonFreeman 2:b3c668ec43ac 310 bits2shift = (sizeof (long) << 3) - 2,
JonFreeman 0:5d0f270bfc87 311 static unsigned long
JonFreeman 0:5d0f270bfc87 312 // acc_s = 0L, // For Spindle motor, probably not needed as may be pwm
JonFreeman 0:5d0f270bfc87 313 acc_a = 0L,
JonFreeman 0:5d0f270bfc87 314 acc_x = 0L,
JonFreeman 0:5d0f270bfc87 315 acc_y = 0L,
JonFreeman 0:5d0f270bfc87 316 acc_z = 0L;
JonFreeman 1:66ee619f206b 317 static int obitz = 0, mscount = millisec_countdown;
JonFreeman 0:5d0f270bfc87 318 int oldbitz, acts;
JonFreeman 0:5d0f270bfc87 319
JonFreeman 0:5d0f270bfc87 320 intled = 1; // LED on for duration of interrupt service - point for scope probing
JonFreeman 0:5d0f270bfc87 321 ticks++; // count of interrupts serviced
JonFreeman 1:66ee619f206b 322 if(!--mscount) { // Maintain global counter of elapsed milli seconds
JonFreeman 1:66ee619f206b 323 mscount = millisec_countdown;
JonFreeman 1:66ee619f206b 324 millisecs++;
JonFreeman 0:5d0f270bfc87 325 }
JonFreeman 1:66ee619f206b 326 if (running) {
JonFreeman 1:66ee619f206b 327 acc_x += pir_x; // Update phase of signals in accumulators
JonFreeman 1:66ee619f206b 328 acc_y += pir_y;
JonFreeman 1:66ee619f206b 329 acc_z += pir_z;
JonFreeman 1:66ee619f206b 330 acc_a += pir_a; // not yet implemented
JonFreeman 1:66ee619f206b 331 // acc_s += pir_s; // pir_s used for spindle speed
JonFreeman 1:66ee619f206b 332 oldbitz = obitz; // pin output levels as determined during previous interrut
JonFreeman 1:66ee619f206b 333 obitz = bit_lutx[acc_x >> bits2shift] | bit_luty[acc_y >> bits2shift] | bit_lutz[acc_z >> bits2shift] | bit_luta[acc_a >> bits2shift];
JonFreeman 1:66ee619f206b 334
JonFreeman 1:66ee619f206b 335 mysteppers = obitz; // Output signals to stepper motor drivers, next look for _- pos clk events on 'Step' outputs
JonFreeman 1:66ee619f206b 336
JonFreeman 1:66ee619f206b 337 acts = (~oldbitz & obitz); // get pos clk edge triggers 'Step' bits
JonFreeman 1:66ee619f206b 338 acts |= (obitz & (XDi1 | YDi1 | ZDi1)); // get axis X, Y and Z Direction bits
JonFreeman 1:66ee619f206b 339 if(acts & XSt1) { // got pos clk edge for axis X
JonFreeman 1:66ee619f206b 340 if (acts & XDi1)
JonFreeman 1:66ee619f206b 341 dro.x++;
JonFreeman 1:66ee619f206b 342 else dro.x--;
JonFreeman 1:66ee619f206b 343 }
JonFreeman 1:66ee619f206b 344 if(acts & YSt1) { // got pos clk edge for axis Y
JonFreeman 1:66ee619f206b 345 if (acts & YDi1)
JonFreeman 1:66ee619f206b 346 dro.y++;
JonFreeman 1:66ee619f206b 347 else dro.y--;
JonFreeman 1:66ee619f206b 348 }
JonFreeman 1:66ee619f206b 349 if(acts & ZSt1) { // got pos clk edge for axis Z
JonFreeman 1:66ee619f206b 350 if (acts & ZDi1)
JonFreeman 1:66ee619f206b 351 dro.z++;
JonFreeman 1:66ee619f206b 352 else dro.z--;
JonFreeman 1:66ee619f206b 353 }
JonFreeman 1:66ee619f206b 354 if (tickrun <= ticks) { // End of a machine movement detected, start next move here if possible
JonFreeman 1:66ee619f206b 355 running = false;
JonFreeman 1:66ee619f206b 356 move_ended = true;
JonFreeman 1:66ee619f206b 357 pir_x = 0L; // stop all stepper motors
JonFreeman 1:66ee619f206b 358 pir_y = 0L;
JonFreeman 1:66ee619f206b 359 pir_z = 0L;
JonFreeman 1:66ee619f206b 360 pir_a = 0L;
JonFreeman 1:66ee619f206b 361 // ticks = 0L; // Simply to avoid having to think about overflow problems
JonFreeman 1:66ee619f206b 362 }
JonFreeman 0:5d0f270bfc87 363 }
JonFreeman 1:66ee619f206b 364 else { // Not running. Grab next data here when or if available
JonFreeman 1:66ee619f206b 365 if (new_run_pending) { // Pick up on flag set elsewhere
JonFreeman 1:66ee619f206b 366 pir_a = pir_a_next;
JonFreeman 1:66ee619f206b 367 pir_x = pir_x_next;
JonFreeman 1:66ee619f206b 368 pir_y = pir_y_next;
JonFreeman 1:66ee619f206b 369 pir_z = pir_z_next;
JonFreeman 1:66ee619f206b 370 tickrun = ticks + ticks_next;
JonFreeman 1:66ee619f206b 371 running = true; // Start the new run
JonFreeman 1:66ee619f206b 372 new_run_pending = false; // Clear the flag which initiated this update
JonFreeman 1:66ee619f206b 373 idle = false;
JonFreeman 1:66ee619f206b 374 }
JonFreeman 0:5d0f270bfc87 375 }
JonFreeman 1:66ee619f206b 376 charge_pump = ticks & 0x02;
JonFreeman 0:5d0f270bfc87 377 intled = 0; // LED off
JonFreeman 0:5d0f270bfc87 378 } // end of interrupt handler
JonFreeman 2:b3c668ec43ac 379 */
JonFreeman 0:5d0f270bfc87 380 /*
JonFreeman 0:5d0f270bfc87 381 * End of Interrupt Service Routine
JonFreeman 0:5d0f270bfc87 382 */
JonFreeman 0:5d0f270bfc87 383
JonFreeman 0:5d0f270bfc87 384
JonFreeman 2:b3c668ec43ac 385
JonFreeman 2:b3c668ec43ac 386
JonFreeman 2:b3c668ec43ac 387
JonFreeman 2:b3c668ec43ac 388
JonFreeman 2:b3c668ec43ac 389
JonFreeman 2:b3c668ec43ac 390
JonFreeman 2:b3c668ec43ac 391
JonFreeman 2:b3c668ec43ac 392
JonFreeman 2:b3c668ec43ac 393
JonFreeman 2:b3c668ec43ac 394
JonFreeman 2:b3c668ec43ac 395
JonFreeman 2:b3c668ec43ac 396
JonFreeman 2:b3c668ec43ac 397
JonFreeman 2:b3c668ec43ac 398
JonFreeman 2:b3c668ec43ac 399 /*
JonFreeman 2:b3c668ec43ac 400 * Interrupt Service Routine
JonFreeman 2:b3c668ec43ac 401 */
JonFreeman 2:b3c668ec43ac 402 #define STEP_IDLE_HI
JonFreeman 2:b3c668ec43ac 403 //#define STEP_IDLE_LO
JonFreeman 2:b3c668ec43ac 404 void Numerically_Controlled_Oscillators_ISR () { // services Ticker 'NCO_gen' generated interrupts ***ISR***
JonFreeman 2:b3c668ec43ac 405 static const int millisec_countdown = 1000 / interrupt_period_us;
JonFreeman 2:b3c668ec43ac 406 const long step_mask = ASt | XSt | YSt | ZSt, // Added 6th Feb 14 Mask Does NOT include spindle bits
JonFreeman 2:b3c668ec43ac 407 dir_mask = ADi | XDi | YDi | ZDi; // Added 6th Feb 14 Mask Does NOT include spindle bits
JonFreeman 2:b3c668ec43ac 408 static unsigned long
JonFreeman 2:b3c668ec43ac 409 acc_spin = 0L,
JonFreeman 2:b3c668ec43ac 410 acc_a = 0L,
JonFreeman 2:b3c668ec43ac 411 acc_x = 0L,
JonFreeman 2:b3c668ec43ac 412 acc_y = 0L,
JonFreeman 2:b3c668ec43ac 413 acc_z = 0L;
JonFreeman 2:b3c668ec43ac 414 static long mscount = millisec_countdown;
JonFreeman 2:b3c668ec43ac 415 static long dir_bits = 0L, oldSteps = 0L; // Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 416 long acts, tmp, newSteps, stbits;
JonFreeman 2:b3c668ec43ac 417
JonFreeman 2:b3c668ec43ac 418 intled = 1; // LED on for duration of interrupt service - point for scope probing
JonFreeman 2:b3c668ec43ac 419 ticks++; // count of interrupts serviced
JonFreeman 2:b3c668ec43ac 420 if(!--mscount) { // Maintain global counter of elapsed milli seconds
JonFreeman 2:b3c668ec43ac 421 mscount = millisec_countdown;
JonFreeman 2:b3c668ec43ac 422 millisecs++;
JonFreeman 2:b3c668ec43ac 423 }
JonFreeman 2:b3c668ec43ac 424 acc_spin += pir_spin;
JonFreeman 2:b3c668ec43ac 425 tmp = Steppers ^ direction_swappers;
JonFreeman 2:b3c668ec43ac 426 #if defined STEP_IDLE_LO
JonFreeman 2:b3c668ec43ac 427 tmp &= ~step_mask; // Step bits prepared for idle lo
JonFreeman 2:b3c668ec43ac 428 #endif
JonFreeman 2:b3c668ec43ac 429 #if defined STEP_IDLE_HI
JonFreeman 2:b3c668ec43ac 430 tmp |= step_mask; // Step bits prepared for idle hi
JonFreeman 2:b3c668ec43ac 431 #endif
JonFreeman 2:b3c668ec43ac 432 if (acc_spin & 0x80000000) { tmp |= SSt; }
JonFreeman 2:b3c668ec43ac 433 else { tmp &= ~SSt; }
JonFreeman 2:b3c668ec43ac 434 // mysteppers = tmp;
JonFreeman 2:b3c668ec43ac 435 if (running) {
JonFreeman 2:b3c668ec43ac 436 acc_x += pir_x; // Update phase of signals in accumulators
JonFreeman 2:b3c668ec43ac 437 acc_y += pir_y;
JonFreeman 2:b3c668ec43ac 438 acc_z += pir_z;
JonFreeman 2:b3c668ec43ac 439 acc_a += pir_a; // not yet implemented
JonFreeman 2:b3c668ec43ac 440
JonFreeman 2:b3c668ec43ac 441 newSteps = 0L; // Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 442 if (acc_a & 0x80000000) newSteps |= ASt;// Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 443 if (acc_x & 0x80000000) newSteps |= XSt;// Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 444 if (acc_y & 0x80000000) newSteps |= YSt;// Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 445 if (acc_z & 0x80000000) newSteps |= ZSt;// Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 446 stbits = newSteps ^ oldSteps; // Any bit of stbits set to initiate a Step pulse
JonFreeman 2:b3c668ec43ac 447 acts = dir_bits | stbits; //
JonFreeman 2:b3c668ec43ac 448 oldSteps = newSteps; // Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 449 // tmp = acts ^ step_mask; // Invert clock - Arc Euro stepp motor driver only goes into half current mode this way
JonFreeman 2:b3c668ec43ac 450 tmp ^= stbits;
JonFreeman 2:b3c668ec43ac 451 Steppers = tmp ^ direction_swappers; // Output signals to stepper motor drivers, next update dros from 'clocked' bits CLOCK IDLES HIGH
JonFreeman 2:b3c668ec43ac 452
JonFreeman 2:b3c668ec43ac 453 if(acts & XSt) { // got clk edge for axis X
JonFreeman 2:b3c668ec43ac 454 if (acts & XDi)
JonFreeman 2:b3c668ec43ac 455 dro_out.x--;
JonFreeman 2:b3c668ec43ac 456 else dro_out.x++;
JonFreeman 2:b3c668ec43ac 457 }
JonFreeman 2:b3c668ec43ac 458 if(acts & YSt) { // got clk edge for axis Y
JonFreeman 2:b3c668ec43ac 459 if (acts & YDi)
JonFreeman 2:b3c668ec43ac 460 dro_out.y--;
JonFreeman 2:b3c668ec43ac 461 else dro_out.y++;
JonFreeman 2:b3c668ec43ac 462 }
JonFreeman 2:b3c668ec43ac 463 if(acts & ZSt) { // got clk edge for axis Z
JonFreeman 2:b3c668ec43ac 464 if (acts & ZDi)
JonFreeman 2:b3c668ec43ac 465 dro_out.z--;
JonFreeman 2:b3c668ec43ac 466 else dro_out.z++;
JonFreeman 2:b3c668ec43ac 467 }
JonFreeman 2:b3c668ec43ac 468 if (tickrun <= ticks) { // End of a machine movement detected, start next move here if possible
JonFreeman 2:b3c668ec43ac 469 if (new_run_pending) {
JonFreeman 2:b3c668ec43ac 470 pir_a = pir_a_next;
JonFreeman 2:b3c668ec43ac 471 pir_x = pir_x_next;
JonFreeman 2:b3c668ec43ac 472 pir_y = pir_y_next;
JonFreeman 2:b3c668ec43ac 473 pir_z = pir_z_next;
JonFreeman 2:b3c668ec43ac 474 dir_bits = 0; // Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 475 if (pir_a & 0x80000000) dir_bits |= ADi;// Added 6th Feb 14 read sign bits
JonFreeman 2:b3c668ec43ac 476 if (pir_x & 0x80000000) dir_bits |= XDi;// Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 477 if (pir_y & 0x80000000) dir_bits |= YDi;// Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 478 if (pir_z & 0x80000000) dir_bits |= ZDi;// Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 479 acts = Steppers ^ direction_swappers; // read output lines
JonFreeman 2:b3c668ec43ac 480 acts &= ~dir_mask;
JonFreeman 2:b3c668ec43ac 481 acts |= dir_bits;
JonFreeman 2:b3c668ec43ac 482 Steppers = acts ^ direction_swappers;
JonFreeman 2:b3c668ec43ac 483 tickrun = ticks + ticks_next;
JonFreeman 2:b3c668ec43ac 484 running = true; // Start the new run
JonFreeman 2:b3c668ec43ac 485 new_run_pending = false; // Clear the flag which initiated this update
JonFreeman 2:b3c668ec43ac 486 idle = false;
JonFreeman 2:b3c668ec43ac 487 } // End of if (new_run_pending) {
JonFreeman 2:b3c668ec43ac 488 else { // End of machine movement AND no new_run_pending
JonFreeman 2:b3c668ec43ac 489 running = false;
JonFreeman 2:b3c668ec43ac 490 move_ended = true;
JonFreeman 2:b3c668ec43ac 491 pir_x = 0L; // stop all stepper motors
JonFreeman 2:b3c668ec43ac 492 pir_y = 0L;
JonFreeman 2:b3c668ec43ac 493 pir_z = 0L;
JonFreeman 2:b3c668ec43ac 494 pir_a = 0L;
JonFreeman 2:b3c668ec43ac 495 // ticks = 0L; // Simply to avoid having to think about overflow problems
JonFreeman 2:b3c668ec43ac 496 }
JonFreeman 2:b3c668ec43ac 497 }
JonFreeman 2:b3c668ec43ac 498 }
JonFreeman 2:b3c668ec43ac 499 else { // Not running. Grab next data here when or if available
JonFreeman 2:b3c668ec43ac 500 Steppers = tmp ^ direction_swappers;
JonFreeman 2:b3c668ec43ac 501 if (new_run_pending) { // Pick up on flag set elsewhere
JonFreeman 2:b3c668ec43ac 502 pir_a = pir_a_next;
JonFreeman 2:b3c668ec43ac 503 pir_x = pir_x_next;
JonFreeman 2:b3c668ec43ac 504 pir_y = pir_y_next;
JonFreeman 2:b3c668ec43ac 505 pir_z = pir_z_next;
JonFreeman 2:b3c668ec43ac 506 dir_bits = 0; // Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 507 if (pir_a & 0x80000000) dir_bits |= ADi;// Added 6th Feb 14 read sign bits
JonFreeman 2:b3c668ec43ac 508 if (pir_x & 0x80000000) dir_bits |= XDi;// Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 509 if (pir_y & 0x80000000) dir_bits |= YDi;// Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 510 if (pir_z & 0x80000000) dir_bits |= ZDi;// Added 6th Feb 14
JonFreeman 2:b3c668ec43ac 511 acts = Steppers ^ direction_swappers; // read output lines
JonFreeman 2:b3c668ec43ac 512 acts &= ~dir_mask;
JonFreeman 2:b3c668ec43ac 513 acts |= dir_bits;
JonFreeman 2:b3c668ec43ac 514 Steppers = acts ^ direction_swappers;
JonFreeman 2:b3c668ec43ac 515 tickrun = ticks + ticks_next;
JonFreeman 2:b3c668ec43ac 516 running = true; // Start the new run
JonFreeman 2:b3c668ec43ac 517 new_run_pending = false; // Clear the flag which initiated this update
JonFreeman 2:b3c668ec43ac 518 idle = false;
JonFreeman 2:b3c668ec43ac 519 } // end of if (new_run_pending) { // Pick up on flag set elsewhere
JonFreeman 2:b3c668ec43ac 520 } // end of else { // Not running. Grab next data here when or if available
JonFreeman 2:b3c668ec43ac 521 charge_pumpD25pin1 = ticks & 0x01; // Can use 0x01 or 0x02 here to alter charge pump freq
JonFreeman 2:b3c668ec43ac 522 intled = 0; // LED off
JonFreeman 2:b3c668ec43ac 523 } // end of interrupt handler
JonFreeman 2:b3c668ec43ac 524
JonFreeman 2:b3c668ec43ac 525 /*
JonFreeman 2:b3c668ec43ac 526 * End of Interrupt Service Routine
JonFreeman 2:b3c668ec43ac 527 */
JonFreeman 2:b3c668ec43ac 528 bool spindle_running () {
JonFreeman 2:b3c668ec43ac 529 return pir_spin;
JonFreeman 2:b3c668ec43ac 530 }
JonFreeman 2:b3c668ec43ac 531 void spindle_control (double ss) {
JonFreeman 2:b3c668ec43ac 532 long t, p;
JonFreeman 2:b3c668ec43ac 533 pir_spin = (signed long) (ss * spindle_factor);
JonFreeman 2:b3c668ec43ac 534 t = ticks;
JonFreeman 2:b3c668ec43ac 535 while (t == ticks) {} // wait until just after next interrupt
JonFreeman 2:b3c668ec43ac 536 p = Steppers ^ direction_swappers;
JonFreeman 2:b3c668ec43ac 537 if (pir_spin & 0x80000000)
JonFreeman 2:b3c668ec43ac 538 p |= SDi;
JonFreeman 2:b3c668ec43ac 539 else
JonFreeman 2:b3c668ec43ac 540 p &= ~SDi;
JonFreeman 2:b3c668ec43ac 541 Steppers = p ^ direction_swappers;
JonFreeman 2:b3c668ec43ac 542 pc.printf("Done setting spindle speed %.0f, delay = %d\r\n", ss, ticks - t);
JonFreeman 2:b3c668ec43ac 543 }
JonFreeman 2:b3c668ec43ac 544
JonFreeman 2:b3c668ec43ac 545
JonFreeman 2:b3c668ec43ac 546 /*
JonFreeman 2:b3c668ec43ac 547 void scmd (struct singleGparam * a) {
JonFreeman 2:b3c668ec43ac 548 long t, p;
JonFreeman 2:b3c668ec43ac 549 if (fabs(a[1].dbl) > spindle_max) {
JonFreeman 2:b3c668ec43ac 550 pc.printf ("Errror setting spindle RPM, can't set to %.0f, ignoring request\r\n", a[1].dbl);
JonFreeman 2:b3c668ec43ac 551 return;
JonFreeman 2:b3c668ec43ac 552 }
JonFreeman 2:b3c668ec43ac 553 pc.printf ("Setting spindle RPM to %.0f Can set Pos or Neg for fwd/rev\r\n", a[1].dbl);
JonFreeman 2:b3c668ec43ac 554 pir_spin = (signed long) (a[1].dbl * spindle_factor);
JonFreeman 2:b3c668ec43ac 555 t = ticks;
JonFreeman 2:b3c668ec43ac 556 while (t == ticks) {} // wait until just after next interrupt
JonFreeman 2:b3c668ec43ac 557 p = mysteppers;
JonFreeman 2:b3c668ec43ac 558 if (pir_spin & 0x80000000)
JonFreeman 2:b3c668ec43ac 559 p |= SDi;
JonFreeman 2:b3c668ec43ac 560 else
JonFreeman 2:b3c668ec43ac 561 p &= ~SDi;
JonFreeman 2:b3c668ec43ac 562 mysteppers = p;
JonFreeman 2:b3c668ec43ac 563 pc.printf("Done setting spindle, delay = %d", ticks - t);
JonFreeman 2:b3c668ec43ac 564 }
JonFreeman 2:b3c668ec43ac 565 */
JonFreeman 1:66ee619f206b 566 void newpir_updater (void const * name) {
JonFreeman 2:b3c668ec43ac 567 static long x, y, z;//, count = 0;
JonFreeman 1:66ee619f206b 568 struct pirbufgrain outs;
JonFreeman 2:b3c668ec43ac 569 // pc.printf("Arrived at newpir_updater\r\n");
JonFreeman 1:66ee619f206b 570 while (true) {
JonFreeman 2:b3c668ec43ac 571 // while (!move_ended || !CircBuff.readable()) { ** TO DO ** Solve problem with empty flag
JonFreeman 2:b3c668ec43ac 572 while (!move_ended || CircBuff.On_Q() == 0) {
JonFreeman 1:66ee619f206b 573 osThreadYield();
JonFreeman 2:b3c668ec43ac 574 } // Proceed beyond here only when move_ended AND CircBuff.readable() both TRUE
JonFreeman 1:66ee619f206b 575 CircBuff.read(outs);
JonFreeman 1:66ee619f206b 576 x = (long)(outs.f_rate * outs.x); // These take much CPU time !!
JonFreeman 1:66ee619f206b 577 y = (long)(outs.f_rate * outs.y);
JonFreeman 1:66ee619f206b 578 z = (long)(outs.f_rate * outs.z);
JonFreeman 1:66ee619f206b 579 ticks_next = (unsigned long)(outs.c / outs.f_rate);
JonFreeman 1:66ee619f206b 580 pir_x_next = x;
JonFreeman 1:66ee619f206b 581 pir_y_next = y;
JonFreeman 1:66ee619f206b 582 pir_z_next = z;
JonFreeman 2:b3c668ec43ac 583 move_ended = idle = false;
JonFreeman 1:66ee619f206b 584 new_run_pending = true; // cleared and 'running' flag set in interrupt handler
JonFreeman 2:b3c668ec43ac 585 // idle = false;
JonFreeman 2:b3c668ec43ac 586 // count++;
JonFreeman 1:66ee619f206b 587 // pc.printf("CircB tot %d\r\n", count);
JonFreeman 1:66ee619f206b 588 }
JonFreeman 0:5d0f270bfc87 589 }
JonFreeman 0:5d0f270bfc87 590
JonFreeman 1:66ee619f206b 591
JonFreeman 2:b3c668ec43ac 592 void flags_report_cmd (struct singleGparam * a) { // Diagnostic helper function
JonFreeman 2:b3c668ec43ac 593 pc.printf("Flags Report\r\nRunning %s\r\n", running ? "T":"F");
JonFreeman 2:b3c668ec43ac 594 pc.printf("idle %s\r\n", idle ? "T":"F");
JonFreeman 2:b3c668ec43ac 595 pc.printf("new_run_pending %s\r\n", new_run_pending ? "T":"F");
JonFreeman 2:b3c668ec43ac 596 pc.printf("move_ended %s\r\n", move_ended ? "T":"F");
JonFreeman 2:b3c668ec43ac 597 pc.printf("CircBuff.readable() %s\r\n", CircBuff.readable() ? "T":"F");
JonFreeman 2:b3c668ec43ac 598 pc.printf("On CircBuff %d\r\n", CircBuff.On_Q());
JonFreeman 2:b3c668ec43ac 599 }
JonFreeman 1:66ee619f206b 600
JonFreeman 1:66ee619f206b 601 /*void taskone (void const * name)
JonFreeman 1:66ee619f206b 602 {
JonFreeman 1:66ee619f206b 603 static int i = 0;
JonFreeman 1:66ee619f206b 604 while (true) {
JonFreeman 1:66ee619f206b 605 pc.printf("%s %d\r\n", name, i++);
JonFreeman 1:66ee619f206b 606 Thread::wait(9500);
JonFreeman 1:66ee619f206b 607 osThreadYield();
JonFreeman 1:66ee619f206b 608 }
JonFreeman 1:66ee619f206b 609 }
JonFreeman 1:66ee619f206b 610
JonFreeman 1:66ee619f206b 611 void tasktwo (void const * name)
JonFreeman 1:66ee619f206b 612 {
JonFreeman 1:66ee619f206b 613 pc.printf("Task Two runs once and exits\r\n");
JonFreeman 1:66ee619f206b 614 Thread::wait(700);
JonFreeman 1:66ee619f206b 615 osThreadYield();
JonFreeman 1:66ee619f206b 616 }
JonFreeman 1:66ee619f206b 617
JonFreeman 1:66ee619f206b 618 void taskthree (void const * name)
JonFreeman 1:66ee619f206b 619 {
JonFreeman 1:66ee619f206b 620 static int i = 0;
JonFreeman 1:66ee619f206b 621 while (true) {
JonFreeman 1:66ee619f206b 622 pc.printf("%s %d\r\n", name, i++);
JonFreeman 1:66ee619f206b 623 Thread::wait(3500);
JonFreeman 1:66ee619f206b 624 osThreadYield();
JonFreeman 1:66ee619f206b 625 }
JonFreeman 1:66ee619f206b 626 }*/
JonFreeman 2:b3c668ec43ac 627 /*
JonFreeman 2:b3c668ec43ac 628 #define ESTOP 0x100
JonFreeman 2:b3c668ec43ac 629 #define XLIM 1
JonFreeman 2:b3c668ec43ac 630 #define YLIM 2
JonFreeman 2:b3c668ec43ac 631 #define ZLIM 4
JonFreeman 2:b3c668ec43ac 632 #define UNKN 8
JonFreeman 2:b3c668ec43ac 633 */
JonFreeman 2:b3c668ec43ac 634 class inputsreaderstuff {
JonFreeman 2:b3c668ec43ac 635 private:
JonFreeman 2:b3c668ec43ac 636 long ins_now;//, ins_old, ins_changed;
JonFreeman 2:b3c668ec43ac 637 public:
JonFreeman 2:b3c668ec43ac 638 void init () { ins_now = 0L;}//ins_old = ins_changed = 0L; }
JonFreeman 2:b3c668ec43ac 639 long read () {
JonFreeman 2:b3c668ec43ac 640 ins_now = 0;
JonFreeman 2:b3c668ec43ac 641 if (D25pin10_EStop) ins_now |= ESTOP;
JonFreeman 2:b3c668ec43ac 642 if (D25pin11_XLim) ins_now |= XLIM;
JonFreeman 2:b3c668ec43ac 643 if (D25pin12_YLim) ins_now |= YLIM;
JonFreeman 2:b3c668ec43ac 644 if (D25pin13_ZLim) ins_now |= ZLIM;
JonFreeman 2:b3c668ec43ac 645 if (D25pin15_unkn) ins_now |= UNKN;
JonFreeman 2:b3c668ec43ac 646 // ins_changed = ins_now ^ ins_old;
JonFreeman 2:b3c668ec43ac 647 // ins_old = ins_now;
JonFreeman 2:b3c668ec43ac 648 return ins_now;
JonFreeman 2:b3c668ec43ac 649 }
JonFreeman 2:b3c668ec43ac 650 // long changed () { return ins_changed; }
JonFreeman 2:b3c668ec43ac 651 } Inputs_From_Machine;
JonFreeman 2:b3c668ec43ac 652
JonFreeman 2:b3c668ec43ac 653 void report_inputs () {
JonFreeman 2:b3c668ec43ac 654 long i = Inputs_From_Machine.read();
JonFreeman 2:b3c668ec43ac 655 pc.printf("Inputs: EStop %d, XLim %d, YLim %d, ", i & ESTOP ? 1:0, i & XLIM ? 1:0, i & YLIM ? 1:0);
JonFreeman 2:b3c668ec43ac 656 pc.printf("ZLim %d, unkn %d\r\n", i & ZLIM ? 1:0, i & UNKN ? 1:0);
JonFreeman 2:b3c668ec43ac 657 }
JonFreeman 2:b3c668ec43ac 658
JonFreeman 2:b3c668ec43ac 659 //void Emergency_Stop_Interrupt () {
JonFreeman 2:b3c668ec43ac 660 // pc.printf("Emergency Stop Activated !!\r\n");
JonFreeman 2:b3c668ec43ac 661 // spindle_control (0.0); // Stop spindle rotation
JonFreeman 2:b3c668ec43ac 662 //}
JonFreeman 1:66ee619f206b 663
JonFreeman 0:5d0f270bfc87 664 int main() {
JonFreeman 0:5d0f270bfc87 665 pc.baud(BAUD); // comms to 'PuTTY' serial terminal via mbed usb
JonFreeman 2:b3c668ec43ac 666 // D25pin11_XLim.mode (PullDown); External resistors now fitted
JonFreeman 2:b3c668ec43ac 667 // D25pin12_YLim.mode (PullDown);
JonFreeman 2:b3c668ec43ac 668 // D25pin13_ZLim.mode (PullDown);
JonFreeman 2:b3c668ec43ac 669 // D25pin15_unkn.mode (PullDown);
JonFreeman 2:b3c668ec43ac 670 // D25pin10_EStop.mode (PullDown);
JonFreeman 2:b3c668ec43ac 671 // D25pin10_EStop.rise (& Emergency_Stop_Interrupt);
JonFreeman 2:b3c668ec43ac 672 // D25pin10_EStop.fall (& Emergency_Stop_Interrupt);
JonFreeman 2:b3c668ec43ac 673
JonFreeman 1:66ee619f206b 674 more_setup () ; // Zeros one 'pirs' structure 'last_position'
JonFreeman 2:b3c668ec43ac 675 dro_out.init();
JonFreeman 1:66ee619f206b 676 CircBuff.init ();
JonFreeman 2:b3c668ec43ac 677 Inputs_From_Machine.init ();
JonFreeman 0:5d0f270bfc87 678 spidevice.format(8, 0); // 8 bits mode 0, // p11 mosi, p12 miso, p13 sclk ** ONLY 8 BIT **
JonFreeman 0:5d0f270bfc87 679 spidevice.frequency(12000000); // 12MHz bit rate
JonFreeman 2:b3c668ec43ac 680 pc.printf("\r\n*\n*\nFound Computer %s\r\n", Target);
JonFreeman 1:66ee619f206b 681 pc.printf("Welcome to the CNC tester\r\nStep pulses required to move 1.0mm = %9.0f\r\n", pulses_per_mm);
JonFreeman 2:b3c668ec43ac 682 pc.printf("PIR 'n' for 1mm per min = %9.0f\r\ntop speed = %6.1f mm per min\r\n\n", n_for_onemmpermin, max_mm_per_min);
JonFreeman 1:66ee619f206b 683 NCO_gen.attach_us(&Numerically_Controlled_Oscillators_ISR, (long)interrupt_period_us);// Have setup timed interrupts, let other code deal
JonFreeman 1:66ee619f206b 684 // Thread threadnametaskone (taskone, (void *)"task one stuff");
JonFreeman 1:66ee619f206b 685 // Thread t8 (tasktwo, (void *)"task two");
JonFreeman 1:66ee619f206b 686 Thread tsr2 (newpir_updater, (void *)"read from CircBuff and move");
JonFreeman 1:66ee619f206b 687 // Thread tthree (taskthree, (void *)"task three");
JonFreeman 2:b3c668ec43ac 688 // Thread patterngen (lissajous, (void *)"Loading Lissajous") ;
JonFreeman 1:66ee619f206b 689 Thread comlin (command_line_interpreter, (void *)"cli"); // Read any instructions arriving via serial port and act upon them
JonFreeman 2:b3c668ec43ac 690 long ins, ins_old, ins_changed = 0;
JonFreeman 2:b3c668ec43ac 691 ins = ins_old = Inputs_From_Machine.read ();
JonFreeman 1:66ee619f206b 692 move_ended = true; // Needed to kickstart system
JonFreeman 1:66ee619f206b 693
JonFreeman 1:66ee619f206b 694 while(1) { // Round Robin loop
JonFreeman 1:66ee619f206b 695 dro_out.update (); // Update DRO readings if, and as often as needed
JonFreeman 2:b3c668ec43ac 696 ins = Inputs_From_Machine.read ();
JonFreeman 2:b3c668ec43ac 697 ins_changed = ins ^ ins_old;
JonFreeman 2:b3c668ec43ac 698 ins_old = ins;
JonFreeman 2:b3c668ec43ac 699 if (ins_changed)
JonFreeman 2:b3c668ec43ac 700 pc.printf("Inputs Have Changed 0x%x, read 0x%x\r\n", ins_changed, ins);
JonFreeman 2:b3c668ec43ac 701 // pc.printf(".");
JonFreeman 1:66ee619f206b 702 osThreadYield(); //
JonFreeman 1:66ee619f206b 703 } // end of Round Robin loop
JonFreeman 1:66ee619f206b 704 } // end of int main()
JonFreeman 1:66ee619f206b 705