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

Dependencies:   FastPWM SimpleIOMacros mbed

Committer:
daapp
Date:
Sun Mar 03 19:56:48 2013 +0000
Revision:
2:33a99f65551d
Parent:
1:86997189bb6b
Acceleration begin with incorrect delay.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daapp 2:33a99f65551d 1 /* picocom -b 115200 -c --imap lfcrlf --omap crlf /dev/ttyACM0 */
daapp 2:33a99f65551d 2
daapp 2:33a99f65551d 3
daapp 2:33a99f65551d 4 /*
daapp 2:33a99f65551d 5 todo: when command complete it should print "ok"
daapp 2:33a99f65551d 6 todo: when value of parameter changed print "ok saved"
daapp 2:33a99f65551d 7 todo: when value of parameter is invalid print "err invalid value"
daapp 2:33a99f65551d 8 todo: add G command for set zero here
daapp 2:33a99f65551d 9 */
daapp 2:33a99f65551d 10
daapp 2:33a99f65551d 11 #include "mbed.h"
daapp 2:33a99f65551d 12 #include "FastPWM.h"
daapp 2:33a99f65551d 13 #include "IOMacros.h"
daapp 2:33a99f65551d 14
daapp 2:33a99f65551d 15 #define VERSION "0.1"
daapp 2:33a99f65551d 16
daapp 2:33a99f65551d 17 #define DEBUG
daapp 2:33a99f65551d 18
daapp 2:33a99f65551d 19 #define FILESYSTEM_ROOT "local"
daapp 2:33a99f65551d 20 #define SETTINGS_FILE ("/" FILESYSTEM_ROOT "/settings.txt")
daapp 2:33a99f65551d 21 #define SETTINGS_BACKUP_FILE ("/" FILESYSTEM_ROOT "/settings.bak")
daapp 2:33a99f65551d 22
daapp 2:33a99f65551d 23 LocalFileSystem local(FILESYSTEM_ROOT);
daapp 2:33a99f65551d 24
daapp 2:33a99f65551d 25
daapp 2:33a99f65551d 26 /* p30 - P0_4 */
daapp 2:33a99f65551d 27 // const uint32_t counterPin = 4;
daapp 2:33a99f65551d 28 const uint32_t count_int_mask = p30_SET_MASK;
daapp 2:33a99f65551d 29
daapp 2:33a99f65551d 30 volatile int32_t position;
daapp 2:33a99f65551d 31
daapp 2:33a99f65551d 32 FastPWM stepper(p21);
daapp 2:33a99f65551d 33
daapp 2:33a99f65551d 34 // Dir pin is p22 - P2.4
daapp 2:33a99f65551d 35
daapp 2:33a99f65551d 36
daapp 2:33a99f65551d 37 /* G code interpreter state*/
daapp 2:33a99f65551d 38 bool abs_movement_mode = true;
daapp 2:33a99f65551d 39 double position_mm = 0.0; // mm
daapp 2:33a99f65551d 40 double feed_rate = 1.0; // mm/sec^2
daapp 2:33a99f65551d 41
daapp 2:33a99f65551d 42 /* *** Serial port *** */
daapp 2:33a99f65551d 43 #define INPUT_BUFFER_SIZE 40
daapp 2:33a99f65551d 44
daapp 2:33a99f65551d 45 Serial pc(USBTX, USBRX);
daapp 2:33a99f65551d 46
daapp 2:33a99f65551d 47 char input_buffer[INPUT_BUFFER_SIZE+1];
daapp 2:33a99f65551d 48 int input_position = 0;
daapp 2:33a99f65551d 49
daapp 2:33a99f65551d 50
daapp 2:33a99f65551d 51 /* *** Settings *** */
daapp 2:33a99f65551d 52
daapp 2:33a99f65551d 53 typedef struct {
daapp 2:33a99f65551d 54 double steps_per_mm;
daapp 2:33a99f65551d 55 double acceleration; // mm/sec^2
daapp 2:33a99f65551d 56 double start_speed; // mm/sec^2
daapp 2:33a99f65551d 57 } settings_t;
daapp 2:33a99f65551d 58
daapp 2:33a99f65551d 59 settings_t settings;
daapp 2:33a99f65551d 60
daapp 2:33a99f65551d 61 // return true - if parsed succesfully
daapp 2:33a99f65551d 62 // return false - if error during parsing
daapp 2:33a99f65551d 63 bool parse_settings(FILE *fp, settings_t *settings) {
daapp 2:33a99f65551d 64 // todo: write parser
daapp 2:33a99f65551d 65 return true;
daapp 2:33a99f65551d 66 }
daapp 2:33a99f65551d 67
daapp 2:33a99f65551d 68 void load_settings(char *filename) {
daapp 2:33a99f65551d 69 //FILE *fp;
daapp 2:33a99f65551d 70
daapp 2:33a99f65551d 71 #ifdef DEBUG
daapp 2:33a99f65551d 72 pc.printf("debug load settings from file \"%s\"\n", filename);
daapp 2:33a99f65551d 73 #endif
daapp 2:33a99f65551d 74
daapp 2:33a99f65551d 75 //fp = fopen(filename, "r");
daapp 2:33a99f65551d 76 //if (fp == NULL) {
daapp 2:33a99f65551d 77 settings.steps_per_mm = 12800.0 / 150.0; // 170.666667;
daapp 2:33a99f65551d 78 settings.acceleration = 2000.000; // mm/sec^2
daapp 2:33a99f65551d 79 settings.start_speed = 100.0;
daapp 2:33a99f65551d 80 //} else {
daapp 2:33a99f65551d 81 // parse_settings(fp, &settings);
daapp 2:33a99f65551d 82 // fclose(fp);
daapp 2:33a99f65551d 83 //}
daapp 2:33a99f65551d 84 }
daapp 2:33a99f65551d 85
daapp 2:33a99f65551d 86 void save_settings(char *filename) {
daapp 2:33a99f65551d 87 FILE *fp;
daapp 2:33a99f65551d 88
daapp 2:33a99f65551d 89 fp = fopen(SETTINGS_FILE, "w");
daapp 2:33a99f65551d 90 if (fp != NULL) {
daapp 2:33a99f65551d 91 fprintf(fp, "$0=%f\n", settings.steps_per_mm);
daapp 2:33a99f65551d 92 fprintf(fp, "$1=%f\n", settings.acceleration);
daapp 2:33a99f65551d 93 fprintf(fp, "$2=%f\n", settings.start_speed);
daapp 2:33a99f65551d 94 fclose(fp);
daapp 2:33a99f65551d 95 #ifdef DEBUG
daapp 2:33a99f65551d 96 pc.printf("ok settings saved to %s\n", SETTINGS_FILE);
daapp 2:33a99f65551d 97 #endif
daapp 2:33a99f65551d 98 } else {
daapp 2:33a99f65551d 99 pc.printf("err unable to open %s for writing\n", SETTINGS_FILE);
daapp 2:33a99f65551d 100 }
daapp 2:33a99f65551d 101 }
daapp 2:33a99f65551d 102
daapp 2:33a99f65551d 103 void print_settings() {
daapp 2:33a99f65551d 104 pc.printf("$0=%f (x, steps/mm)\n", settings.steps_per_mm);
daapp 2:33a99f65551d 105 pc.printf("$1=%f (x accel, mm/sec^2)\n", settings.acceleration);
daapp 2:33a99f65551d 106 pc.printf("$2=%f (x start acceleration, mm/sec)\n", settings.start_speed);
daapp 2:33a99f65551d 107 pc.printf("ok\n");
daapp 2:33a99f65551d 108 }
daapp 2:33a99f65551d 109
daapp 2:33a99f65551d 110 // return true if no error
daapp 2:33a99f65551d 111 // return false if error (invalid parameter or value)
daapp 2:33a99f65551d 112 bool set_param(char name, char *value) {
daapp 2:33a99f65551d 113 if (name >= '0' && name <= '2') {
daapp 2:33a99f65551d 114 char *rest = value;
daapp 2:33a99f65551d 115 double dbl_value;
daapp 2:33a99f65551d 116 bool error = false;
daapp 2:33a99f65551d 117
daapp 2:33a99f65551d 118 dbl_value = strtod(value, &rest);
daapp 2:33a99f65551d 119 if (value == rest || *rest != '\0') {
daapp 2:33a99f65551d 120 pc.printf("err invalid value for command $%c: %s\n", name, value);
daapp 2:33a99f65551d 121 error = true;
daapp 2:33a99f65551d 122 } else {
daapp 2:33a99f65551d 123
daapp 2:33a99f65551d 124 #ifdef DEBUG
daapp 2:33a99f65551d 125 pc.printf("debug $%c=%f -> %s\n", name, dbl_value, rest);
daapp 2:33a99f65551d 126 #endif
daapp 2:33a99f65551d 127
daapp 2:33a99f65551d 128 switch (name) {
daapp 2:33a99f65551d 129 case '0':
daapp 2:33a99f65551d 130 if (dbl_value > 0.0) {
daapp 2:33a99f65551d 131 settings.steps_per_mm = dbl_value;
daapp 2:33a99f65551d 132 } else {
daapp 2:33a99f65551d 133 pc.printf("err value should be > 0.0, but %f\n", dbl_value);
daapp 2:33a99f65551d 134 error = true;
daapp 2:33a99f65551d 135 }
daapp 2:33a99f65551d 136 break;
daapp 2:33a99f65551d 137 case '1':
daapp 2:33a99f65551d 138 if (dbl_value > 0.0) {
daapp 2:33a99f65551d 139 settings.acceleration = dbl_value;
daapp 2:33a99f65551d 140 } else {
daapp 2:33a99f65551d 141 pc.printf("err value should be > 0.0, but %f\n", dbl_value);
daapp 2:33a99f65551d 142 error = true;
daapp 2:33a99f65551d 143 }
daapp 2:33a99f65551d 144 break;
daapp 2:33a99f65551d 145 case '2':
daapp 2:33a99f65551d 146 if (dbl_value >= 0.0) {
daapp 2:33a99f65551d 147 settings.start_speed = dbl_value;
daapp 2:33a99f65551d 148 } else {
daapp 2:33a99f65551d 149 pc.printf("err value should be >= 0.0, but %f\n", dbl_value);
daapp 2:33a99f65551d 150 error = true;
daapp 2:33a99f65551d 151 }
daapp 2:33a99f65551d 152 break;
daapp 2:33a99f65551d 153 default:
daapp 2:33a99f65551d 154 pc.printf("err parameter %c unrecognized\n", name);
daapp 2:33a99f65551d 155 error = true;
daapp 2:33a99f65551d 156 break;
daapp 2:33a99f65551d 157 }
daapp 2:33a99f65551d 158 }
daapp 2:33a99f65551d 159 return !error;
daapp 2:33a99f65551d 160 } else {
daapp 2:33a99f65551d 161 pc.printf("err invalid parameter %c\n", name);
daapp 2:33a99f65551d 162 return false;
daapp 2:33a99f65551d 163 }
daapp 2:33a99f65551d 164 }
daapp 2:33a99f65551d 165
daapp 2:33a99f65551d 166
daapp 2:33a99f65551d 167 void invalid_command() {
daapp 2:33a99f65551d 168 pc.printf("err invalid command %s\n", input_buffer);
daapp 2:33a99f65551d 169 }
daapp 2:33a99f65551d 170
daapp 2:33a99f65551d 171 enum MOVE_STATE {
daapp 2:33a99f65551d 172 STOP,
daapp 2:33a99f65551d 173 ACCELERATION,
daapp 2:33a99f65551d 174 MOVE,
daapp 2:33a99f65551d 175 DECELERATION
daapp 2:33a99f65551d 176 };
daapp 2:33a99f65551d 177
daapp 2:33a99f65551d 178 enum MOVE_DIR {
daapp 2:33a99f65551d 179 CW = 1,
daapp 2:33a99f65551d 180 CCW = -1
daapp 2:33a99f65551d 181 };
daapp 2:33a99f65551d 182
daapp 2:33a99f65551d 183 volatile double current_freq, max_freq;
daapp 2:33a99f65551d 184 volatile double delta_freq;
daapp 2:33a99f65551d 185 volatile uint64_t accel_pulses = 0;
daapp 2:33a99f65551d 186 volatile uint32_t accel_pulses_left, decel_pulses_left, move_pulses_left; // pulses left until end of movement
daapp 2:33a99f65551d 187 volatile MOVE_DIR dir;
daapp 2:33a99f65551d 188
daapp 2:33a99f65551d 189 // todo: remove, because useless
daapp 2:33a99f65551d 190 volatile double last_current_freq;
daapp 2:33a99f65551d 191 volatile MOVE_STATE last_move_state;
daapp 2:33a99f65551d 192
daapp 2:33a99f65551d 193 volatile MOVE_STATE move_state = STOP;
daapp 2:33a99f65551d 194
daapp 2:33a99f65551d 195 void move_module(double new_position_mm) {
daapp 2:33a99f65551d 196 uint32_t distance_pulses;
daapp 2:33a99f65551d 197
daapp 2:33a99f65551d 198 LED1_OFF;
daapp 2:33a99f65551d 199 LED2_OFF;
daapp 2:33a99f65551d 200 LED3_OFF;
daapp 2:33a99f65551d 201
daapp 2:33a99f65551d 202 new_position_mm = abs_movement_mode ? new_position_mm : position_mm + new_position_mm;
daapp 2:33a99f65551d 203
daapp 2:33a99f65551d 204 distance_pulses = (uint32_t) ceil(fabs(new_position_mm - position_mm) * settings.steps_per_mm);
daapp 2:33a99f65551d 205
daapp 2:33a99f65551d 206 #ifdef DEBUG
daapp 2:33a99f65551d 207 pc.printf("debug move from %f to %f mm\n", position_mm, new_position_mm);
daapp 2:33a99f65551d 208 pc.printf("debug move from %f to %f pulses\n", position_mm * settings.steps_per_mm, new_position_mm * settings.steps_per_mm);
daapp 2:33a99f65551d 209 #endif
daapp 2:33a99f65551d 210
daapp 2:33a99f65551d 211 if (new_position_mm > position_mm) {
daapp 2:33a99f65551d 212 p22_CLR; // positive dir
daapp 2:33a99f65551d 213 dir = CW;
daapp 2:33a99f65551d 214 } else {
daapp 2:33a99f65551d 215 p22_SET; // negative dir
daapp 2:33a99f65551d 216 dir = CCW;
daapp 2:33a99f65551d 217 }
daapp 2:33a99f65551d 218
daapp 2:33a99f65551d 219 // todo: remove
daapp 2:33a99f65551d 220 //position = 0;
daapp 2:33a99f65551d 221
daapp 2:33a99f65551d 222 double start_freq = settings.start_speed * settings.steps_per_mm ;
daapp 2:33a99f65551d 223
daapp 2:33a99f65551d 224 // = freeRate / 60sec / acc
daapp 2:33a99f65551d 225 double accTime = feed_rate / 60.0 / settings.acceleration;
daapp 2:33a99f65551d 226 // = pulse/mm mm/sec
daapp 2:33a99f65551d 227 max_freq = settings.steps_per_mm * (feed_rate/60.0);
daapp 2:33a99f65551d 228
daapp 2:33a99f65551d 229
daapp 2:33a99f65551d 230 if (max_freq < start_freq) {
daapp 2:33a99f65551d 231 delta_freq = 0.0;
daapp 2:33a99f65551d 232 } else {
daapp 2:33a99f65551d 233 delta_freq = (max_freq - start_freq) / (((start_freq + max_freq) / 2.0) * accTime);
daapp 2:33a99f65551d 234 }
daapp 2:33a99f65551d 235
daapp 2:33a99f65551d 236 accel_pulses = (uint32_t) ceil((max_freq - start_freq) / delta_freq);
daapp 2:33a99f65551d 237
daapp 2:33a99f65551d 238 accel_pulses_left = accel_pulses;
daapp 2:33a99f65551d 239 decel_pulses_left = accel_pulses;
daapp 2:33a99f65551d 240 move_pulses_left = distance_pulses - accel_pulses_left - decel_pulses_left;
daapp 2:33a99f65551d 241
daapp 2:33a99f65551d 242 current_freq = start_freq > 1.0 ? start_freq : 1.0;
daapp 2:33a99f65551d 243
daapp 2:33a99f65551d 244 #ifdef DEBUG
daapp 2:33a99f65551d 245 pc.printf("debug frequency from %f to %f step %f time %f\n", start_freq, max_freq, delta_freq, accTime);
daapp 2:33a99f65551d 246 pc.printf("debug distance_pulses %u\n", distance_pulses);
daapp 2:33a99f65551d 247 pc.printf("debug %u + %u + %u\n", accel_pulses_left, move_pulses_left, decel_pulses_left);
daapp 2:33a99f65551d 248 pc.printf("debug current_freq %f Hz\n", current_freq);
daapp 2:33a99f65551d 249 #endif
daapp 2:33a99f65551d 250
daapp 2:33a99f65551d 251
daapp 2:33a99f65551d 252
daapp 2:33a99f65551d 253 LED1_ON;
daapp 2:33a99f65551d 254
daapp 2:33a99f65551d 255 __disable_irq();
daapp 2:33a99f65551d 256
daapp 2:33a99f65551d 257 move_state = ACCELERATION;
daapp 2:33a99f65551d 258
daapp 2:33a99f65551d 259 stepper.period(1.0/current_freq); //1.0/ (settings.steps_per_mm * 1000));
daapp 2:33a99f65551d 260 stepper.write(0.50);
daapp 2:33a99f65551d 261
daapp 2:33a99f65551d 262 __enable_irq();
daapp 2:33a99f65551d 263
daapp 2:33a99f65551d 264
daapp 2:33a99f65551d 265 //position_mm = newposition_mm;
daapp 2:33a99f65551d 266 }
daapp 2:33a99f65551d 267
daapp 2:33a99f65551d 268
daapp 2:33a99f65551d 269
daapp 2:33a99f65551d 270 void stop_module() {
daapp 2:33a99f65551d 271 if (move_state != STOP) {
daapp 2:33a99f65551d 272 move_state = DECELERATION;
daapp 2:33a99f65551d 273
daapp 2:33a99f65551d 274 #ifdef DEBUG
daapp 2:33a99f65551d 275 pc.printf("position = %d steps\n", position);
daapp 2:33a99f65551d 276 pc.printf("debug STOP: %u %u %u %f\n", accel_pulses_left, move_pulses_left, decel_pulses_left,current_freq);
daapp 2:33a99f65551d 277 pc.printf("debug last_current_freq = %f\tlast_move_state=%d\n", last_current_freq, last_move_state);
daapp 2:33a99f65551d 278 #endif
daapp 2:33a99f65551d 279
daapp 2:33a99f65551d 280 position_mm = position / settings.steps_per_mm;
daapp 2:33a99f65551d 281 pc.printf("ok manual stop position %f mm\n", position_mm);
daapp 2:33a99f65551d 282 }
daapp 2:33a99f65551d 283 }
daapp 2:33a99f65551d 284
daapp 2:33a99f65551d 285 void update_position() {
daapp 2:33a99f65551d 286 // position += dir;
daapp 2:33a99f65551d 287 // __disable_irq();
daapp 2:33a99f65551d 288
daapp 2:33a99f65551d 289 switch (move_state) {
daapp 2:33a99f65551d 290
daapp 2:33a99f65551d 291 case ACCELERATION:
daapp 2:33a99f65551d 292 accel_pulses_left--;
daapp 2:33a99f65551d 293 if (accel_pulses_left > 0) {
daapp 2:33a99f65551d 294 current_freq += delta_freq;
daapp 2:33a99f65551d 295 } else {
daapp 2:33a99f65551d 296 current_freq = max_freq;
daapp 2:33a99f65551d 297 move_state = MOVE;
daapp 2:33a99f65551d 298 LED2_ON;
daapp 2:33a99f65551d 299 }
daapp 2:33a99f65551d 300 stepper.period(1.0/current_freq);
daapp 2:33a99f65551d 301
daapp 2:33a99f65551d 302 break;
daapp 2:33a99f65551d 303
daapp 2:33a99f65551d 304 case MOVE:
daapp 2:33a99f65551d 305 move_pulses_left--;
daapp 2:33a99f65551d 306 if (move_pulses_left > 0) {
daapp 2:33a99f65551d 307
daapp 2:33a99f65551d 308 } else {
daapp 2:33a99f65551d 309 move_state = DECELERATION;
daapp 2:33a99f65551d 310 LED3_ON;
daapp 2:33a99f65551d 311 }
daapp 2:33a99f65551d 312 break;
daapp 2:33a99f65551d 313
daapp 2:33a99f65551d 314 case DECELERATION:
daapp 2:33a99f65551d 315 decel_pulses_left--;
daapp 2:33a99f65551d 316
daapp 2:33a99f65551d 317 if (decel_pulses_left > 0) {
daapp 2:33a99f65551d 318 current_freq -= delta_freq;
daapp 2:33a99f65551d 319 } else {
daapp 2:33a99f65551d 320 move_state = STOP;
daapp 2:33a99f65551d 321 current_freq = 0.0;
daapp 2:33a99f65551d 322 }
daapp 2:33a99f65551d 323
daapp 2:33a99f65551d 324 if (fabs(current_freq) > 0.0001) {
daapp 2:33a99f65551d 325 stepper.period(1.0/current_freq);
daapp 2:33a99f65551d 326 } else {
daapp 2:33a99f65551d 327 stepper.period(0.0);
daapp 2:33a99f65551d 328 }
daapp 2:33a99f65551d 329
daapp 2:33a99f65551d 330 last_current_freq = current_freq;
daapp 2:33a99f65551d 331 last_move_state = move_state;
daapp 2:33a99f65551d 332 break;
daapp 2:33a99f65551d 333
daapp 2:33a99f65551d 334 case STOP:
daapp 2:33a99f65551d 335 stepper.period(0.0);
daapp 2:33a99f65551d 336 stepper.write(0.0);
daapp 2:33a99f65551d 337 p27_SET;
daapp 2:33a99f65551d 338 LED1_OFF;
daapp 2:33a99f65551d 339 LED2_OFF;
daapp 2:33a99f65551d 340 LED3_OFF;
daapp 2:33a99f65551d 341 //pc.printf("ok stop position %f mm\n", position_mm);
daapp 2:33a99f65551d 342 break;
daapp 2:33a99f65551d 343 }
daapp 2:33a99f65551d 344
daapp 2:33a99f65551d 345 // __enable_irq();
daapp 2:33a99f65551d 346 }
daapp 2:33a99f65551d 347
daapp 2:33a99f65551d 348
daapp 2:33a99f65551d 349
daapp 2:33a99f65551d 350 void process_command(void) {
daapp 2:33a99f65551d 351
daapp 2:33a99f65551d 352 #ifdef DEBUG
daapp 2:33a99f65551d 353 pc.printf("debug serial buffer <%s>\n", input_buffer);
daapp 2:33a99f65551d 354 #endif
daapp 2:33a99f65551d 355
daapp 2:33a99f65551d 356 if (input_buffer[0] == '\0') {
daapp 2:33a99f65551d 357 // todo: empty command stop the stage
daapp 2:33a99f65551d 358 stop_module();
daapp 2:33a99f65551d 359 } else if (input_buffer[0] == '$') {
daapp 2:33a99f65551d 360 // '$' - print or change settings
daapp 2:33a99f65551d 361 if (input_buffer[1] == '\0') {
daapp 2:33a99f65551d 362 print_settings();
daapp 2:33a99f65551d 363 } else if (input_buffer[1] >= '0' and input_buffer[1] <='9' and input_buffer[2] == '=') {
daapp 2:33a99f65551d 364 // todo: save settings to file
daapp 2:33a99f65551d 365 if (set_param(input_buffer[1], &input_buffer[3])) {
daapp 2:33a99f65551d 366 save_settings(SETTINGS_FILE);
daapp 2:33a99f65551d 367 }
daapp 2:33a99f65551d 368 } else {
daapp 2:33a99f65551d 369 invalid_command();
daapp 2:33a99f65551d 370 }
daapp 2:33a99f65551d 371 } else if (input_buffer[0] == '?' && input_buffer[1] == '\0') {
daapp 2:33a99f65551d 372 pc.printf("ok %f\n", position_mm);
daapp 2:33a99f65551d 373 } else {
daapp 2:33a99f65551d 374 char *p = input_buffer, *rest = input_buffer;
daapp 2:33a99f65551d 375 uint32_t ul_value;
daapp 2:33a99f65551d 376 double dbl_value;
daapp 2:33a99f65551d 377
daapp 2:33a99f65551d 378 bool error = false;
daapp 2:33a99f65551d 379
daapp 2:33a99f65551d 380 bool newabs_movement_mode = abs_movement_mode;
daapp 2:33a99f65551d 381 double newposition_mm = position_mm;
daapp 2:33a99f65551d 382 double new_feed_rate = feed_rate;
daapp 2:33a99f65551d 383
daapp 2:33a99f65551d 384 bool move = false;
daapp 2:33a99f65551d 385
daapp 2:33a99f65551d 386 while (*p != '\0') {
daapp 2:33a99f65551d 387 switch (*p) {
daapp 2:33a99f65551d 388 case 'G':
daapp 2:33a99f65551d 389 p++;
daapp 2:33a99f65551d 390 ul_value = strtoul(p, &rest, 10);
daapp 2:33a99f65551d 391 if (p == rest) {
daapp 2:33a99f65551d 392 pc.printf("err invalid value for command G: %s\n", p);
daapp 2:33a99f65551d 393 error = true;
daapp 2:33a99f65551d 394 } else {
daapp 2:33a99f65551d 395 #ifdef DEBUG
daapp 2:33a99f65551d 396 pc.printf("debug G%u -> %s\n", ul_value, rest);
daapp 2:33a99f65551d 397 #endif
daapp 2:33a99f65551d 398 p = rest;
daapp 2:33a99f65551d 399 switch (ul_value) {
daapp 2:33a99f65551d 400 case 0:
daapp 2:33a99f65551d 401 // todo: implement
daapp 2:33a99f65551d 402 break;
daapp 2:33a99f65551d 403 case 1:
daapp 2:33a99f65551d 404 // todo: implement
daapp 2:33a99f65551d 405 break;
daapp 2:33a99f65551d 406 case 90:
daapp 2:33a99f65551d 407 newabs_movement_mode = true;
daapp 2:33a99f65551d 408 break;
daapp 2:33a99f65551d 409 case 91:
daapp 2:33a99f65551d 410 newabs_movement_mode = false;
daapp 2:33a99f65551d 411 break;
daapp 2:33a99f65551d 412 default:
daapp 2:33a99f65551d 413 pc.printf("err invalid value for command G: %u\n", ul_value);
daapp 2:33a99f65551d 414 error = true;
daapp 2:33a99f65551d 415 break;
daapp 2:33a99f65551d 416 }
daapp 2:33a99f65551d 417 }
daapp 2:33a99f65551d 418 break;
daapp 2:33a99f65551d 419 case 'X':
daapp 2:33a99f65551d 420 p++;
daapp 2:33a99f65551d 421 dbl_value = strtod(p, &rest);
daapp 2:33a99f65551d 422 if (p == rest) {
daapp 2:33a99f65551d 423 pc.printf("err invalid value for command X: %s\n", p);
daapp 2:33a99f65551d 424 error = true;
daapp 2:33a99f65551d 425 } else {
daapp 2:33a99f65551d 426 #ifdef DEBUG
daapp 2:33a99f65551d 427 pc.printf("debug X%f -> %s\n", dbl_value, rest);
daapp 2:33a99f65551d 428 #endif
daapp 2:33a99f65551d 429 p = rest;
daapp 2:33a99f65551d 430 newposition_mm = dbl_value;
daapp 2:33a99f65551d 431
daapp 2:33a99f65551d 432 move = true;
daapp 2:33a99f65551d 433 }
daapp 2:33a99f65551d 434 break;
daapp 2:33a99f65551d 435 case 'F':
daapp 2:33a99f65551d 436 p++;
daapp 2:33a99f65551d 437 dbl_value = strtod(p, &rest);
daapp 2:33a99f65551d 438 if (p == rest || dbl_value < 0.0) {
daapp 2:33a99f65551d 439 pc.printf("err invalid value for command F: %s\n", p);
daapp 2:33a99f65551d 440 error = true;
daapp 2:33a99f65551d 441 } else {
daapp 2:33a99f65551d 442 #ifdef DEBUG
daapp 2:33a99f65551d 443 pc.printf("debug parse F%f => %s\n", dbl_value, rest);
daapp 2:33a99f65551d 444 #endif
daapp 2:33a99f65551d 445 p = rest;
daapp 2:33a99f65551d 446 new_feed_rate = dbl_value;
daapp 2:33a99f65551d 447 }
daapp 2:33a99f65551d 448 break;
daapp 2:33a99f65551d 449 default:
daapp 2:33a99f65551d 450 pc.printf("err invalid command %s\n", p);
daapp 2:33a99f65551d 451 error = true;
daapp 2:33a99f65551d 452 break;
daapp 2:33a99f65551d 453 }
daapp 2:33a99f65551d 454
daapp 2:33a99f65551d 455 if (error) {
daapp 2:33a99f65551d 456 break;
daapp 2:33a99f65551d 457 }
daapp 2:33a99f65551d 458
daapp 2:33a99f65551d 459 }
daapp 2:33a99f65551d 460
daapp 2:33a99f65551d 461 if (!error) {
daapp 2:33a99f65551d 462 abs_movement_mode = newabs_movement_mode;
daapp 2:33a99f65551d 463 feed_rate = new_feed_rate;
daapp 2:33a99f65551d 464
daapp 2:33a99f65551d 465 if (move) {
daapp 2:33a99f65551d 466 move_module(newposition_mm);
daapp 2:33a99f65551d 467 }
daapp 2:33a99f65551d 468 }
daapp 2:33a99f65551d 469 }
daapp 2:33a99f65551d 470 }
daapp 2:33a99f65551d 471
daapp 2:33a99f65551d 472
daapp 2:33a99f65551d 473 void read_char(void) {
daapp 2:33a99f65551d 474 int ch;
daapp 2:33a99f65551d 475
daapp 2:33a99f65551d 476 #ifdef DEBUG
daapp 2:33a99f65551d 477 LED4_ON;
daapp 2:33a99f65551d 478 #endif
daapp 2:33a99f65551d 479
daapp 2:33a99f65551d 480 ch = pc.getc();
daapp 2:33a99f65551d 481 if (input_position < INPUT_BUFFER_SIZE) {
daapp 2:33a99f65551d 482
daapp 2:33a99f65551d 483 } else {
daapp 2:33a99f65551d 484 pc.printf("\nToo long string, should be <= %d characters.\n", INPUT_BUFFER_SIZE);
daapp 2:33a99f65551d 485 input_position = 0;
daapp 2:33a99f65551d 486 }
daapp 2:33a99f65551d 487
daapp 2:33a99f65551d 488 if (ch == ' ' || ch == '\t') {
daapp 2:33a99f65551d 489 // ignore space characters
daapp 2:33a99f65551d 490 } else {
daapp 2:33a99f65551d 491
daapp 2:33a99f65551d 492 if (ch == '\n') {
daapp 2:33a99f65551d 493 input_buffer[input_position] = '\0';
daapp 2:33a99f65551d 494 process_command();
daapp 2:33a99f65551d 495 input_position = 0;
daapp 2:33a99f65551d 496 input_buffer[input_position] = '\0';
daapp 2:33a99f65551d 497 } else {
daapp 2:33a99f65551d 498 if (ch >= 'a' and ch <= 'z') {
daapp 2:33a99f65551d 499 ch = 'A' + (ch - 'a'); // convert to upper case
daapp 2:33a99f65551d 500 }
daapp 2:33a99f65551d 501 input_buffer[input_position++] = ch;
daapp 2:33a99f65551d 502 }
daapp 2:33a99f65551d 503 }
daapp 2:33a99f65551d 504
daapp 2:33a99f65551d 505 #ifdef DEBUG
daapp 2:33a99f65551d 506 LED4_OFF;
daapp 2:33a99f65551d 507 #endif
daapp 2:33a99f65551d 508 }
daapp 2:33a99f65551d 509
daapp 2:33a99f65551d 510
daapp 2:33a99f65551d 511 extern "C" void EINT3_IRQHandler (void) __irq {
daapp 2:33a99f65551d 512 if (LPC_GPIOINT->IntStatus & 0x1) {
daapp 2:33a99f65551d 513 if (LPC_GPIOINT->IO0IntStatF & count_int_mask) {
daapp 2:33a99f65551d 514 update_position();
daapp 2:33a99f65551d 515 }
daapp 2:33a99f65551d 516 }
daapp 2:33a99f65551d 517
daapp 2:33a99f65551d 518 LPC_GPIOINT->IO2IntClr = (LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF);
daapp 2:33a99f65551d 519 LPC_GPIOINT->IO0IntClr = (LPC_GPIOINT->IO0IntStatR | LPC_GPIOINT->IO0IntStatF);
daapp 2:33a99f65551d 520
daapp 2:33a99f65551d 521 }
daapp 2:33a99f65551d 522
daapp 2:33a99f65551d 523 void event_irq_init(void) {
daapp 2:33a99f65551d 524 p30_AS_INPUT;
daapp 2:33a99f65551d 525 // p30_MODE(PIN_REPEAT);
daapp 2:33a99f65551d 526 // Enable p30 is P0_4 for rising edge interrupt generation.
daapp 2:33a99f65551d 527 LPC_GPIOINT->IO0IntEnF |= count_int_mask;
daapp 2:33a99f65551d 528 NVIC_SetPriority(EINT3_IRQn, 1);
daapp 2:33a99f65551d 529 // Enable the interrupt
daapp 2:33a99f65551d 530 NVIC_EnableIRQ(EINT3_IRQn);
daapp 2:33a99f65551d 531 }
daapp 2:33a99f65551d 532
daapp 2:33a99f65551d 533
daapp 2:33a99f65551d 534
daapp 2:33a99f65551d 535 int main() {
daapp 2:33a99f65551d 536 LED1_USE; // acceleration
daapp 2:33a99f65551d 537 LED2_USE; // move
daapp 2:33a99f65551d 538 LED3_USE; // deceleration
daapp 2:33a99f65551d 539 LED4_USE; // serial port receive
daapp 2:33a99f65551d 540
daapp 2:33a99f65551d 541 p22_AS_OUTPUT; // dir pin
daapp 2:33a99f65551d 542
daapp 2:33a99f65551d 543 p27_AS_OUTPUT;
daapp 2:33a99f65551d 544
daapp 2:33a99f65551d 545 position = 0;
daapp 2:33a99f65551d 546
daapp 2:33a99f65551d 547 pc.baud(115200);
daapp 2:33a99f65551d 548 pc.attach(read_char);
daapp 2:33a99f65551d 549
daapp 2:33a99f65551d 550 pc.printf("IGNB-SM %s ['$' for help]\n", VERSION);
daapp 2:33a99f65551d 551
daapp 2:33a99f65551d 552 load_settings(SETTINGS_FILE);
daapp 2:33a99f65551d 553
daapp 2:33a99f65551d 554 event_irq_init();
daapp 2:33a99f65551d 555
daapp 2:33a99f65551d 556 while(1) {}
daapp 2:33a99f65551d 557 }