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
main.cpp@3:7aaf0072cc22, 2014-03-14 (annotated)
- Committer:
- JonFreeman
- Date:
- Fri Mar 14 14:14:55 2014 +0000
- Revision:
- 3:7aaf0072cc22
- Parent:
- 2:b3c668ec43ac
CNC Machine driver, emulates PC LPT port, docs are wip
Who changed what in which revision?
User | Revision | Line number | New 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 | 3:7aaf0072cc22 | 5 | extern void i2c_handler (void const *); |
JonFreeman | 1:66ee619f206b | 6 | extern void command_line_interpreter (void const *) ; |
JonFreeman | 3:7aaf0072cc22 | 7 | extern fl_typ feed_rate; // float type is 'float' |
JonFreeman | 3:7aaf0072cc22 | 8 | extern signed long spindle_rpm; |
JonFreeman | 0:5d0f270bfc87 | 9 | |
JonFreeman | 1:66ee619f206b | 10 | const int BAUD = 38400; |
JonFreeman | 3:7aaf0072cc22 | 11 | MODSERIAL pc(USBTX, USBRX); // tx, rx to pc via usb lead |
JonFreeman | 3:7aaf0072cc22 | 12 | Ticker NCO_gen; // Ticker generating interrupts at "Kernel Speed", NCO updating frequency (about 40kHz) |
JonFreeman | 3:7aaf0072cc22 | 13 | Ticker msec; // Ticker updating global millisecs counter |
JonFreeman | 3:7aaf0072cc22 | 14 | |
JonFreeman | 3:7aaf0072cc22 | 15 | bool running = false, |
JonFreeman | 3:7aaf0072cc22 | 16 | new_run_pending = false, |
JonFreeman | 3:7aaf0072cc22 | 17 | idle = false, |
JonFreeman | 3:7aaf0072cc22 | 18 | move_ended = false; |
JonFreeman | 0:5d0f270bfc87 | 19 | |
JonFreeman | 3:7aaf0072cc22 | 20 | volatile unsigned long ticks = 0L; // 32 bit count of "interrupt_period_us" interrupts from time t=0 |
JonFreeman | 3:7aaf0072cc22 | 21 | unsigned long tickrun = 0L, // 32 bit effectively stores time in future when current movement to stop |
JonFreeman | 3:7aaf0072cc22 | 22 | ticks_next = 0L, // 32 bit effectively stores time in future when current movement to stop |
JonFreeman | 3:7aaf0072cc22 | 23 | millisecs = 0L; // 32 bit |
JonFreeman | 3:7aaf0072cc22 | 24 | signed long |
JonFreeman | 3:7aaf0072cc22 | 25 | #if defined Fourth_Axis |
JonFreeman | 3:7aaf0072cc22 | 26 | pir_a_next = 0L, // Data for next move assembled here |
JonFreeman | 3:7aaf0072cc22 | 27 | #endif |
JonFreeman | 3:7aaf0072cc22 | 28 | pir_x_next = 0L, // during a move. |
JonFreeman | 3:7aaf0072cc22 | 29 | pir_y_next = 0L, // This way, next move can start immediately |
JonFreeman | 3:7aaf0072cc22 | 30 | pir_z_next = 0L, // on end of current move - minimised jerking |
JonFreeman | 3:7aaf0072cc22 | 31 | #if defined Fourth_Axis |
JonFreeman | 3:7aaf0072cc22 | 32 | inc_a_next = 1L, |
JonFreeman | 3:7aaf0072cc22 | 33 | #endif |
JonFreeman | 3:7aaf0072cc22 | 34 | inc_x_next = 1L, |
JonFreeman | 3:7aaf0072cc22 | 35 | inc_y_next = 1L, |
JonFreeman | 3:7aaf0072cc22 | 36 | inc_z_next = 1L, |
JonFreeman | 1:66ee619f206b | 37 | |
JonFreeman | 3:7aaf0072cc22 | 38 | dir_bits_next = 0L, |
JonFreeman | 3:7aaf0072cc22 | 39 | pir_spin = 0L; // Referenced only in command_interpreter as spindle speed setting |
JonFreeman | 3:7aaf0072cc22 | 40 | |
JonFreeman | 3:7aaf0072cc22 | 41 | struct Gparams last_position; // |
JonFreeman | 0:5d0f270bfc87 | 42 | |
JonFreeman | 1:66ee619f206b | 43 | |
JonFreeman | 0:5d0f270bfc87 | 44 | #if defined (TARGET_KL25Z) |
JonFreeman | 3:7aaf0072cc22 | 45 | const char Target[] = "KL25Z"; // Note need PTE0 (sda) and PTE1 (scl) |
JonFreeman | 3:7aaf0072cc22 | 46 | DigitalOut intled (PTD7); //(PTE1); //J2p19, was 20 |
JonFreeman | 3:7aaf0072cc22 | 47 | DigitalOut charge_pumpD25pin1 (PTD6); //(PTE0); //J2p17, was 18 |
JonFreeman | 2:b3c668ec43ac | 48 | // InterruptIn D25pin10_EStop (PTE20); //j10p1 KL25 J10 is KL46 j4 |
JonFreeman | 2:b3c668ec43ac | 49 | DigitalIn D25pin10_EStop (PTE20); //j10p1 KL25 J10 is KL46 j4 |
JonFreeman | 2:b3c668ec43ac | 50 | DigitalIn D25pin11_XLim (PTE21); //j10p3 |
JonFreeman | 2:b3c668ec43ac | 51 | DigitalIn D25pin12_YLim (PTE22); //j10p5 |
JonFreeman | 2:b3c668ec43ac | 52 | DigitalIn D25pin13_ZLim (PTE23); //j10p7 |
JonFreeman | 2:b3c668ec43ac | 53 | DigitalIn D25pin15_unkn (PTE30); //j10p11 |
JonFreeman | 3:7aaf0072cc22 | 54 | #if defined I2C_Enable |
JonFreeman | 3:7aaf0072cc22 | 55 | I2CSlave slave(PTE0, PTE1); // PTE0 sda, (yellow) PTE1 scl (blue) |
JonFreeman | 3:7aaf0072cc22 | 56 | #endif |
JonFreeman | 3:7aaf0072cc22 | 57 | #if defined SPI_Enable |
JonFreeman | 3:7aaf0072cc22 | 58 | SPISlave spidevice(PTD2, PTD3, PTD1, PTD0); // mosi, miso, sclk (uses p11, p12, p13 on mbed LPC1768) |
JonFreeman | 3:7aaf0072cc22 | 59 | #endif |
JonFreeman | 0:5d0f270bfc87 | 60 | // J2p08,J2p10,J2p12, J2p06 |
JonFreeman | 0:5d0f270bfc87 | 61 | #define STEPPER_PORT PortC |
JonFreeman | 2:b3c668ec43ac | 62 | const int PortBitXSt = 3, // Port bit num X Step J1P05 D25pin 2 |
JonFreeman | 2:b3c668ec43ac | 63 | PortBitXDi = 4, // Port bit num X Dir J1P07 D25pin 3 |
JonFreeman | 2:b3c668ec43ac | 64 | PortBitYSt = 5, // Port bit num Y Step J1P09 D25pin 4 |
JonFreeman | 2:b3c668ec43ac | 65 | PortBitYDi = 6, // Port bit num Y Dir J1P11 D25pin 5 |
JonFreeman | 2:b3c668ec43ac | 66 | PortBitZSt = 10, // Port bit num Z Step J1P13 D25pin 6 |
JonFreeman | 2:b3c668ec43ac | 67 | PortBitZDi = 11, // Port bit num Z Dir J1P15 D25pin 7 |
JonFreeman | 2:b3c668ec43ac | 68 | PortBitASt = 12, // Port bit num A Step J2P01 D25pin 8 |
JonFreeman | 2:b3c668ec43ac | 69 | PortBitADi = 13, // Port bit num A Dir J2P03 D25pin 9 |
JonFreeman | 2:b3c668ec43ac | 70 | PortBitSSt = 8, // Port bit num Spin Step J1P14 D25pin 14 |
JonFreeman | 2:b3c668ec43ac | 71 | PortBitSDi = 9; // Port bit num Spin Dir J1P16 D25pin 16 |
JonFreeman | 0:5d0f270bfc87 | 72 | #endif |
JonFreeman | 2:b3c668ec43ac | 73 | |
JonFreeman | 2:b3c668ec43ac | 74 | |
JonFreeman | 2:b3c668ec43ac | 75 | |
JonFreeman | 0:5d0f270bfc87 | 76 | #if defined (TARGET_KL46Z) |
JonFreeman | 2:b3c668ec43ac | 77 | const char Target[] = "KL46Z"; |
JonFreeman | 2:b3c668ec43ac | 78 | DigitalOut intled (PTE1); //J2p20 checked |
JonFreeman | 2:b3c668ec43ac | 79 | |
JonFreeman | 2:b3c668ec43ac | 80 | |
JonFreeman | 2:b3c668ec43ac | 81 | DigitalOut charge_pumpD25pin1 (PTE0); //J2p18 checked |
JonFreeman | 2:b3c668ec43ac | 82 | // InterruptIn D25pin10_EStop (PTE20); // j4p1 KL46 J4 is KL25 J10 |
JonFreeman | 2:b3c668ec43ac | 83 | DigitalIn D25pin10_EStop (PTE20); // j4p1 KL46 J4 is KL25 J10 checked |
JonFreeman | 2:b3c668ec43ac | 84 | DigitalIn D25pin11_XLim (PTE21); // j4p3 checked |
JonFreeman | 2:b3c668ec43ac | 85 | DigitalIn D25pin12_YLim (PTE22); // j4p5 checked |
JonFreeman | 2:b3c668ec43ac | 86 | DigitalIn D25pin13_ZLim (PTE23); // j4p7 checked |
JonFreeman | 2:b3c668ec43ac | 87 | DigitalIn D25pin15_unkn (PTE30); // j4p11 checked |
JonFreeman | 3:7aaf0072cc22 | 88 | #if defined I2C_Enable |
JonFreeman | 3:7aaf0072cc22 | 89 | I2CSlave slave(p9, p10); |
JonFreeman | 3:7aaf0072cc22 | 90 | #endif |
JonFreeman | 3:7aaf0072cc22 | 91 | #if defined SPI_Enable |
JonFreeman | 0:5d0f270bfc87 | 92 | SPISlave spidevice(PTA16, PTA17, PTA15, PTA14); // mosi, miso, sclk, ssel (uses p11, p12, p13, p? on mbed LPC) |
JonFreeman | 3:7aaf0072cc22 | 93 | #endif |
JonFreeman | 0:5d0f270bfc87 | 94 | // J2p13, J2p15, J2p11, J2p09 |
JonFreeman | 2:b3c668ec43ac | 95 | // Easy way to allocate port bits for |
JonFreeman | 0:5d0f270bfc87 | 96 | // output of stepper motor Step and DIR sigs |
JonFreeman | 0:5d0f270bfc87 | 97 | #define STEPPER_PORT PortC |
JonFreeman | 2:b3c668ec43ac | 98 | const int PortBitXSt = 0, // Port bit num X Step J1P05 D25pin 2 checked |
JonFreeman | 2:b3c668ec43ac | 99 | PortBitXDi = 4, // Port bit num X Dir J1P07 D25pin 3 checked |
JonFreeman | 2:b3c668ec43ac | 100 | PortBitYSt = 6, // Port bit num Y Step J1P09 D25pin 4 checked |
JonFreeman | 2:b3c668ec43ac | 101 | PortBitYDi = 7, // Port bit num Y Dir J1P11 D25pin 5 checked |
JonFreeman | 2:b3c668ec43ac | 102 | PortBitZSt = 10, // Port bit num Z Step J1P13 D25pin 6 checked |
JonFreeman | 2:b3c668ec43ac | 103 | PortBitZDi = 11, // Port bit num Z Dir J1P15 D25pin 7 checked |
JonFreeman | 2:b3c668ec43ac | 104 | PortBitASt = 13, // Port bit num A Step J2P01 D25pin 8 checked |
JonFreeman | 2:b3c668ec43ac | 105 | PortBitADi = 16, // Port bit num A Dir J2P03 D25pin 9 checked |
JonFreeman | 2:b3c668ec43ac | 106 | PortBitSSt = 8, // Port bit num Spin Step J1P14 D25pin 14 checked |
JonFreeman | 2:b3c668ec43ac | 107 | PortBitSDi = 9; // Port bit num Spin Dir J1P16 D25pin 16 checked |
JonFreeman | 0:5d0f270bfc87 | 108 | #endif |
JonFreeman | 0:5d0f270bfc87 | 109 | #if defined (TARGET_MBED_LPC1768) |
JonFreeman | 2:b3c668ec43ac | 110 | const char Target[] = "MBED LPC1768"; |
JonFreeman | 1:66ee619f206b | 111 | DigitalOut intled(LED2); // Correct |
JonFreeman | 3:7aaf0072cc22 | 112 | DigitalOut charge_pumpD25pin1 (p25); // |
JonFreeman | 2:b3c668ec43ac | 113 | // InterruptIn D25pin10_EStop (p26); //P2.0 |
JonFreeman | 2:b3c668ec43ac | 114 | DigitalIn D25pin10_EStop (p26); //P2.0 |
JonFreeman | 2:b3c668ec43ac | 115 | DigitalIn D25pin11_XLim (p24); //P2.2 |
JonFreeman | 2:b3c668ec43ac | 116 | DigitalIn D25pin12_YLim (p23); //P2.3 |
JonFreeman | 2:b3c668ec43ac | 117 | DigitalIn D25pin13_ZLim (p19); //P1.30 |
JonFreeman | 2:b3c668ec43ac | 118 | DigitalIn D25pin15_unkn (p20); //P1.31 |
JonFreeman | 3:7aaf0072cc22 | 119 | #if defined I2C_Enable |
JonFreeman | 3:7aaf0072cc22 | 120 | I2CSlave slave(p9, p10); |
JonFreeman | 3:7aaf0072cc22 | 121 | #endif |
JonFreeman | 3:7aaf0072cc22 | 122 | #if defined SPI_Enable |
JonFreeman | 0:5d0f270bfc87 | 123 | SPISlave spidevice(p5, p6, p7, p8); |
JonFreeman | 3:7aaf0072cc22 | 124 | #endif |
JonFreeman | 3:7aaf0072cc22 | 125 | // Easy way to allocate port bits |
JonFreeman | 0:5d0f270bfc87 | 126 | // output of stepper motor Step and DIR sigs |
JonFreeman | 0:5d0f270bfc87 | 127 | #define STEPPER_PORT Port0 |
JonFreeman | 0:5d0f270bfc87 | 128 | /* Port 0 bits routed to DIP pins as follows:- |
JonFreeman | 0:5d0f270bfc87 | 129 | P0.00 p09 Reserve SDA |
JonFreeman | 0:5d0f270bfc87 | 130 | P0.01 p10 Reserve SCL |
JonFreeman | 2:b3c668ec43ac | 131 | P0.04 p30 CAN rd - USE X Step D25pin 2 |
JonFreeman | 2:b3c668ec43ac | 132 | P0.05 p29 CAN td - USE X Dir D25pin 3 |
JonFreeman | 2:b3c668ec43ac | 133 | P0.10 p28 SDA - USE Y Step D25pin 4 |
JonFreeman | 2:b3c668ec43ac | 134 | P0.11 p27 SCL - USE Y Dir D25pin 5 |
JonFreeman | 2:b3c668ec43ac | 135 | P0.15 p13 Tx - USE Z Step D25pin 6 |
JonFreeman | 2:b3c668ec43ac | 136 | P0.16 p14 Rx - USE Z Dir D25pin 7 |
JonFreeman | 2:b3c668ec43ac | 137 | P0.17 p12 miso - USE A Step D25pin 8 |
JonFreeman | 2:b3c668ec43ac | 138 | P0.18 p11 mosi - Use A Dir D25pin 9 |
JonFreeman | 2:b3c668ec43ac | 139 | P0.23 p15 A In - Use S Step D25pin 14 |
JonFreeman | 2:b3c668ec43ac | 140 | P0.24 p16 A In - Use S Dir D25pin 16 |
JonFreeman | 2:b3c668ec43ac | 141 | P0.25 p17 Reserve A In |
JonFreeman | 0:5d0f270bfc87 | 142 | P0.26 p18 Reserve A Out |
JonFreeman | 0:5d0f270bfc87 | 143 | */ |
JonFreeman | 2:b3c668ec43ac | 144 | const int PortBitXSt = 4, // Port bit num X Step |
JonFreeman | 2:b3c668ec43ac | 145 | PortBitXDi = 5, // Port bit num X Dir |
JonFreeman | 2:b3c668ec43ac | 146 | PortBitYSt = 10, // Port bit num Y Step |
JonFreeman | 2:b3c668ec43ac | 147 | PortBitYDi = 11, // Port bit num Y Dir |
JonFreeman | 2:b3c668ec43ac | 148 | PortBitZSt = 15, // Port bit num Z Step |
JonFreeman | 2:b3c668ec43ac | 149 | PortBitZDi = 16, // Port bit num Z Dir |
JonFreeman | 2:b3c668ec43ac | 150 | PortBitASt = 17, // Port bit num A Step |
JonFreeman | 2:b3c668ec43ac | 151 | PortBitADi = 18, // Port bit num A Dir |
JonFreeman | 2:b3c668ec43ac | 152 | PortBitSSt = 23, // Port bit num Spin Step |
JonFreeman | 2:b3c668ec43ac | 153 | PortBitSDi = 24; // Port bit num Spin Dir |
JonFreeman | 0:5d0f270bfc87 | 154 | #endif |
JonFreeman | 0:5d0f270bfc87 | 155 | |
JonFreeman | 2:b3c668ec43ac | 156 | const long // Assemble mask bits from now known port bit positions |
JonFreeman | 3:7aaf0072cc22 | 157 | XSt = 1 << PortBitXSt, // X axis Step signal |
JonFreeman | 3:7aaf0072cc22 | 158 | XDi = 1 << PortBitXDi, // X axis Direction signal |
JonFreeman | 3:7aaf0072cc22 | 159 | YSt = 1 << PortBitYSt, // Y axis Step, etc |
JonFreeman | 3:7aaf0072cc22 | 160 | YDi = 1 << PortBitYDi, |
JonFreeman | 3:7aaf0072cc22 | 161 | ZSt = 1 << PortBitZSt, // Z axis |
JonFreeman | 3:7aaf0072cc22 | 162 | ZDi = 1 << PortBitZDi, |
JonFreeman | 3:7aaf0072cc22 | 163 | ASt = 1 << PortBitASt, // A axis, not implemented in full, for e.g. rotary axis |
JonFreeman | 3:7aaf0072cc22 | 164 | ADi = 1 << PortBitADi, |
JonFreeman | 3:7aaf0072cc22 | 165 | SDi = 1 << PortBitSDi, // Spindle, also driven by Step and Dir signals up to 5kHz |
JonFreeman | 3:7aaf0072cc22 | 166 | SSt = 1 << PortBitSSt, // for 5000 RPM |
JonFreeman | 2:b3c668ec43ac | 167 | |
JonFreeman | 3:7aaf0072cc22 | 168 | SM_MASK = (XSt | XDi | YSt | YDi | ZSt | ZDi | ASt | ADi | SDi | SSt), |
JonFreeman | 3:7aaf0072cc22 | 169 | direction_swappers = XDi | YDi | ZDi | SDi; // include bit to swap direction |
JonFreeman | 0:5d0f270bfc87 | 170 | |
JonFreeman | 2:b3c668ec43ac | 171 | PortOut Steppers (STEPPER_PORT, SM_MASK); |
JonFreeman | 3:7aaf0072cc22 | 172 | |
JonFreeman | 3:7aaf0072cc22 | 173 | void target_cmd (struct singleGparam * a) { |
JonFreeman | 3:7aaf0072cc22 | 174 | pc.printf("Computer is %s\r\n", Target); |
JonFreeman | 3:7aaf0072cc22 | 175 | } |
JonFreeman | 3:7aaf0072cc22 | 176 | |
JonFreeman | 3:7aaf0072cc22 | 177 | void grain_clr (struct singleGparam & g) { |
JonFreeman | 3:7aaf0072cc22 | 178 | g.flt = 0.0; |
JonFreeman | 3:7aaf0072cc22 | 179 | g.ul = 0L; |
JonFreeman | 3:7aaf0072cc22 | 180 | g.i = g.c = 0; |
JonFreeman | 3:7aaf0072cc22 | 181 | g.changed = false; |
JonFreeman | 3:7aaf0072cc22 | 182 | } |
JonFreeman | 3:7aaf0072cc22 | 183 | void Gparams_clr (struct Gparams & p) { |
JonFreeman | 3:7aaf0072cc22 | 184 | grain_clr (p.x); grain_clr (p.y); grain_clr (p.z); grain_clr (p.i); grain_clr (p.j); |
JonFreeman | 3:7aaf0072cc22 | 185 | grain_clr (p.r); grain_clr (p.a); grain_clr (p.b); grain_clr (p.c); grain_clr (p.d); |
JonFreeman | 3:7aaf0072cc22 | 186 | } |
JonFreeman | 3:7aaf0072cc22 | 187 | |
JonFreeman | 2:b3c668ec43ac | 188 | class digital_readout_stuff { // class does not need to be named here |
JonFreeman | 2:b3c668ec43ac | 189 | private: |
JonFreeman | 2:b3c668ec43ac | 190 | char * readout (char * txt, long p) // p has running subtotal of all pulses issued to stepper driver |
JonFreeman | 2:b3c668ec43ac | 191 | { |
JonFreeman | 2:b3c668ec43ac | 192 | txt[0] = '+'; // constructs string e.g. "+123.456" |
JonFreeman | 2:b3c668ec43ac | 193 | txt[8] = 0; // null terminated |
JonFreeman | 2:b3c668ec43ac | 194 | if (p < 0) { |
JonFreeman | 2:b3c668ec43ac | 195 | txt[0] = '-'; |
JonFreeman | 2:b3c668ec43ac | 196 | p = -p; |
JonFreeman | 2:b3c668ec43ac | 197 | } |
JonFreeman | 2:b3c668ec43ac | 198 | p *= 1000; |
JonFreeman | 2:b3c668ec43ac | 199 | p /= pulses_per_mm; |
JonFreeman | 2:b3c668ec43ac | 200 | if (p > 999999) { |
JonFreeman | 2:b3c668ec43ac | 201 | sprintf(txt + 1, "OVRANGE"); |
JonFreeman | 2:b3c668ec43ac | 202 | return txt; |
JonFreeman | 2:b3c668ec43ac | 203 | } |
JonFreeman | 2:b3c668ec43ac | 204 | for(int k = 7; k > 0; k--) { |
JonFreeman | 2:b3c668ec43ac | 205 | if (k == 4) |
JonFreeman | 2:b3c668ec43ac | 206 | txt[k] = '.'; |
JonFreeman | 2:b3c668ec43ac | 207 | else { |
JonFreeman | 2:b3c668ec43ac | 208 | txt[k] = '0' + (p % 10); |
JonFreeman | 2:b3c668ec43ac | 209 | p /= 10; |
JonFreeman | 2:b3c668ec43ac | 210 | } |
JonFreeman | 2:b3c668ec43ac | 211 | } |
JonFreeman | 2:b3c668ec43ac | 212 | return txt; // Returns pointer unaltered for subsequent use by e.g. cout |
JonFreeman | 2:b3c668ec43ac | 213 | } |
JonFreeman | 2:b3c668ec43ac | 214 | public: |
JonFreeman | 2:b3c668ec43ac | 215 | signed long x, y, z, a; // Could easily expand up to six or more dros |
JonFreeman | 3:7aaf0072cc22 | 216 | // bool dro_output; // To enabe / disable output to terminal |
JonFreeman | 2:b3c668ec43ac | 217 | void init () { |
JonFreeman | 2:b3c668ec43ac | 218 | x = y = z = a = 0; // These dro registers count pulses delivered to stepper motor driver |
JonFreeman | 3:7aaf0072cc22 | 219 | // dro_output = true; |
JonFreeman | 2:b3c668ec43ac | 220 | } |
JonFreeman | 2:b3c668ec43ac | 221 | void update () { |
JonFreeman | 2:b3c668ec43ac | 222 | static long t = 300; // Prevent display immediately upon startup |
JonFreeman | 2:b3c668ec43ac | 223 | if (millisecs < t) |
JonFreeman | 2:b3c668ec43ac | 224 | return; |
JonFreeman | 3:7aaf0072cc22 | 225 | // if(!idle && dro_output) { |
JonFreeman | 3:7aaf0072cc22 | 226 | if(!idle) { |
JonFreeman | 2:b3c668ec43ac | 227 | char txt[12]; |
JonFreeman | 2:b3c668ec43ac | 228 | pc.printf("dros X %s,", readout(txt, x)); // dro.n has running subtotal of all pulses issued to stepper driver.n |
JonFreeman | 2:b3c668ec43ac | 229 | pc.printf(" Y %s, Z ", readout(txt, y)); |
JonFreeman | 2:b3c668ec43ac | 230 | pc.printf("%s, %s\r\n", readout(txt, z), running ? "R":"idle"); |
JonFreeman | 2:b3c668ec43ac | 231 | if(!running) idle = true; // Purpose of idle flag is to stop dro updates JUST AFTER run completes. |
JonFreeman | 2:b3c668ec43ac | 232 | t = millisecs + 350; // Schedule next update after this non-blocking delay |
JonFreeman | 2:b3c668ec43ac | 233 | } |
JonFreeman | 2:b3c668ec43ac | 234 | } |
JonFreeman | 3:7aaf0072cc22 | 235 | } dro_out ; // single instance of class digital_readout_stuff |
JonFreeman | 0:5d0f270bfc87 | 236 | |
JonFreeman | 3:7aaf0072cc22 | 237 | /** |
JonFreeman | 3:7aaf0072cc22 | 238 | class circbuff { public functions |
JonFreeman | 3:7aaf0072cc22 | 239 | void init () { |
JonFreeman | 3:7aaf0072cc22 | 240 | int On_Q () { |
JonFreeman | 3:7aaf0072cc22 | 241 | bool readable () {return !buffempty; } |
JonFreeman | 3:7aaf0072cc22 | 242 | bool writeable () {return !bufffull; } |
JonFreeman | 3:7aaf0072cc22 | 243 | bool read (pirbufgrain & g) { |
JonFreeman | 3:7aaf0072cc22 | 244 | bool write (pirbufgrain & g) { |
JonFreeman | 3:7aaf0072cc22 | 245 | */ |
JonFreeman | 2:b3c668ec43ac | 246 | const int PIRBUFFSIZE = 40; // pirbufgrain are 40 bytes each |
JonFreeman | 1:66ee619f206b | 247 | class circbuff { |
JonFreeman | 1:66ee619f206b | 248 | private: |
JonFreeman | 1:66ee619f206b | 249 | pirbufgrain grain [PIRBUFFSIZE + 1]; |
JonFreeman | 1:66ee619f206b | 250 | int OnPtr, OffPtr; |
JonFreeman | 1:66ee619f206b | 251 | bool bufffull, buffempty, buffhalf; |
JonFreeman | 1:66ee619f206b | 252 | void setempty () { |
JonFreeman | 1:66ee619f206b | 253 | bufffull = false; |
JonFreeman | 1:66ee619f206b | 254 | buffhalf = false; |
JonFreeman | 1:66ee619f206b | 255 | buffempty = true; |
JonFreeman | 1:66ee619f206b | 256 | } |
JonFreeman | 1:66ee619f206b | 257 | void grain_copy (pirbufgrain & src, pirbufgrain & dest) { |
JonFreeman | 3:7aaf0072cc22 | 258 | dest.x = src.x; |
JonFreeman | 3:7aaf0072cc22 | 259 | dest.y = src.y; |
JonFreeman | 3:7aaf0072cc22 | 260 | dest.z = src.z; |
JonFreeman | 3:7aaf0072cc22 | 261 | dest.distance_code = src.distance_code; |
JonFreeman | 1:66ee619f206b | 262 | dest.f_rate = src.f_rate; // int feed rate mm per min * 1000 |
JonFreeman | 1:66ee619f206b | 263 | } |
JonFreeman | 1:66ee619f206b | 264 | public: |
JonFreeman | 1:66ee619f206b | 265 | void init () { |
JonFreeman | 1:66ee619f206b | 266 | OnPtr = OffPtr = 0; |
JonFreeman | 1:66ee619f206b | 267 | setempty (); |
JonFreeman | 1:66ee619f206b | 268 | } |
JonFreeman | 1:66ee619f206b | 269 | int On_Q () { |
JonFreeman | 1:66ee619f206b | 270 | int k; |
JonFreeman | 1:66ee619f206b | 271 | if (bufffull) return PIRBUFFSIZE; |
JonFreeman | 1:66ee619f206b | 272 | k = OnPtr - OffPtr; |
JonFreeman | 1:66ee619f206b | 273 | if (k < 0) k += PIRBUFFSIZE; |
JonFreeman | 1:66ee619f206b | 274 | if (k > PIRBUFFSIZE / 2) |
JonFreeman | 1:66ee619f206b | 275 | buffhalf = true; |
JonFreeman | 1:66ee619f206b | 276 | else |
JonFreeman | 1:66ee619f206b | 277 | buffhalf = false; |
JonFreeman | 1:66ee619f206b | 278 | return k; |
JonFreeman | 1:66ee619f206b | 279 | } |
JonFreeman | 1:66ee619f206b | 280 | bool readable () {return !buffempty; } |
JonFreeman | 1:66ee619f206b | 281 | bool writeable () {return !bufffull; } |
JonFreeman | 1:66ee619f206b | 282 | bool read (pirbufgrain & g) { |
JonFreeman | 2:b3c668ec43ac | 283 | // if (buffempty) return false; // TO DO Fix problem with buffempty flag |
JonFreeman | 2:b3c668ec43ac | 284 | if (On_Q() == 0) return false; |
JonFreeman | 1:66ee619f206b | 285 | bufffull = false; |
JonFreeman | 1:66ee619f206b | 286 | grain_copy (grain[OffPtr++], g); |
JonFreeman | 1:66ee619f206b | 287 | if (OffPtr >= PIRBUFFSIZE) |
JonFreeman | 1:66ee619f206b | 288 | OffPtr = 0; |
JonFreeman | 1:66ee619f206b | 289 | if (OnPtr == OffPtr) |
JonFreeman | 1:66ee619f206b | 290 | buffempty = true; |
JonFreeman | 1:66ee619f206b | 291 | return true; |
JonFreeman | 1:66ee619f206b | 292 | } |
JonFreeman | 1:66ee619f206b | 293 | bool write (pirbufgrain & g) { |
JonFreeman | 1:66ee619f206b | 294 | if (bufffull) return false; |
JonFreeman | 1:66ee619f206b | 295 | buffempty = false; |
JonFreeman | 1:66ee619f206b | 296 | grain_copy (g, grain[OnPtr++]); |
JonFreeman | 1:66ee619f206b | 297 | if (OnPtr >= PIRBUFFSIZE) |
JonFreeman | 1:66ee619f206b | 298 | OnPtr = 0; |
JonFreeman | 1:66ee619f206b | 299 | if (OnPtr == OffPtr) |
JonFreeman | 1:66ee619f206b | 300 | bufffull = true; |
JonFreeman | 1:66ee619f206b | 301 | return true; |
JonFreeman | 1:66ee619f206b | 302 | } |
JonFreeman | 3:7aaf0072cc22 | 303 | } CircBuff; // single instance of class circbuff |
JonFreeman | 1:66ee619f206b | 304 | |
JonFreeman | 1:66ee619f206b | 305 | |
JonFreeman | 3:7aaf0072cc22 | 306 | /** |
JonFreeman | 2:b3c668ec43ac | 307 | void move_to_XYZ (struct pirbufgrain & ins) { |
JonFreeman | 3:7aaf0072cc22 | 308 | Takes floating point x, y, z and feed_rate as input. |
JonFreeman | 3:7aaf0072cc22 | 309 | Finds distances from 'last_position' global, |
JonFreeman | 3:7aaf0072cc22 | 310 | copies structure containing floating point values for x, y, z, distance_multiplier and feed_rate |
JonFreeman | 3:7aaf0072cc22 | 311 | onto a circular buffer. |
JonFreeman | 3:7aaf0072cc22 | 312 | If buffer full, executes 'osThreadYield()' until space is created on buffer |
JonFreeman | 3:7aaf0072cc22 | 313 | */ |
JonFreeman | 3:7aaf0072cc22 | 314 | void move_to_XYZ (struct pirbufgrain & ins) { |
JonFreeman | 3:7aaf0072cc22 | 315 | static const fl_typ duration_multiplier = 60000000.0 / interrupt_period_us; |
JonFreeman | 2:b3c668ec43ac | 316 | struct pirbufgrain outs; |
JonFreeman | 3:7aaf0072cc22 | 317 | fl_typ distx = ins.x - last_position.x.flt, |
JonFreeman | 3:7aaf0072cc22 | 318 | disty = ins.y - last_position.y.flt, |
JonFreeman | 3:7aaf0072cc22 | 319 | distz = ins.z - last_position.z.flt, |
JonFreeman | 2:b3c668ec43ac | 320 | distT = sqrt ((distx * distx) + (disty * disty) + (distz * distz)), // 3D Pythag ! |
JonFreeman | 2:b3c668ec43ac | 321 | temp = n_for_onemmpermin / distT; |
JonFreeman | 2:b3c668ec43ac | 322 | if (distT < 0.01) { |
JonFreeman | 2:b3c668ec43ac | 323 | pc.printf("Very small move %.4f, Ignoring!\r\n", distT); |
JonFreeman | 3:7aaf0072cc22 | 324 | return; // Return without updating last_position as it was not changed |
JonFreeman | 2:b3c668ec43ac | 325 | } |
JonFreeman | 3:7aaf0072cc22 | 326 | last_position.x.flt = ins.x; // Update global last_position record |
JonFreeman | 3:7aaf0072cc22 | 327 | last_position.y.flt = ins.y; |
JonFreeman | 3:7aaf0072cc22 | 328 | last_position.z.flt = ins.z; |
JonFreeman | 2:b3c668ec43ac | 329 | outs.f_rate = ins.f_rate; |
JonFreeman | 3:7aaf0072cc22 | 330 | outs.distance_code = duration_multiplier * distT; // Duration ticks subject to feed rate compo |
JonFreeman | 2:b3c668ec43ac | 331 | outs.x = temp * distx; |
JonFreeman | 2:b3c668ec43ac | 332 | outs.y = temp * disty; |
JonFreeman | 2:b3c668ec43ac | 333 | outs.z = temp * distz; // Have assembled data ready to put onto queue of move instructions |
JonFreeman | 3:7aaf0072cc22 | 334 | while (!CircBuff.writeable()) |
JonFreeman | 3:7aaf0072cc22 | 335 | osThreadYield(); |
JonFreeman | 3:7aaf0072cc22 | 336 | CircBuff.write (outs); // Move details put on circular buffer |
JonFreeman | 3:7aaf0072cc22 | 337 | } |
JonFreeman | 3:7aaf0072cc22 | 338 | |
JonFreeman | 3:7aaf0072cc22 | 339 | /** |
JonFreeman | 3:7aaf0072cc22 | 340 | * Interrupt Service Routines |
JonFreeman | 3:7aaf0072cc22 | 341 | void millisec_update_ISR () { self explanatory |
JonFreeman | 3:7aaf0072cc22 | 342 | |
JonFreeman | 3:7aaf0072cc22 | 343 | void Numerically_Controlled_Oscillators_ISR () { |
JonFreeman | 3:7aaf0072cc22 | 344 | services Ticker 'NCO_gen' generated interrupts ***ISR*** |
JonFreeman | 3:7aaf0072cc22 | 345 | Does all of the stepper motor driving. |
JonFreeman | 3:7aaf0072cc22 | 346 | At end of movement, fetches and starts next move to run from circular buffer |
JonFreeman | 3:7aaf0072cc22 | 347 | If nothing buffered, stops x, y and z, leaves spindle unaltered |
JonFreeman | 3:7aaf0072cc22 | 348 | */ |
JonFreeman | 3:7aaf0072cc22 | 349 | void millisec_update_ISR () { |
JonFreeman | 3:7aaf0072cc22 | 350 | millisecs++; |
JonFreeman | 2:b3c668ec43ac | 351 | } |
JonFreeman | 2:b3c668ec43ac | 352 | |
JonFreeman | 3:7aaf0072cc22 | 353 | #define STEP_IDLE_HI // Choose IDLE_HI or LO to suit any power save function of stepper motor drive units |
JonFreeman | 3:7aaf0072cc22 | 354 | //#define STEP_IDLE_LO |
JonFreeman | 0:5d0f270bfc87 | 355 | void Numerically_Controlled_Oscillators_ISR () { // services Ticker 'NCO_gen' generated interrupts ***ISR*** |
JonFreeman | 3:7aaf0072cc22 | 356 | static const long step_mask = ASt | XSt | YSt | ZSt, // Added 6th Feb 14 Mask Does NOT include spindle bits |
JonFreeman | 3:7aaf0072cc22 | 357 | dir_mask = ADi | XDi | YDi | ZDi; // Added 6th Feb 14 Mask Does NOT include spindle bits |
JonFreeman | 3:7aaf0072cc22 | 358 | static signed long // 27 Feb 14 changed from unsigned |
JonFreeman | 3:7aaf0072cc22 | 359 | #if defined Fourth_Axis |
JonFreeman | 3:7aaf0072cc22 | 360 | acc_a = 0L, pir_a = 0L, |
JonFreeman | 3:7aaf0072cc22 | 361 | #endif |
JonFreeman | 3:7aaf0072cc22 | 362 | acc_x = 0L, // acc Accumuloators |
JonFreeman | 3:7aaf0072cc22 | 363 | pir_x = 0L, // pir Phase Increment Registers |
JonFreeman | 3:7aaf0072cc22 | 364 | acc_y = 0L, pir_y = 0L, |
JonFreeman | 3:7aaf0072cc22 | 365 | acc_z = 0L, pir_z = 0L, |
JonFreeman | 3:7aaf0072cc22 | 366 | acc_spin = 0L, // separate acc for spindle rotation NCO |
JonFreeman | 3:7aaf0072cc22 | 367 | inc_x = 1L, // inc_x, y, z for updating DRO registers |
JonFreeman | 3:7aaf0072cc22 | 368 | inc_y = 1L, inc_z = 1L, |
JonFreeman | 3:7aaf0072cc22 | 369 | dir_bits = 0L, // direction flags for up to four axes |
JonFreeman | 3:7aaf0072cc22 | 370 | oldSteps = 0L; // |
JonFreeman | 3:7aaf0072cc22 | 371 | long tmp, newSteps = 0L; |
JonFreeman | 0:5d0f270bfc87 | 372 | |
JonFreeman | 0:5d0f270bfc87 | 373 | intled = 1; // LED on for duration of interrupt service - point for scope probing |
JonFreeman | 3:7aaf0072cc22 | 374 | ticks++; // count of interrupts serviced, vital to time end of movement |
JonFreeman | 3:7aaf0072cc22 | 375 | charge_pumpD25pin1 = ticks & 0x01; // Can use 0x01 or 0x02 here to alter charge pump freq |
JonFreeman | 2:b3c668ec43ac | 376 | tmp = Steppers ^ direction_swappers; |
JonFreeman | 2:b3c668ec43ac | 377 | #if defined STEP_IDLE_LO |
JonFreeman | 2:b3c668ec43ac | 378 | tmp &= ~step_mask; // Step bits prepared for idle lo |
JonFreeman | 2:b3c668ec43ac | 379 | #endif |
JonFreeman | 2:b3c668ec43ac | 380 | #if defined STEP_IDLE_HI |
JonFreeman | 2:b3c668ec43ac | 381 | tmp |= step_mask; // Step bits prepared for idle hi |
JonFreeman | 2:b3c668ec43ac | 382 | #endif |
JonFreeman | 3:7aaf0072cc22 | 383 | acc_spin += pir_spin; // Spindle NCO |
JonFreeman | 3:7aaf0072cc22 | 384 | if (acc_spin < 0) tmp |= SSt; |
JonFreeman | 3:7aaf0072cc22 | 385 | else tmp &= ~SSt; |
JonFreeman | 3:7aaf0072cc22 | 386 | if (!running) Steppers = tmp ^ direction_swappers; // Axes not moving, spindle may be turning or not |
JonFreeman | 3:7aaf0072cc22 | 387 | else { // running == true, Further manipulation of tmp follows, prior to rewriting to 'Steppers' IO Port |
JonFreeman | 3:7aaf0072cc22 | 388 | // newSteps = 0L; // Added 6th Feb 14 |
JonFreeman | 3:7aaf0072cc22 | 389 | #if defined Fourth_Axis |
JonFreeman | 3:7aaf0072cc22 | 390 | acc_a += pir_a; |
JonFreeman | 3:7aaf0072cc22 | 391 | if (acc_a < 0) newSteps |= ASt;// Added 6th Feb 14 |
JonFreeman | 3:7aaf0072cc22 | 392 | #endif |
JonFreeman | 3:7aaf0072cc22 | 393 | acc_x += pir_x; // Update phase of signals in accumulators |
JonFreeman | 3:7aaf0072cc22 | 394 | if (acc_x < 0) newSteps |= XSt;// Added 6th Feb 14 |
JonFreeman | 3:7aaf0072cc22 | 395 | acc_y += pir_y; |
JonFreeman | 3:7aaf0072cc22 | 396 | if (acc_y < 0) newSteps |= YSt;// Added 6th Feb 14 |
JonFreeman | 3:7aaf0072cc22 | 397 | acc_z += pir_z; |
JonFreeman | 3:7aaf0072cc22 | 398 | if (acc_z < 0) newSteps |= ZSt;// Added 6th Feb 14 |
JonFreeman | 3:7aaf0072cc22 | 399 | // newSteps has copy of all 4 'acc' MSBs shifted into port bit positions |
JonFreeman | 3:7aaf0072cc22 | 400 | oldSteps ^= newSteps; // Any bit of stbits set to initiate a Step pulse |
JonFreeman | 3:7aaf0072cc22 | 401 | tmp ^= oldSteps; |
JonFreeman | 2:b3c668ec43ac | 402 | Steppers = tmp ^ direction_swappers; // Output signals to stepper motor drivers, next update dros from 'clocked' bits CLOCK IDLES HIGH |
JonFreeman | 3:7aaf0072cc22 | 403 | if(oldSteps & XSt) dro_out.x += inc_x; // got clk edge for axis X |
JonFreeman | 3:7aaf0072cc22 | 404 | if(oldSteps & YSt) dro_out.y += inc_y; // got clk edge for axis Y |
JonFreeman | 3:7aaf0072cc22 | 405 | if(oldSteps & ZSt) dro_out.z += inc_z; // got clk edge for axis Z |
JonFreeman | 3:7aaf0072cc22 | 406 | oldSteps = newSteps; // Added 6th Feb 14 |
JonFreeman | 3:7aaf0072cc22 | 407 | if (tickrun <= ticks & !new_run_pending) { // End of a machine movement detected, start next move here if possible |
JonFreeman | 2:b3c668ec43ac | 408 | running = false; |
JonFreeman | 2:b3c668ec43ac | 409 | move_ended = true; |
JonFreeman | 2:b3c668ec43ac | 410 | pir_x = 0L; // stop all stepper motors |
JonFreeman | 2:b3c668ec43ac | 411 | pir_y = 0L; |
JonFreeman | 2:b3c668ec43ac | 412 | pir_z = 0L; |
JonFreeman | 3:7aaf0072cc22 | 413 | #if defined Fourth_Axis |
JonFreeman | 2:b3c668ec43ac | 414 | pir_a = 0L; |
JonFreeman | 3:7aaf0072cc22 | 415 | #endif |
JonFreeman | 2:b3c668ec43ac | 416 | // ticks = 0L; // Simply to avoid having to think about overflow problems |
JonFreeman | 3:7aaf0072cc22 | 417 | } // end of if (tickrun <= ticks) { |
JonFreeman | 3:7aaf0072cc22 | 418 | } // end of else is (running) { |
JonFreeman | 3:7aaf0072cc22 | 419 | if (!running & new_run_pending) { // Start axis movement |
JonFreeman | 3:7aaf0072cc22 | 420 | dir_bits= dir_bits_next; |
JonFreeman | 3:7aaf0072cc22 | 421 | #if defined Fourth_Axis |
JonFreeman | 3:7aaf0072cc22 | 422 | pir_a = pir_a_next; |
JonFreeman | 3:7aaf0072cc22 | 423 | #endif |
JonFreeman | 3:7aaf0072cc22 | 424 | pir_x = pir_x_next; |
JonFreeman | 3:7aaf0072cc22 | 425 | pir_y = pir_y_next; |
JonFreeman | 3:7aaf0072cc22 | 426 | pir_z = pir_z_next; |
JonFreeman | 3:7aaf0072cc22 | 427 | inc_x = inc_x_next; |
JonFreeman | 3:7aaf0072cc22 | 428 | inc_y = inc_y_next; |
JonFreeman | 3:7aaf0072cc22 | 429 | inc_z = inc_z_next; |
JonFreeman | 3:7aaf0072cc22 | 430 | tmp = Steppers ^ direction_swappers; // read output lines |
JonFreeman | 3:7aaf0072cc22 | 431 | tmp &= ~dir_mask; |
JonFreeman | 3:7aaf0072cc22 | 432 | tmp |= dir_bits; |
JonFreeman | 2:b3c668ec43ac | 433 | Steppers = tmp ^ direction_swappers; |
JonFreeman | 3:7aaf0072cc22 | 434 | tickrun = ticks + ticks_next; |
JonFreeman | 3:7aaf0072cc22 | 435 | running = true; // Start the new run |
JonFreeman | 3:7aaf0072cc22 | 436 | new_run_pending = false; // Clear the flag which initiated this update |
JonFreeman | 3:7aaf0072cc22 | 437 | idle = false; |
JonFreeman | 2:b3c668ec43ac | 438 | } // end of else { // Not running. Grab next data here when or if available |
JonFreeman | 2:b3c668ec43ac | 439 | intled = 0; // LED off |
JonFreeman | 2:b3c668ec43ac | 440 | } // end of interrupt handler |
JonFreeman | 2:b3c668ec43ac | 441 | |
JonFreeman | 2:b3c668ec43ac | 442 | /* |
JonFreeman | 2:b3c668ec43ac | 443 | * End of Interrupt Service Routine |
JonFreeman | 2:b3c668ec43ac | 444 | */ |
JonFreeman | 2:b3c668ec43ac | 445 | bool spindle_running () { |
JonFreeman | 3:7aaf0072cc22 | 446 | if (pir_spin == 0) return false; |
JonFreeman | 3:7aaf0072cc22 | 447 | return true; |
JonFreeman | 2:b3c668ec43ac | 448 | } |
JonFreeman | 3:7aaf0072cc22 | 449 | void spindle_control (signed long ss) { |
JonFreeman | 2:b3c668ec43ac | 450 | long t, p; |
JonFreeman | 3:7aaf0072cc22 | 451 | pir_spin = ss * spindle_factor; |
JonFreeman | 2:b3c668ec43ac | 452 | t = ticks; |
JonFreeman | 2:b3c668ec43ac | 453 | while (t == ticks) {} // wait until just after next interrupt |
JonFreeman | 2:b3c668ec43ac | 454 | p = Steppers ^ direction_swappers; |
JonFreeman | 3:7aaf0072cc22 | 455 | if (pir_spin & 0x80000000) p |= SDi; |
JonFreeman | 3:7aaf0072cc22 | 456 | else p &= ~SDi; |
JonFreeman | 2:b3c668ec43ac | 457 | Steppers = p ^ direction_swappers; |
JonFreeman | 3:7aaf0072cc22 | 458 | pc.printf("Done setting spindle speed %d, pir_spin %d, delay = %d\r\n", ss, pir_spin, ticks - t); |
JonFreeman | 2:b3c668ec43ac | 459 | } |
JonFreeman | 2:b3c668ec43ac | 460 | |
JonFreeman | 3:7aaf0072cc22 | 461 | /** |
JonFreeman | 3:7aaf0072cc22 | 462 | void pir_updater_task (void const * name) { |
JonFreeman | 3:7aaf0072cc22 | 463 | A task handed to the RTOS Round Robin |
JonFreeman | 3:7aaf0072cc22 | 464 | ISR controls certain flags. |
JonFreeman | 3:7aaf0072cc22 | 465 | This task responds after 'move_ended' flag asserted by NCO ISR |
JonFreeman | 3:7aaf0072cc22 | 466 | If CircBuff not empty, set of floating point data for next point is fetched, |
JonFreeman | 3:7aaf0072cc22 | 467 | remaining calcs performed and translated into signed longs, results placed in |
JonFreeman | 3:7aaf0072cc22 | 468 | set of '_next' locations to be picked up by future NCO ISR |
JonFreeman | 2:b3c668ec43ac | 469 | */ |
JonFreeman | 3:7aaf0072cc22 | 470 | void pir_updater_task (void const * name) { |
JonFreeman | 2:b3c668ec43ac | 471 | static long x, y, z;//, count = 0; |
JonFreeman | 1:66ee619f206b | 472 | struct pirbufgrain outs; |
JonFreeman | 1:66ee619f206b | 473 | while (true) { |
JonFreeman | 2:b3c668ec43ac | 474 | // while (!move_ended || !CircBuff.readable()) { ** TO DO ** Solve problem with empty flag |
JonFreeman | 2:b3c668ec43ac | 475 | while (!move_ended || CircBuff.On_Q() == 0) { |
JonFreeman | 1:66ee619f206b | 476 | osThreadYield(); |
JonFreeman | 2:b3c668ec43ac | 477 | } // Proceed beyond here only when move_ended AND CircBuff.readable() both TRUE |
JonFreeman | 1:66ee619f206b | 478 | CircBuff.read(outs); |
JonFreeman | 1:66ee619f206b | 479 | x = (long)(outs.f_rate * outs.x); // These take much CPU time !! |
JonFreeman | 1:66ee619f206b | 480 | y = (long)(outs.f_rate * outs.y); |
JonFreeman | 1:66ee619f206b | 481 | z = (long)(outs.f_rate * outs.z); |
JonFreeman | 3:7aaf0072cc22 | 482 | ticks_next = (unsigned long)(outs.distance_code / outs.f_rate); |
JonFreeman | 1:66ee619f206b | 483 | pir_x_next = x; |
JonFreeman | 1:66ee619f206b | 484 | pir_y_next = y; |
JonFreeman | 1:66ee619f206b | 485 | pir_z_next = z; |
JonFreeman | 3:7aaf0072cc22 | 486 | dir_bits_next = 0; |
JonFreeman | 3:7aaf0072cc22 | 487 | //if (pir_a & 0x80000000) dir_bits_next |= ADi;// Added 6th Feb 14 read sign bits |
JonFreeman | 3:7aaf0072cc22 | 488 | inc_x_next = inc_y_next = inc_z_next = 1L; |
JonFreeman | 3:7aaf0072cc22 | 489 | if (x < 0) { |
JonFreeman | 3:7aaf0072cc22 | 490 | dir_bits_next |= XDi; |
JonFreeman | 3:7aaf0072cc22 | 491 | inc_x_next = -1L; |
JonFreeman | 3:7aaf0072cc22 | 492 | } |
JonFreeman | 3:7aaf0072cc22 | 493 | if (y < 0) { |
JonFreeman | 3:7aaf0072cc22 | 494 | dir_bits_next |= YDi; |
JonFreeman | 3:7aaf0072cc22 | 495 | inc_y_next = -1L; |
JonFreeman | 3:7aaf0072cc22 | 496 | } |
JonFreeman | 3:7aaf0072cc22 | 497 | if (z < 0) { |
JonFreeman | 3:7aaf0072cc22 | 498 | dir_bits_next |= ZDi; |
JonFreeman | 3:7aaf0072cc22 | 499 | inc_z_next = -1L; |
JonFreeman | 3:7aaf0072cc22 | 500 | } |
JonFreeman | 2:b3c668ec43ac | 501 | move_ended = idle = false; |
JonFreeman | 1:66ee619f206b | 502 | new_run_pending = true; // cleared and 'running' flag set in interrupt handler |
JonFreeman | 3:7aaf0072cc22 | 503 | } // end of while (true) { |
JonFreeman | 0:5d0f270bfc87 | 504 | } |
JonFreeman | 0:5d0f270bfc87 | 505 | |
JonFreeman | 1:66ee619f206b | 506 | |
JonFreeman | 2:b3c668ec43ac | 507 | void flags_report_cmd (struct singleGparam * a) { // Diagnostic helper function |
JonFreeman | 2:b3c668ec43ac | 508 | pc.printf("Flags Report\r\nRunning %s\r\n", running ? "T":"F"); |
JonFreeman | 2:b3c668ec43ac | 509 | pc.printf("idle %s\r\n", idle ? "T":"F"); |
JonFreeman | 2:b3c668ec43ac | 510 | pc.printf("new_run_pending %s\r\n", new_run_pending ? "T":"F"); |
JonFreeman | 2:b3c668ec43ac | 511 | pc.printf("move_ended %s\r\n", move_ended ? "T":"F"); |
JonFreeman | 2:b3c668ec43ac | 512 | pc.printf("CircBuff.readable() %s\r\n", CircBuff.readable() ? "T":"F"); |
JonFreeman | 2:b3c668ec43ac | 513 | pc.printf("On CircBuff %d\r\n", CircBuff.On_Q()); |
JonFreeman | 2:b3c668ec43ac | 514 | } |
JonFreeman | 1:66ee619f206b | 515 | |
JonFreeman | 2:b3c668ec43ac | 516 | /* |
JonFreeman | 2:b3c668ec43ac | 517 | #define ESTOP 0x100 |
JonFreeman | 2:b3c668ec43ac | 518 | #define XLIM 1 |
JonFreeman | 2:b3c668ec43ac | 519 | #define YLIM 2 |
JonFreeman | 2:b3c668ec43ac | 520 | #define ZLIM 4 |
JonFreeman | 2:b3c668ec43ac | 521 | #define UNKN 8 |
JonFreeman | 2:b3c668ec43ac | 522 | */ |
JonFreeman | 2:b3c668ec43ac | 523 | class inputsreaderstuff { |
JonFreeman | 2:b3c668ec43ac | 524 | private: |
JonFreeman | 2:b3c668ec43ac | 525 | long ins_now;//, ins_old, ins_changed; |
JonFreeman | 2:b3c668ec43ac | 526 | public: |
JonFreeman | 2:b3c668ec43ac | 527 | void init () { ins_now = 0L;}//ins_old = ins_changed = 0L; } |
JonFreeman | 2:b3c668ec43ac | 528 | long read () { |
JonFreeman | 2:b3c668ec43ac | 529 | ins_now = 0; |
JonFreeman | 2:b3c668ec43ac | 530 | if (D25pin10_EStop) ins_now |= ESTOP; |
JonFreeman | 2:b3c668ec43ac | 531 | if (D25pin11_XLim) ins_now |= XLIM; |
JonFreeman | 2:b3c668ec43ac | 532 | if (D25pin12_YLim) ins_now |= YLIM; |
JonFreeman | 2:b3c668ec43ac | 533 | if (D25pin13_ZLim) ins_now |= ZLIM; |
JonFreeman | 2:b3c668ec43ac | 534 | if (D25pin15_unkn) ins_now |= UNKN; |
JonFreeman | 2:b3c668ec43ac | 535 | // ins_changed = ins_now ^ ins_old; |
JonFreeman | 2:b3c668ec43ac | 536 | // ins_old = ins_now; |
JonFreeman | 2:b3c668ec43ac | 537 | return ins_now; |
JonFreeman | 2:b3c668ec43ac | 538 | } |
JonFreeman | 2:b3c668ec43ac | 539 | // long changed () { return ins_changed; } |
JonFreeman | 2:b3c668ec43ac | 540 | } Inputs_From_Machine; |
JonFreeman | 2:b3c668ec43ac | 541 | |
JonFreeman | 2:b3c668ec43ac | 542 | void report_inputs () { |
JonFreeman | 2:b3c668ec43ac | 543 | long i = Inputs_From_Machine.read(); |
JonFreeman | 2:b3c668ec43ac | 544 | pc.printf("Inputs: EStop %d, XLim %d, YLim %d, ", i & ESTOP ? 1:0, i & XLIM ? 1:0, i & YLIM ? 1:0); |
JonFreeman | 2:b3c668ec43ac | 545 | pc.printf("ZLim %d, unkn %d\r\n", i & ZLIM ? 1:0, i & UNKN ? 1:0); |
JonFreeman | 2:b3c668ec43ac | 546 | } |
JonFreeman | 2:b3c668ec43ac | 547 | |
JonFreeman | 2:b3c668ec43ac | 548 | //void Emergency_Stop_Interrupt () { |
JonFreeman | 2:b3c668ec43ac | 549 | // pc.printf("Emergency Stop Activated !!\r\n"); |
JonFreeman | 3:7aaf0072cc22 | 550 | // spindle_control (0); // Stop spindle rotation |
JonFreeman | 2:b3c668ec43ac | 551 | //} |
JonFreeman | 1:66ee619f206b | 552 | |
JonFreeman | 3:7aaf0072cc22 | 553 | /** |
JonFreeman | 0:5d0f270bfc87 | 554 | int main() { |
JonFreeman | 3:7aaf0072cc22 | 555 | |
JonFreeman | 3:7aaf0072cc22 | 556 | */ |
JonFreeman | 3:7aaf0072cc22 | 557 | int main() { |
JonFreeman | 3:7aaf0072cc22 | 558 | long ins, ins_old, ins_changed = 0; |
JonFreeman | 0:5d0f270bfc87 | 559 | pc.baud(BAUD); // comms to 'PuTTY' serial terminal via mbed usb |
JonFreeman | 2:b3c668ec43ac | 560 | // D25pin11_XLim.mode (PullDown); External resistors now fitted |
JonFreeman | 2:b3c668ec43ac | 561 | // D25pin12_YLim.mode (PullDown); |
JonFreeman | 2:b3c668ec43ac | 562 | // D25pin13_ZLim.mode (PullDown); |
JonFreeman | 2:b3c668ec43ac | 563 | // D25pin15_unkn.mode (PullDown); |
JonFreeman | 2:b3c668ec43ac | 564 | // D25pin10_EStop.mode (PullDown); |
JonFreeman | 2:b3c668ec43ac | 565 | // D25pin10_EStop.rise (& Emergency_Stop_Interrupt); |
JonFreeman | 2:b3c668ec43ac | 566 | // D25pin10_EStop.fall (& Emergency_Stop_Interrupt); |
JonFreeman | 3:7aaf0072cc22 | 567 | |
JonFreeman | 3:7aaf0072cc22 | 568 | Gparams_clr (last_position); |
JonFreeman | 3:7aaf0072cc22 | 569 | dro_out.init (); |
JonFreeman | 1:66ee619f206b | 570 | CircBuff.init (); |
JonFreeman | 2:b3c668ec43ac | 571 | Inputs_From_Machine.init (); |
JonFreeman | 3:7aaf0072cc22 | 572 | #if defined SPI_Enable |
JonFreeman | 0:5d0f270bfc87 | 573 | spidevice.format(8, 0); // 8 bits mode 0, // p11 mosi, p12 miso, p13 sclk ** ONLY 8 BIT ** |
JonFreeman | 0:5d0f270bfc87 | 574 | spidevice.frequency(12000000); // 12MHz bit rate |
JonFreeman | 3:7aaf0072cc22 | 575 | #endif |
JonFreeman | 2:b3c668ec43ac | 576 | pc.printf("\r\n*\n*\nFound Computer %s\r\n", Target); |
JonFreeman | 1:66ee619f206b | 577 | pc.printf("Welcome to the CNC tester\r\nStep pulses required to move 1.0mm = %9.0f\r\n", pulses_per_mm); |
JonFreeman | 3:7aaf0072cc22 | 578 | pc.printf("PIR 'n' for 1mm per min = %9.0f\r\ntop speed = %d mm per min\r\n\n", n_for_onemmpermin, feed_rate_max); |
JonFreeman | 3:7aaf0072cc22 | 579 | |
JonFreeman | 3:7aaf0072cc22 | 580 | |
JonFreeman | 3:7aaf0072cc22 | 581 | // NVIC_SetPriority(TIMER3_IRQn, 255); // set mbed tickers to lower priority than other things ONLY COMPILES FOR LPC1768 |
JonFreeman | 3:7aaf0072cc22 | 582 | |
JonFreeman | 3:7aaf0072cc22 | 583 | |
JonFreeman | 3:7aaf0072cc22 | 584 | NCO_gen.attach_us(&Numerically_Controlled_Oscillators_ISR, interrupt_period_us);// Have setup timed interrupts, let other code deal |
JonFreeman | 3:7aaf0072cc22 | 585 | msec.attach_us(&millisec_update_ISR, 1001); |
JonFreeman | 3:7aaf0072cc22 | 586 | |
JonFreeman | 3:7aaf0072cc22 | 587 | Thread tsr2 (pir_updater_task, (void *)"read from CircBuff and move"); |
JonFreeman | 1:66ee619f206b | 588 | Thread comlin (command_line_interpreter, (void *)"cli"); // Read any instructions arriving via serial port and act upon them |
JonFreeman | 3:7aaf0072cc22 | 589 | #if defined I2C_Enable |
JonFreeman | 3:7aaf0072cc22 | 590 | Thread i2cstuff (i2c_handler, (void *)"i2c thing"); |
JonFreeman | 3:7aaf0072cc22 | 591 | #endif |
JonFreeman | 2:b3c668ec43ac | 592 | ins = ins_old = Inputs_From_Machine.read (); |
JonFreeman | 1:66ee619f206b | 593 | move_ended = true; // Needed to kickstart system |
JonFreeman | 1:66ee619f206b | 594 | |
JonFreeman | 1:66ee619f206b | 595 | while(1) { // Round Robin loop |
JonFreeman | 1:66ee619f206b | 596 | dro_out.update (); // Update DRO readings if, and as often as needed |
JonFreeman | 2:b3c668ec43ac | 597 | ins = Inputs_From_Machine.read (); |
JonFreeman | 2:b3c668ec43ac | 598 | ins_changed = ins ^ ins_old; |
JonFreeman | 2:b3c668ec43ac | 599 | ins_old = ins; |
JonFreeman | 2:b3c668ec43ac | 600 | if (ins_changed) |
JonFreeman | 2:b3c668ec43ac | 601 | pc.printf("Inputs Have Changed 0x%x, read 0x%x\r\n", ins_changed, ins); |
JonFreeman | 1:66ee619f206b | 602 | osThreadYield(); // |
JonFreeman | 1:66ee619f206b | 603 | } // end of Round Robin loop |
JonFreeman | 1:66ee619f206b | 604 | } // end of int main() |
JonFreeman | 1:66ee619f206b | 605 |