Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FastPWM SimpleIOMacros mbed
Revision 2:33a99f65551d, committed 2013-03-03
- Comitter:
- daapp
- Date:
- Sun Mar 03 19:56:48 2013 +0000
- Parent:
- 1:86997189bb6b
- Commit message:
- Acceleration begin with incorrect delay.
Changed in this revision
| main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 86997189bb6b -r 33a99f65551d main.cpp
--- a/main.cpp Thu Feb 28 11:40:50 2013 +0000
+++ b/main.cpp Sun Mar 03 19:56:48 2013 +0000
@@ -1,443 +1,557 @@
-/* picocom -b 115200 -c --imap lfcrlf --omap crlf /dev/ttyACM0 */
-
-
-/*
- todo: attach callback to Serial when no command executed only with STOP command
- todo: when command complete it should print "ok"
- todo: when all settings printed print "ok"
- todo: when value of parameter changed print "ok saved"
- todo: when value of parameter is invalid print "err invalid value"
- todo: add G command for set zero here
-*/
-
-#include "mbed.h"
-#include "FastPWM.h"
-#include "IOMacros.h"
-
-#define VERSION "0.1"
-
-#define DEBUG
-
-#define FILESYSTEM_ROOT "local"
-#define SETTINGS_FILE ("/" FILESYSTEM_ROOT "/settings.txt")
-#define SETTINGS_BACKUP_FILE ("/" FILESYSTEM_ROOT "/settings.bak")
-
-LocalFileSystem local(FILESYSTEM_ROOT);
-
-
-/* p30 - P0_4 */
-// const uint32_t counterPin = 4;
-const uint32_t counterIntMask = p30_SET_MASK;
-
-volatile int32_t position;
-
-FastPWM stepper(p21);
-
-// Dir pin is p22 - P2.4
-
-
-/* G code interpreter state*/
-bool absMovementMode = true;
-double mmPosition = 0.0; // mm
-double feedRate = 1.0; // mm/sec^2
-
-/* *** Serial port *** */
-Serial pc(USBTX, USBRX);
-#define SERIAL_BUFFER_SIZE 40
-char serialBuffer[SERIAL_BUFFER_SIZE+1];
-int serialPosition = 0;
-
-
-/* *** Settings *** */
-
-typedef struct {
- double steps_per_mm;
- double acceleration; // mm/sec^2
- double start_acceleration; // mm/sec^2
-} settings_t;
-
-settings_t settings;
-
-// return true - if parsed succesfully
-// return false - if error during parsing
-bool parse_settings(FILE *fp, settings_t *settings) {
- // todo: write parser
- return true;
-}
-
-void load_settings(char *filename) {
- FILE *fp;
-
-#ifdef DEBUG
- pc.printf("debug load settings from file \"%s\"\n", filename);
-#endif
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
- settings.steps_per_mm = 25600.0 / 150.0; // 170.666667;
- settings.acceleration = 1000.000;
- settings.start_acceleration = 0.0;
- } else {
- parse_settings(fp, &settings);
- fclose(fp);
- }
-}
-
-void save_settings(char *filename) {
- FILE *fp;
-
- fp = fopen(SETTINGS_FILE, "w");
- if (fp != NULL) {
- fprintf(fp, "$0=%f\n", settings.steps_per_mm);
- fprintf(fp, "$1=%f\n", settings.acceleration);
- fprintf(fp, "$2=%f\n", settings.start_acceleration);
- fclose(fp);
-#ifdef DEBUG
- pc.printf("ok settings saved to %s\n", SETTINGS_FILE);
-#endif
- } else {
- pc.printf("err unable to open %s for writing\n", SETTINGS_FILE);
- }
-}
-
-void print_settings() {
- pc.printf("$0=%f (x, steps/mm)\n", settings.steps_per_mm);
- pc.printf("$1=%f (x accel, mm/sec^2)\n", settings.acceleration);
- pc.printf("$2=%f (x start acceleration, mm/sec^2)\n", settings.start_acceleration);
- pc.printf("ok\n");
-}
-
-// return true if no error
-// return false if error (invalid parameter or value)
-bool set_param(char name, char *value) {
- if (name >= '0' && name <= '2') {
- char *endP = value;
- double dblValue;
- bool error = false;
-
- dblValue = strtod(value, &endP);
- if (value == endP || *endP != '\0') {
- pc.printf("err invalid value for command $%c: %s\n", name, value);
- error = true;
- } else {
-
-#ifdef DEBUG
- pc.printf("debug $%c=%f -> %s\n", name, dblValue, endP);
-#endif
-
- switch (name) {
- case '0':
- if (dblValue > 0.0) {
- settings.steps_per_mm = dblValue;
- } else {
- pc.printf("err value should be > 0.0, but %f\n", dblValue);
- error = true;
- }
- break;
- case '1':
- if (dblValue > 0.0) {
- settings.acceleration = dblValue;
- } else {
- pc.printf("err value should be > 0.0, but %f\n", dblValue);
- error = true;
- }
- break;
- case '2':
- if (dblValue >= 0.0) {
- settings.start_acceleration = dblValue;
- } else {
- pc.printf("err value should be >= 0.0, but %f\n", dblValue);
- error = true;
- }
- break;
- default:
- pc.printf("err parameter %c unrecognized\n", name);
- error = true;
- break;
- }
- }
- return !error;
- } else {
- pc.printf("err invalid parameter %c\n", name);
- return false;
- }
-}
-
-
-void invalidCommand() {
- pc.printf("err invalid command %s\n", serialBuffer);
-}
-
-void moveModule(double position) {
- double newmmPosition;
- newmmPosition = absMovementMode ? position : mmPosition + position;
-
-#ifdef DEBUG
- pc.printf("debug move from %f to %f\n", mmPosition, newmmPosition);
- pc.printf("debug move from %f to %f\n", mmPosition * settings.steps_per_mm, newmmPosition * settings.steps_per_mm);
-#endif
-
- if (newmmPosition > mmPosition) {
- p22_CLR;
- } else {
- p22_SET;
- }
-
- // todo: remove
- position = 0;
-
- stepper.period(1.0/170000.0);
- stepper.write(0.50);
-
- mmPosition = newmmPosition;
-}
-
-void stopModule() {
- stepper.write(0);
-
-#ifdef DEBUG
- pc.printf("position = %d steps\n", position);
-#endif
-
- mmPosition = position / settings.steps_per_mm;
- pc.printf("ok stop position %f mm\n", mmPosition);
-}
-
-void processCommand(void) {
-#ifdef DEBUG
- pc.printf("debug serial buffer <%s>\n", serialBuffer);
-#endif
-
- if (serialBuffer[0] == '\0') {
- // todo: empty command stop the stage
- stopModule();
- } else if (serialBuffer[0] == '$') {
- // '$' - print or change settings
- if (serialBuffer[1] == '\0') {
- print_settings();
- } else if (serialBuffer[1] >= '0' and serialBuffer[1] <='9' and serialBuffer[2] == '=') {
- // todo: save settings to file
- if (set_param(serialBuffer[1], &serialBuffer[3])) {
- save_settings(SETTINGS_FILE);
- }
- } else {
- invalidCommand();
- }
- } else if (serialBuffer[0] == '?' && serialBuffer[1] == '\0') {
- // todo: print in millimeters
- pc.printf("ok %f\n", mmPosition);
- } else {
- // todo: parse G-code here
- char *p = serialBuffer, *endP = serialBuffer;
- uint32_t ulValue;
- double dblValue;
-
- bool error = false;
-
- bool newAbsMovementMode = absMovementMode;
- double newmmPosition = mmPosition;
- double newFeedRate = feedRate;
-
- bool move = false;
-
- while (*p != '\0') {
- switch (*p) {
- case 'G':
- p++;
- ulValue = strtoul(p, &endP, 10);
- if (p == endP) {
- pc.printf("err invalid value for command G: %s\n", p);
- error = true;
- } else {
-#ifdef DEBUG
- pc.printf("debug G%u -> %s\n", ulValue, endP);
-#endif
- p = endP;
- switch (ulValue) {
- case 0:
- // todo: implement
- break;
- case 1:
- // todo: implement
- break;
- case 90:
- newAbsMovementMode = true;
- break;
- case 91:
- newAbsMovementMode = false;
- break;
- default:
- pc.printf("err invalid value for command G: %u\n", ulValue);
- error = true;
- break;
- }
- }
- break;
- case 'X':
- p++;
- dblValue = strtod(p, &endP);
- if (p == endP) {
- pc.printf("err invalid value for command X: %s\n", p);
- error = true;
- } else {
-#ifdef DEBUG
- pc.printf("debug X%f -> %s\n", dblValue, endP);
-#endif
- p = endP;
- newmmPosition = dblValue;
-
- move = true;
- }
- break;
- case 'F':
- p++;
- dblValue = strtod(p, &endP);
- if (p == endP || dblValue < 0.0) {
- pc.printf("err invalid value for command F: %s\n", p);
- error = true;
- } else {
-#ifdef DEBUG
- pc.printf("debug parse F%f => rest %s\n", dblValue, endP);
-#endif
- p = endP;
- newFeedRate = dblValue;
- }
- break;
- default:
- pc.printf("err invalid command %s\n", p);
- error = true;
- break;
- }
-
- if (error) {
- break;
- }
-
- }
-
- if (!error) {
- // todo: check all flags and execute commands here
- absMovementMode = newAbsMovementMode;
- //mmPosition = newmmPosition;
- feedRate = newFeedRate;
- // todo: run line module here
-
- pc.printf("absMovementMode = %u\n", absMovementMode);
- pc.printf("mmPosition = %f\n", mmPosition);
- pc.printf("feedRate = %f\n", feedRate);
-
- if (move) {
- moveModule(newmmPosition);
- }
- }
- }
-}
-
-
-void readChar(void) {
- int ch;
-
-#ifdef DEBUG
- LED4_ON;
-#endif
-
- ch = pc.getc();
- if (serialPosition < SERIAL_BUFFER_SIZE) {
-
- } else {
- pc.printf("\nToo long string, should be <= %d characters.\n", SERIAL_BUFFER_SIZE);
- serialPosition = 0;
- }
- if (ch == ' ' || ch == '\t') {
- // ignore space characters
- } else {
-
- if (ch == '\n') {
- serialBuffer[serialPosition] = '\0';
- processCommand();
- serialPosition = 0;
- serialBuffer[serialPosition] = '\0';
- } else {
- if (ch >= 'a' and ch <= 'z') {
- ch = 'A' + (ch - 'a'); // convert to upper case
- }
- serialBuffer[serialPosition++] = ch;
- }
- }
-
-#ifdef DEBUG
- LED4_OFF;
-#endif
-}
-
-
-
-void update_position();
-
-
-extern "C" void EINT3_IRQHandler (void) __irq {
- if (LPC_GPIOINT->IntStatus & 0x1) {
- if (LPC_GPIOINT->IO0IntStatF & counterIntMask) {
- update_position();
- }
- }
-
- LPC_GPIOINT->IO2IntClr = (LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF);
- LPC_GPIOINT->IO0IntClr = (LPC_GPIOINT->IO0IntStatR | LPC_GPIOINT->IO0IntStatF);
-
-}
-
-void update_position() {
- position++;
- /*
- if (position > 0) {
- position--;
- } else {
- position = 170000;
- }*/
-}
-
-
-void event_irq_init(void) {
- p30_AS_INPUT;
- // Enable p30 is P0_4 for rising edge interrupt generation.
- LPC_GPIOINT->IO0IntEnF |= counterIntMask;
- //NVIC_SetPriority(EINT3_IRQn, 1);
- // Enable the interrupt
- NVIC_EnableIRQ(EINT3_IRQn);
-}
-
-
-
-int main() {
- LED1_USE; // step movement
- LED4_USE; // serial port receive
-
- p22_AS_OUTPUT;
-
- position = 0;
-
- pc.baud(115200);
- pc.attach(readChar);
-
- pc.printf("IGNB-SM %s ['$' for help]\n", VERSION);
-
- load_settings(SETTINGS_FILE);
-
- //stepper.period(1.0/170000.0);
- //stepper.write(0.50);
-
- event_irq_init();
-
- while(1) {
- //position = 0;
-
- //LED1_ON;
- //stepper.write(0.5);
- //wait(1);
- //stepper.write(0.0);
- //LED1_OFF;
- //pc.printf("%d\r\n", position);
- //wait(1);
- }
-}
+/* picocom -b 115200 -c --imap lfcrlf --omap crlf /dev/ttyACM0 */
+
+
+/*
+ todo: when command complete it should print "ok"
+ todo: when value of parameter changed print "ok saved"
+ todo: when value of parameter is invalid print "err invalid value"
+ todo: add G command for set zero here
+*/
+
+#include "mbed.h"
+#include "FastPWM.h"
+#include "IOMacros.h"
+
+#define VERSION "0.1"
+
+#define DEBUG
+
+#define FILESYSTEM_ROOT "local"
+#define SETTINGS_FILE ("/" FILESYSTEM_ROOT "/settings.txt")
+#define SETTINGS_BACKUP_FILE ("/" FILESYSTEM_ROOT "/settings.bak")
+
+LocalFileSystem local(FILESYSTEM_ROOT);
+
+
+/* p30 - P0_4 */
+// const uint32_t counterPin = 4;
+const uint32_t count_int_mask = p30_SET_MASK;
+
+volatile int32_t position;
+
+FastPWM stepper(p21);
+
+// Dir pin is p22 - P2.4
+
+
+/* G code interpreter state*/
+bool abs_movement_mode = true;
+double position_mm = 0.0; // mm
+double feed_rate = 1.0; // mm/sec^2
+
+/* *** Serial port *** */
+#define INPUT_BUFFER_SIZE 40
+
+Serial pc(USBTX, USBRX);
+
+char input_buffer[INPUT_BUFFER_SIZE+1];
+int input_position = 0;
+
+
+/* *** Settings *** */
+
+typedef struct {
+ double steps_per_mm;
+ double acceleration; // mm/sec^2
+ double start_speed; // mm/sec^2
+} settings_t;
+
+settings_t settings;
+
+// return true - if parsed succesfully
+// return false - if error during parsing
+bool parse_settings(FILE *fp, settings_t *settings) {
+ // todo: write parser
+ return true;
+}
+
+void load_settings(char *filename) {
+ //FILE *fp;
+
+#ifdef DEBUG
+ pc.printf("debug load settings from file \"%s\"\n", filename);
+#endif
+
+ //fp = fopen(filename, "r");
+ //if (fp == NULL) {
+ settings.steps_per_mm = 12800.0 / 150.0; // 170.666667;
+ settings.acceleration = 2000.000; // mm/sec^2
+ settings.start_speed = 100.0;
+ //} else {
+ // parse_settings(fp, &settings);
+ // fclose(fp);
+ //}
+}
+
+void save_settings(char *filename) {
+ FILE *fp;
+
+ fp = fopen(SETTINGS_FILE, "w");
+ if (fp != NULL) {
+ fprintf(fp, "$0=%f\n", settings.steps_per_mm);
+ fprintf(fp, "$1=%f\n", settings.acceleration);
+ fprintf(fp, "$2=%f\n", settings.start_speed);
+ fclose(fp);
+#ifdef DEBUG
+ pc.printf("ok settings saved to %s\n", SETTINGS_FILE);
+#endif
+ } else {
+ pc.printf("err unable to open %s for writing\n", SETTINGS_FILE);
+ }
+}
+
+void print_settings() {
+ pc.printf("$0=%f (x, steps/mm)\n", settings.steps_per_mm);
+ pc.printf("$1=%f (x accel, mm/sec^2)\n", settings.acceleration);
+ pc.printf("$2=%f (x start acceleration, mm/sec)\n", settings.start_speed);
+ pc.printf("ok\n");
+}
+
+// return true if no error
+// return false if error (invalid parameter or value)
+bool set_param(char name, char *value) {
+ if (name >= '0' && name <= '2') {
+ char *rest = value;
+ double dbl_value;
+ bool error = false;
+
+ dbl_value = strtod(value, &rest);
+ if (value == rest || *rest != '\0') {
+ pc.printf("err invalid value for command $%c: %s\n", name, value);
+ error = true;
+ } else {
+
+#ifdef DEBUG
+ pc.printf("debug $%c=%f -> %s\n", name, dbl_value, rest);
+#endif
+
+ switch (name) {
+ case '0':
+ if (dbl_value > 0.0) {
+ settings.steps_per_mm = dbl_value;
+ } else {
+ pc.printf("err value should be > 0.0, but %f\n", dbl_value);
+ error = true;
+ }
+ break;
+ case '1':
+ if (dbl_value > 0.0) {
+ settings.acceleration = dbl_value;
+ } else {
+ pc.printf("err value should be > 0.0, but %f\n", dbl_value);
+ error = true;
+ }
+ break;
+ case '2':
+ if (dbl_value >= 0.0) {
+ settings.start_speed = dbl_value;
+ } else {
+ pc.printf("err value should be >= 0.0, but %f\n", dbl_value);
+ error = true;
+ }
+ break;
+ default:
+ pc.printf("err parameter %c unrecognized\n", name);
+ error = true;
+ break;
+ }
+ }
+ return !error;
+ } else {
+ pc.printf("err invalid parameter %c\n", name);
+ return false;
+ }
+}
+
+
+void invalid_command() {
+ pc.printf("err invalid command %s\n", input_buffer);
+}
+
+enum MOVE_STATE {
+ STOP,
+ ACCELERATION,
+ MOVE,
+ DECELERATION
+};
+
+enum MOVE_DIR {
+ CW = 1,
+ CCW = -1
+};
+
+volatile double current_freq, max_freq;
+volatile double delta_freq;
+volatile uint64_t accel_pulses = 0;
+volatile uint32_t accel_pulses_left, decel_pulses_left, move_pulses_left; // pulses left until end of movement
+volatile MOVE_DIR dir;
+
+// todo: remove, because useless
+volatile double last_current_freq;
+volatile MOVE_STATE last_move_state;
+
+volatile MOVE_STATE move_state = STOP;
+
+void move_module(double new_position_mm) {
+ uint32_t distance_pulses;
+
+ LED1_OFF;
+ LED2_OFF;
+ LED3_OFF;
+
+ new_position_mm = abs_movement_mode ? new_position_mm : position_mm + new_position_mm;
+
+ distance_pulses = (uint32_t) ceil(fabs(new_position_mm - position_mm) * settings.steps_per_mm);
+
+#ifdef DEBUG
+ pc.printf("debug move from %f to %f mm\n", position_mm, new_position_mm);
+ pc.printf("debug move from %f to %f pulses\n", position_mm * settings.steps_per_mm, new_position_mm * settings.steps_per_mm);
+#endif
+
+ if (new_position_mm > position_mm) {
+ p22_CLR; // positive dir
+ dir = CW;
+ } else {
+ p22_SET; // negative dir
+ dir = CCW;
+ }
+
+ // todo: remove
+ //position = 0;
+
+ double start_freq = settings.start_speed * settings.steps_per_mm ;
+
+ // = freeRate / 60sec / acc
+ double accTime = feed_rate / 60.0 / settings.acceleration;
+ // = pulse/mm mm/sec
+ max_freq = settings.steps_per_mm * (feed_rate/60.0);
+
+
+ if (max_freq < start_freq) {
+ delta_freq = 0.0;
+ } else {
+ delta_freq = (max_freq - start_freq) / (((start_freq + max_freq) / 2.0) * accTime);
+ }
+
+ accel_pulses = (uint32_t) ceil((max_freq - start_freq) / delta_freq);
+
+ accel_pulses_left = accel_pulses;
+ decel_pulses_left = accel_pulses;
+ move_pulses_left = distance_pulses - accel_pulses_left - decel_pulses_left;
+
+ current_freq = start_freq > 1.0 ? start_freq : 1.0;
+
+#ifdef DEBUG
+ pc.printf("debug frequency from %f to %f step %f time %f\n", start_freq, max_freq, delta_freq, accTime);
+ pc.printf("debug distance_pulses %u\n", distance_pulses);
+ pc.printf("debug %u + %u + %u\n", accel_pulses_left, move_pulses_left, decel_pulses_left);
+ pc.printf("debug current_freq %f Hz\n", current_freq);
+#endif
+
+
+
+ LED1_ON;
+
+ __disable_irq();
+
+ move_state = ACCELERATION;
+
+ stepper.period(1.0/current_freq); //1.0/ (settings.steps_per_mm * 1000));
+ stepper.write(0.50);
+
+ __enable_irq();
+
+
+ //position_mm = newposition_mm;
+}
+
+
+
+void stop_module() {
+ if (move_state != STOP) {
+ move_state = DECELERATION;
+
+#ifdef DEBUG
+ pc.printf("position = %d steps\n", position);
+ pc.printf("debug STOP: %u %u %u %f\n", accel_pulses_left, move_pulses_left, decel_pulses_left,current_freq);
+ pc.printf("debug last_current_freq = %f\tlast_move_state=%d\n", last_current_freq, last_move_state);
+#endif
+
+ position_mm = position / settings.steps_per_mm;
+ pc.printf("ok manual stop position %f mm\n", position_mm);
+ }
+}
+
+void update_position() {
+ // position += dir;
+// __disable_irq();
+
+ switch (move_state) {
+
+ case ACCELERATION:
+ accel_pulses_left--;
+ if (accel_pulses_left > 0) {
+ current_freq += delta_freq;
+ } else {
+ current_freq = max_freq;
+ move_state = MOVE;
+ LED2_ON;
+ }
+ stepper.period(1.0/current_freq);
+
+ break;
+
+ case MOVE:
+ move_pulses_left--;
+ if (move_pulses_left > 0) {
+
+ } else {
+ move_state = DECELERATION;
+ LED3_ON;
+ }
+ break;
+
+ case DECELERATION:
+ decel_pulses_left--;
+
+ if (decel_pulses_left > 0) {
+ current_freq -= delta_freq;
+ } else {
+ move_state = STOP;
+ current_freq = 0.0;
+ }
+
+ if (fabs(current_freq) > 0.0001) {
+ stepper.period(1.0/current_freq);
+ } else {
+ stepper.period(0.0);
+ }
+
+ last_current_freq = current_freq;
+ last_move_state = move_state;
+ break;
+
+ case STOP:
+ stepper.period(0.0);
+ stepper.write(0.0);
+ p27_SET;
+ LED1_OFF;
+ LED2_OFF;
+ LED3_OFF;
+ //pc.printf("ok stop position %f mm\n", position_mm);
+ break;
+ }
+
+// __enable_irq();
+}
+
+
+
+void process_command(void) {
+
+#ifdef DEBUG
+ pc.printf("debug serial buffer <%s>\n", input_buffer);
+#endif
+
+ if (input_buffer[0] == '\0') {
+ // todo: empty command stop the stage
+ stop_module();
+ } else if (input_buffer[0] == '$') {
+ // '$' - print or change settings
+ if (input_buffer[1] == '\0') {
+ print_settings();
+ } else if (input_buffer[1] >= '0' and input_buffer[1] <='9' and input_buffer[2] == '=') {
+ // todo: save settings to file
+ if (set_param(input_buffer[1], &input_buffer[3])) {
+ save_settings(SETTINGS_FILE);
+ }
+ } else {
+ invalid_command();
+ }
+ } else if (input_buffer[0] == '?' && input_buffer[1] == '\0') {
+ pc.printf("ok %f\n", position_mm);
+ } else {
+ char *p = input_buffer, *rest = input_buffer;
+ uint32_t ul_value;
+ double dbl_value;
+
+ bool error = false;
+
+ bool newabs_movement_mode = abs_movement_mode;
+ double newposition_mm = position_mm;
+ double new_feed_rate = feed_rate;
+
+ bool move = false;
+
+ while (*p != '\0') {
+ switch (*p) {
+ case 'G':
+ p++;
+ ul_value = strtoul(p, &rest, 10);
+ if (p == rest) {
+ pc.printf("err invalid value for command G: %s\n", p);
+ error = true;
+ } else {
+#ifdef DEBUG
+ pc.printf("debug G%u -> %s\n", ul_value, rest);
+#endif
+ p = rest;
+ switch (ul_value) {
+ case 0:
+ // todo: implement
+ break;
+ case 1:
+ // todo: implement
+ break;
+ case 90:
+ newabs_movement_mode = true;
+ break;
+ case 91:
+ newabs_movement_mode = false;
+ break;
+ default:
+ pc.printf("err invalid value for command G: %u\n", ul_value);
+ error = true;
+ break;
+ }
+ }
+ break;
+ case 'X':
+ p++;
+ dbl_value = strtod(p, &rest);
+ if (p == rest) {
+ pc.printf("err invalid value for command X: %s\n", p);
+ error = true;
+ } else {
+#ifdef DEBUG
+ pc.printf("debug X%f -> %s\n", dbl_value, rest);
+#endif
+ p = rest;
+ newposition_mm = dbl_value;
+
+ move = true;
+ }
+ break;
+ case 'F':
+ p++;
+ dbl_value = strtod(p, &rest);
+ if (p == rest || dbl_value < 0.0) {
+ pc.printf("err invalid value for command F: %s\n", p);
+ error = true;
+ } else {
+#ifdef DEBUG
+ pc.printf("debug parse F%f => %s\n", dbl_value, rest);
+#endif
+ p = rest;
+ new_feed_rate = dbl_value;
+ }
+ break;
+ default:
+ pc.printf("err invalid command %s\n", p);
+ error = true;
+ break;
+ }
+
+ if (error) {
+ break;
+ }
+
+ }
+
+ if (!error) {
+ abs_movement_mode = newabs_movement_mode;
+ feed_rate = new_feed_rate;
+
+ if (move) {
+ move_module(newposition_mm);
+ }
+ }
+ }
+}
+
+
+void read_char(void) {
+ int ch;
+
+#ifdef DEBUG
+ LED4_ON;
+#endif
+
+ ch = pc.getc();
+ if (input_position < INPUT_BUFFER_SIZE) {
+
+ } else {
+ pc.printf("\nToo long string, should be <= %d characters.\n", INPUT_BUFFER_SIZE);
+ input_position = 0;
+ }
+
+ if (ch == ' ' || ch == '\t') {
+ // ignore space characters
+ } else {
+
+ if (ch == '\n') {
+ input_buffer[input_position] = '\0';
+ process_command();
+ input_position = 0;
+ input_buffer[input_position] = '\0';
+ } else {
+ if (ch >= 'a' and ch <= 'z') {
+ ch = 'A' + (ch - 'a'); // convert to upper case
+ }
+ input_buffer[input_position++] = ch;
+ }
+ }
+
+#ifdef DEBUG
+ LED4_OFF;
+#endif
+}
+
+
+extern "C" void EINT3_IRQHandler (void) __irq {
+ if (LPC_GPIOINT->IntStatus & 0x1) {
+ if (LPC_GPIOINT->IO0IntStatF & count_int_mask) {
+ update_position();
+ }
+ }
+
+ LPC_GPIOINT->IO2IntClr = (LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF);
+ LPC_GPIOINT->IO0IntClr = (LPC_GPIOINT->IO0IntStatR | LPC_GPIOINT->IO0IntStatF);
+
+}
+
+void event_irq_init(void) {
+ p30_AS_INPUT;
+ // p30_MODE(PIN_REPEAT);
+ // Enable p30 is P0_4 for rising edge interrupt generation.
+ LPC_GPIOINT->IO0IntEnF |= count_int_mask;
+ NVIC_SetPriority(EINT3_IRQn, 1);
+ // Enable the interrupt
+ NVIC_EnableIRQ(EINT3_IRQn);
+}
+
+
+
+int main() {
+ LED1_USE; // acceleration
+ LED2_USE; // move
+ LED3_USE; // deceleration
+ LED4_USE; // serial port receive
+
+ p22_AS_OUTPUT; // dir pin
+
+ p27_AS_OUTPUT;
+
+ position = 0;
+
+ pc.baud(115200);
+ pc.attach(read_char);
+
+ pc.printf("IGNB-SM %s ['$' for help]\n", VERSION);
+
+ load_settings(SETTINGS_FILE);
+
+ event_irq_init();
+
+ while(1) {}
+}