Firmware for single step driver with fast step (up to 340kHz) and simple gcode interpreter.

Dependencies:   FastPWM SimpleIOMacros mbed

Committer:
daapp
Date:
Mon Feb 25 23:27:01 2013 +0000
Revision:
0:b53649cd217f
Child:
1:86997189bb6b
Implement base G-code command recognition.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daapp 0:b53649cd217f 1 /* picocom -b 115200 -c --imap lfcrlf --omap crlf /dev/ttyACM0 */
daapp 0:b53649cd217f 2
daapp 0:b53649cd217f 3
daapp 0:b53649cd217f 4 /*
daapp 0:b53649cd217f 5 todo: attach callback to Serial when no command executed only with STOP command
daapp 0:b53649cd217f 6 todo: when command complete it should print "ok"
daapp 0:b53649cd217f 7 todo: when all settings printed print "ok"
daapp 0:b53649cd217f 8 todo: when value of parameter changed print "ok saved"
daapp 0:b53649cd217f 9 todo: when value of parameter is invalid print "err invalid value"
daapp 0:b53649cd217f 10 todo: add G command for set zero here
daapp 0:b53649cd217f 11 todo: add G90/G91
daapp 0:b53649cd217f 12 */
daapp 0:b53649cd217f 13
daapp 0:b53649cd217f 14 #include "mbed.h"
daapp 0:b53649cd217f 15 #include "FastPWM.h"
daapp 0:b53649cd217f 16 #include "IOMacros.h"
daapp 0:b53649cd217f 17
daapp 0:b53649cd217f 18 #define VERSION "0.1"
daapp 0:b53649cd217f 19
daapp 0:b53649cd217f 20
daapp 0:b53649cd217f 21 #define DEBUG
daapp 0:b53649cd217f 22
daapp 0:b53649cd217f 23 /* p30 - P0_4 */
daapp 0:b53649cd217f 24 const uint32_t stepPin = 4;
daapp 0:b53649cd217f 25 const uint32_t stepIntMask = (1UL << stepPin);
daapp 0:b53649cd217f 26
daapp 0:b53649cd217f 27 volatile int32_t position;
daapp 0:b53649cd217f 28
daapp 0:b53649cd217f 29
daapp 0:b53649cd217f 30 /* G code interpreter state*/
daapp 0:b53649cd217f 31 bool absMovementMode = true;
daapp 0:b53649cd217f 32 double mmPosition = 0.0; // mm
daapp 0:b53649cd217f 33 double feedRate = 0.0; // mm/sec^2
daapp 0:b53649cd217f 34
daapp 0:b53649cd217f 35 /* *** Serial port *** */
daapp 0:b53649cd217f 36 Serial pc(USBTX, USBRX);
daapp 0:b53649cd217f 37 #define SERIAL_BUFFER_SIZE 40
daapp 0:b53649cd217f 38 char serialBuffer[SERIAL_BUFFER_SIZE+1];
daapp 0:b53649cd217f 39 int serialPosition = 0;
daapp 0:b53649cd217f 40
daapp 0:b53649cd217f 41 void invalidCommand() {
daapp 0:b53649cd217f 42 pc.printf("err invalid command %s\n", serialBuffer);
daapp 0:b53649cd217f 43 }
daapp 0:b53649cd217f 44
daapp 0:b53649cd217f 45 void processCommand(void) {
daapp 0:b53649cd217f 46 #ifdef DEBUG
daapp 0:b53649cd217f 47 pc.printf("<%s>\n", serialBuffer);
daapp 0:b53649cd217f 48 #endif
daapp 0:b53649cd217f 49
daapp 0:b53649cd217f 50 if (serialBuffer[0] == '\0') {
daapp 0:b53649cd217f 51 // todo: empty command stop the stage
daapp 0:b53649cd217f 52 } else if (serialBuffer[0] == '$') {
daapp 0:b53649cd217f 53 // '$' - print or change settings
daapp 0:b53649cd217f 54 if (serialBuffer[1] == '\0') {
daapp 0:b53649cd217f 55 pc.printf("todo: show settings\n");
daapp 0:b53649cd217f 56 } else if (serialBuffer[1] >= '0' and serialBuffer[1] <='9' and serialBuffer[2] == '=') {
daapp 0:b53649cd217f 57 pc.printf("todo: set value here\n");
daapp 0:b53649cd217f 58 // todo: save settings to file
daapp 0:b53649cd217f 59 } else {
daapp 0:b53649cd217f 60 invalidCommand();
daapp 0:b53649cd217f 61 }
daapp 0:b53649cd217f 62 } else if (serialBuffer[0] == '?' && serialBuffer[1] == '\0') {
daapp 0:b53649cd217f 63 // todo: print in millimeters
daapp 0:b53649cd217f 64 pc.printf("ok %d\n", position);
daapp 0:b53649cd217f 65 } else {
daapp 0:b53649cd217f 66 // todo: parse G-code here
daapp 0:b53649cd217f 67 char *p = serialBuffer, *endP = serialBuffer;
daapp 0:b53649cd217f 68 uint32_t ulValue;
daapp 0:b53649cd217f 69 double dblValue;
daapp 0:b53649cd217f 70
daapp 0:b53649cd217f 71 bool error = false;
daapp 0:b53649cd217f 72
daapp 0:b53649cd217f 73 bool newAbsMovementMode = absMovementMode;
daapp 0:b53649cd217f 74 double newmmPosition = mmPosition;
daapp 0:b53649cd217f 75 double newFeedRate = feedRate;
daapp 0:b53649cd217f 76
daapp 0:b53649cd217f 77 bool move = false;
daapp 0:b53649cd217f 78
daapp 0:b53649cd217f 79 while (*p != '\0') {
daapp 0:b53649cd217f 80 switch (*p) {
daapp 0:b53649cd217f 81 case 'G':
daapp 0:b53649cd217f 82 p++;
daapp 0:b53649cd217f 83 ulValue = strtoul(p, &endP, 10);
daapp 0:b53649cd217f 84 if (p == endP) {
daapp 0:b53649cd217f 85 pc.printf("err invalid value for command G: %s\n", p);
daapp 0:b53649cd217f 86 error = true;
daapp 0:b53649cd217f 87 } else {
daapp 0:b53649cd217f 88 #ifdef DEBUG
daapp 0:b53649cd217f 89 pc.printf("debug G%u -> %s\n", ulValue, endP);
daapp 0:b53649cd217f 90 #endif
daapp 0:b53649cd217f 91 p = endP;
daapp 0:b53649cd217f 92 switch (ulValue) {
daapp 0:b53649cd217f 93 case 0:
daapp 0:b53649cd217f 94 // todo: implement
daapp 0:b53649cd217f 95 break;
daapp 0:b53649cd217f 96 case 1:
daapp 0:b53649cd217f 97 // todo: implement
daapp 0:b53649cd217f 98 break;
daapp 0:b53649cd217f 99 case 90:
daapp 0:b53649cd217f 100 newAbsMovementMode = true;
daapp 0:b53649cd217f 101 break;
daapp 0:b53649cd217f 102 case 91:
daapp 0:b53649cd217f 103 newAbsMovementMode = false;
daapp 0:b53649cd217f 104 break;
daapp 0:b53649cd217f 105 default:
daapp 0:b53649cd217f 106 pc.printf("err invalid value for command G: %u\n", ulValue);
daapp 0:b53649cd217f 107 error = true;
daapp 0:b53649cd217f 108 break;
daapp 0:b53649cd217f 109 }
daapp 0:b53649cd217f 110 }
daapp 0:b53649cd217f 111 break;
daapp 0:b53649cd217f 112 case 'X':
daapp 0:b53649cd217f 113 p++;
daapp 0:b53649cd217f 114 dblValue = strtod(p, &endP);
daapp 0:b53649cd217f 115 if (p == endP) {
daapp 0:b53649cd217f 116 pc.printf("err invalid value for command X: %f\n", dblValue);
daapp 0:b53649cd217f 117 error = true;
daapp 0:b53649cd217f 118 } else {
daapp 0:b53649cd217f 119 #ifdef DEBUG
daapp 0:b53649cd217f 120 pc.printf("debug X%f -> %s\n", dblValue, endP);
daapp 0:b53649cd217f 121 #endif
daapp 0:b53649cd217f 122 p = endP;
daapp 0:b53649cd217f 123 newmmPosition = dblValue;
daapp 0:b53649cd217f 124
daapp 0:b53649cd217f 125 move = true;
daapp 0:b53649cd217f 126 }
daapp 0:b53649cd217f 127 break;
daapp 0:b53649cd217f 128 case 'F':
daapp 0:b53649cd217f 129 p++;
daapp 0:b53649cd217f 130 dblValue = strtod(p, &endP);
daapp 0:b53649cd217f 131 if (p == endP || dblValue < 0.0) {
daapp 0:b53649cd217f 132 pc.printf("err invalid value for command F: %f\n", dblValue);
daapp 0:b53649cd217f 133 error = true;
daapp 0:b53649cd217f 134 } else {
daapp 0:b53649cd217f 135 #ifdef DEBUG
daapp 0:b53649cd217f 136 pc.printf("debug F%f -> %s\n", dblValue, endP);
daapp 0:b53649cd217f 137 #endif
daapp 0:b53649cd217f 138 p = endP;
daapp 0:b53649cd217f 139 newFeedRate = dblValue;
daapp 0:b53649cd217f 140 }
daapp 0:b53649cd217f 141 break;
daapp 0:b53649cd217f 142 default:
daapp 0:b53649cd217f 143 pc.printf("err invalid command %s\n", p);
daapp 0:b53649cd217f 144 error = true;
daapp 0:b53649cd217f 145 break;
daapp 0:b53649cd217f 146 }
daapp 0:b53649cd217f 147
daapp 0:b53649cd217f 148 if (error) {
daapp 0:b53649cd217f 149 break;
daapp 0:b53649cd217f 150 }
daapp 0:b53649cd217f 151
daapp 0:b53649cd217f 152 }
daapp 0:b53649cd217f 153
daapp 0:b53649cd217f 154 if (!error) {
daapp 0:b53649cd217f 155 // todo: check all flags and execute commands here
daapp 0:b53649cd217f 156 absMovementMode = newAbsMovementMode;
daapp 0:b53649cd217f 157 mmPosition = newmmPosition;
daapp 0:b53649cd217f 158 feedRate = newFeedRate;
daapp 0:b53649cd217f 159 // todo: run line module here
daapp 0:b53649cd217f 160
daapp 0:b53649cd217f 161 pc.printf("absMovementMode = %u\n", absMovementMode);
daapp 0:b53649cd217f 162 pc.printf("mmPosition = %f\n", mmPosition);
daapp 0:b53649cd217f 163 pc.printf("feedRate = %f\n", feedRate);
daapp 0:b53649cd217f 164 #ifdef DEBUG
daapp 0:b53649cd217f 165 if (move) {
daapp 0:b53649cd217f 166 pc.printf("MOVE\n");
daapp 0:b53649cd217f 167 }
daapp 0:b53649cd217f 168 #endif
daapp 0:b53649cd217f 169 }
daapp 0:b53649cd217f 170 }
daapp 0:b53649cd217f 171 }
daapp 0:b53649cd217f 172
daapp 0:b53649cd217f 173
daapp 0:b53649cd217f 174 void readChar(void) {
daapp 0:b53649cd217f 175 int ch;
daapp 0:b53649cd217f 176
daapp 0:b53649cd217f 177 #ifdef DEBUG
daapp 0:b53649cd217f 178 LED4_ON;
daapp 0:b53649cd217f 179 #endif
daapp 0:b53649cd217f 180
daapp 0:b53649cd217f 181 ch = pc.getc();
daapp 0:b53649cd217f 182 if (serialPosition < SERIAL_BUFFER_SIZE) {
daapp 0:b53649cd217f 183
daapp 0:b53649cd217f 184 } else {
daapp 0:b53649cd217f 185 pc.printf("\nToo long string, should be <= %d characters.\n", SERIAL_BUFFER_SIZE);
daapp 0:b53649cd217f 186 serialPosition = 0;
daapp 0:b53649cd217f 187 }
daapp 0:b53649cd217f 188 if (ch == ' ' || ch == '\t') {
daapp 0:b53649cd217f 189 // ignore space characters
daapp 0:b53649cd217f 190 } else {
daapp 0:b53649cd217f 191
daapp 0:b53649cd217f 192 if (ch == '\n') {
daapp 0:b53649cd217f 193 serialBuffer[serialPosition] = '\0';
daapp 0:b53649cd217f 194 processCommand();
daapp 0:b53649cd217f 195 serialPosition = 0;
daapp 0:b53649cd217f 196 serialBuffer[serialPosition] = '\0';
daapp 0:b53649cd217f 197 } else {
daapp 0:b53649cd217f 198 if (ch >= 'a' and ch <= 'z') {
daapp 0:b53649cd217f 199 ch = 'A' + (ch - 'a'); // convert to upper case
daapp 0:b53649cd217f 200 }
daapp 0:b53649cd217f 201 serialBuffer[serialPosition++] = ch;
daapp 0:b53649cd217f 202 }
daapp 0:b53649cd217f 203 }
daapp 0:b53649cd217f 204
daapp 0:b53649cd217f 205 #ifdef DEBUG
daapp 0:b53649cd217f 206 LED4_OFF;
daapp 0:b53649cd217f 207 #endif
daapp 0:b53649cd217f 208 }
daapp 0:b53649cd217f 209
daapp 0:b53649cd217f 210
daapp 0:b53649cd217f 211 FastPWM stepper(p21);
daapp 0:b53649cd217f 212
daapp 0:b53649cd217f 213
daapp 0:b53649cd217f 214 void update_position();
daapp 0:b53649cd217f 215
daapp 0:b53649cd217f 216
daapp 0:b53649cd217f 217 extern "C" void EINT3_IRQHandler (void) __irq {
daapp 0:b53649cd217f 218 if (LPC_GPIOINT->IntStatus & 0x1) {
daapp 0:b53649cd217f 219 if (LPC_GPIOINT->IO0IntStatR & stepIntMask) {
daapp 0:b53649cd217f 220 update_position();
daapp 0:b53649cd217f 221 }
daapp 0:b53649cd217f 222 }
daapp 0:b53649cd217f 223
daapp 0:b53649cd217f 224 LPC_GPIOINT->IO2IntClr = (LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF);
daapp 0:b53649cd217f 225 LPC_GPIOINT->IO0IntClr = (LPC_GPIOINT->IO0IntStatR | LPC_GPIOINT->IO0IntStatF);
daapp 0:b53649cd217f 226
daapp 0:b53649cd217f 227 }
daapp 0:b53649cd217f 228
daapp 0:b53649cd217f 229 void update_position() {
daapp 0:b53649cd217f 230 //position++;
daapp 0:b53649cd217f 231 if (position > 0) {
daapp 0:b53649cd217f 232 position--;
daapp 0:b53649cd217f 233 } else {
daapp 0:b53649cd217f 234 position = 170000;
daapp 0:b53649cd217f 235 }
daapp 0:b53649cd217f 236 }
daapp 0:b53649cd217f 237
daapp 0:b53649cd217f 238
daapp 0:b53649cd217f 239 void event_irq_init(void) {
daapp 0:b53649cd217f 240 p30_AS_INPUT;
daapp 0:b53649cd217f 241 // Enable p30 is P0_4 for rising edge interrupt generation.
daapp 0:b53649cd217f 242 LPC_GPIOINT->IO0IntEnR |= stepIntMask;
daapp 0:b53649cd217f 243 //NVIC_SetPriority(EINT3_IRQn, 1);
daapp 0:b53649cd217f 244 // Enable the interrupt
daapp 0:b53649cd217f 245 NVIC_EnableIRQ(EINT3_IRQn);
daapp 0:b53649cd217f 246 }
daapp 0:b53649cd217f 247
daapp 0:b53649cd217f 248 int main() {
daapp 0:b53649cd217f 249 LED1_USE; // step movement
daapp 0:b53649cd217f 250 LED4_USE; // serial port receive
daapp 0:b53649cd217f 251 position = 0;
daapp 0:b53649cd217f 252
daapp 0:b53649cd217f 253 pc.baud(115200);
daapp 0:b53649cd217f 254 pc.attach(readChar);
daapp 0:b53649cd217f 255
daapp 0:b53649cd217f 256 pc.printf("IGNB module driver version %s. Input '$' for settings.\n", VERSION);
daapp 0:b53649cd217f 257
daapp 0:b53649cd217f 258 // todo: load settings from file
daapp 0:b53649cd217f 259
daapp 0:b53649cd217f 260 //stepper.period(1.0/170000.0);
daapp 0:b53649cd217f 261 //stepper.write(0.50);
daapp 0:b53649cd217f 262
daapp 0:b53649cd217f 263 //event_irq_init();
daapp 0:b53649cd217f 264
daapp 0:b53649cd217f 265 while(1) {
daapp 0:b53649cd217f 266 //position = 0;
daapp 0:b53649cd217f 267
daapp 0:b53649cd217f 268 //LED1_ON;
daapp 0:b53649cd217f 269 //stepper.write(0.5);
daapp 0:b53649cd217f 270 //wait(1);
daapp 0:b53649cd217f 271 //stepper.write(0.0);
daapp 0:b53649cd217f 272 //LED1_OFF;
daapp 0:b53649cd217f 273 //pc.printf("%d\r\n", position);
daapp 0:b53649cd217f 274 //wait(1);
daapp 0:b53649cd217f 275 }
daapp 0:b53649cd217f 276
daapp 0:b53649cd217f 277 }