diff --git a/grbl/serial.c b/grbl/serial.c index cf5f35e..ec68470 100644 --- a/grbl/serial.c +++ b/grbl/serial.c @@ -20,6 +20,7 @@ */ #include "grbl.h" +#include "mbed.h" #define RX_RING_BUFFER (RX_BUFFER_SIZE+1) #define TX_RING_BUFFER (TX_BUFFER_SIZE+1) @@ -32,6 +33,13 @@ uint8_t serial_tx_buffer[TX_RING_BUFFER]; uint8_t serial_tx_buffer_head = 0; volatile uint8_t serial_tx_buffer_tail = 0; +RawSerial mbedSerial(USBTX, USBRX, BAUD_RATE); +void mbedSerialTxinterrupt(); +void mbedSerialRxinterrupt(); + +//Serial Debug LED #2 +DigitalOut serialled(LED2); + // Returns the number of bytes available in the RX serial buffer. uint8_t serial_get_rx_buffer_available() @@ -61,8 +69,16 @@ uint8_t serial_get_tx_buffer_count() return (TX_RING_BUFFER - (ttail-serial_tx_buffer_head)); } - void serial_init() +{ + mbedSerial.baud(BAUD_RATE); + mbedSerial.attach(&mbedSerialTxinterrupt, Serial::TxIrq); + mbedSerial.attach(&mbedSerialRxinterrupt, Serial::RxIrq); + mbedSerial.putc('\n'); +} + + +void serial_init_legacy() { // Set baud rate #if BAUD_RATE < 57600 @@ -81,9 +97,29 @@ void serial_init() // defaults to 8-bit, no parity, 1 stop bit } +void serial_write(uint8_t data) +{ + serialled = 1; + + // Calculate next head + uint8_t next_head = serial_tx_buffer_head + 1; + if (next_head == TX_RING_BUFFER) { next_head = 0; } + + // Wait until there is space in the buffer + while (next_head == serial_tx_buffer_tail) { + // TODO: Restructure st_prep_buffer() calls to be executed here during a long print. + if (sys_rt_exec_state & EXEC_RESET) { return; } // Only check for abort to avoid an endless loop. + } + + // Store data and advance head + serial_tx_buffer[serial_tx_buffer_head] = data; + serial_tx_buffer_head = next_head; + +// mbedSerial.putc(data); +} // Writes one byte to the TX serial buffer. Called by main program. -void serial_write(uint8_t data) { +void serial_write_legacy(uint8_t data) { // Calculate next head uint8_t next_head = serial_tx_buffer_head + 1; if (next_head == TX_RING_BUFFER) { next_head = 0; } @@ -102,9 +138,23 @@ void serial_write(uint8_t data) { UCSR0B |= (1 << UDRIE0); } +void mbedSerialTxinterrupt() { + uint8_t tail = serial_tx_buffer_tail; // Temporary serial_tx_buffer_tail (to optimize for volatile) + + while ((mbedSerial.writeable()) && (tail != serial_tx_buffer_head)) { + // Send a byte from the buffer + mbedSerial.putc(serial_tx_buffer[tail]); + + // Update tail position + tail++; + if (tail == TX_RING_BUFFER) { tail = 0; } + + serial_tx_buffer_tail = tail; + } +} // Data Register Empty Interrupt handler -ISR(SERIAL_UDRE) +void legacy_tx_ISR(void)//ISR(SERIAL_UDRE) { uint8_t tail = serial_tx_buffer_tail; // Temporary serial_tx_buffer_tail (to optimize for volatile) @@ -139,65 +189,71 @@ uint8_t serial_read() } } - -ISR(SERIAL_RX) +void mbedSerialRxinterrupt() //ISR(SERIAL_RX) { - uint8_t data = UDR0; - uint8_t next_head; + serialled = 0; - // Pick off realtime command characters directly from the serial stream. These characters are - // not passed into the main buffer, but these set system state flag bits for realtime execution. - switch (data) { - case CMD_RESET: mc_reset(); break; // Call motion control reset routine. - case CMD_STATUS_REPORT: system_set_exec_state_flag(EXEC_STATUS_REPORT); break; // Set as true - case CMD_CYCLE_START: system_set_exec_state_flag(EXEC_CYCLE_START); break; // Set as true - case CMD_FEED_HOLD: system_set_exec_state_flag(EXEC_FEED_HOLD); break; // Set as true - default : - if (data > 0x7F) { // Real-time control characters are extended ACSII only. - switch(data) { - case CMD_SAFETY_DOOR: system_set_exec_state_flag(EXEC_SAFETY_DOOR); break; // Set as true - case CMD_JOG_CANCEL: - if (sys.state & STATE_JOG) { // Block all other states from invoking motion cancel. - system_set_exec_state_flag(EXEC_MOTION_CANCEL); - } - break; - #ifdef DEBUG - case CMD_DEBUG_REPORT: {uint8_t sreg = SREG; cli(); bit_true(sys_rt_exec_debug,EXEC_DEBUG_REPORT); SREG = sreg;} break; - #endif - case CMD_FEED_OVR_RESET: system_set_exec_motion_override_flag(EXEC_FEED_OVR_RESET); break; - case CMD_FEED_OVR_COARSE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_PLUS); break; - case CMD_FEED_OVR_COARSE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_MINUS); break; - case CMD_FEED_OVR_FINE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_PLUS); break; - case CMD_FEED_OVR_FINE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_MINUS); break; - case CMD_RAPID_OVR_RESET: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_RESET); break; - case CMD_RAPID_OVR_MEDIUM: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_MEDIUM); break; - case CMD_RAPID_OVR_LOW: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_LOW); break; - case CMD_SPINDLE_OVR_RESET: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_RESET); break; - case CMD_SPINDLE_OVR_COARSE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_PLUS); break; - case CMD_SPINDLE_OVR_COARSE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_MINUS); break; - case CMD_SPINDLE_OVR_FINE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_PLUS); break; - case CMD_SPINDLE_OVR_FINE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_MINUS); break; - case CMD_SPINDLE_OVR_STOP: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP); break; - case CMD_COOLANT_FLOOD_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_FLOOD_OVR_TOGGLE); break; - #ifdef ENABLE_M7 - case CMD_COOLANT_MIST_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_MIST_OVR_TOGGLE); break; - #endif - } - // Throw away any unfound extended-ASCII character by not passing it to the serial buffer. - } else { // Write character to buffer - next_head = serial_rx_buffer_head + 1; - if (next_head == RX_RING_BUFFER) { next_head = 0; } + while (mbedSerial.readable()) { + uint8_t data = mbedSerial.getc();//UDR0; - // Write data to buffer unless it is full. - if (next_head != serial_rx_buffer_tail) { - serial_rx_buffer[serial_rx_buffer_head] = data; - serial_rx_buffer_head = next_head; + //BWF: If I turn this off, nothing works. Why? + //mbedSerial.putc(data); + + uint8_t next_head; + + // Pick off realtime command characters directly from the serial stream. These characters are + // not passed into the main buffer, but these set system state flag bits for realtime execution. + switch (data) { + case CMD_RESET: mc_reset(); break; // Call motion control reset routine. + case CMD_STATUS_REPORT: system_set_exec_state_flag(EXEC_STATUS_REPORT); break; // Set as true + case CMD_CYCLE_START: system_set_exec_state_flag(EXEC_CYCLE_START); break; // Set as true + case CMD_FEED_HOLD: system_set_exec_state_flag(EXEC_FEED_HOLD); break; // Set as true + default : + if (data > 0x7F) { // Real-time control characters are extended ACSII only. + switch(data) { + case CMD_SAFETY_DOOR: system_set_exec_state_flag(EXEC_SAFETY_DOOR); break; // Set as true + case CMD_JOG_CANCEL: + if (sys.state & STATE_JOG) { // Block all other states from invoking motion cancel. + system_set_exec_state_flag(EXEC_MOTION_CANCEL); + } + break; + #ifdef DEBUG + case CMD_DEBUG_REPORT: {uint8_t sreg = SREG; cli(); bit_true(sys_rt_exec_debug,EXEC_DEBUG_REPORT); SREG = sreg;} break; + #endif + case CMD_FEED_OVR_RESET: system_set_exec_motion_override_flag(EXEC_FEED_OVR_RESET); break; + case CMD_FEED_OVR_COARSE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_PLUS); break; + case CMD_FEED_OVR_COARSE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_MINUS); break; + case CMD_FEED_OVR_FINE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_PLUS); break; + case CMD_FEED_OVR_FINE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_MINUS); break; + case CMD_RAPID_OVR_RESET: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_RESET); break; + case CMD_RAPID_OVR_MEDIUM: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_MEDIUM); break; + case CMD_RAPID_OVR_LOW: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_LOW); break; + case CMD_SPINDLE_OVR_RESET: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_RESET); break; + case CMD_SPINDLE_OVR_COARSE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_PLUS); break; + case CMD_SPINDLE_OVR_COARSE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_MINUS); break; + case CMD_SPINDLE_OVR_FINE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_PLUS); break; + case CMD_SPINDLE_OVR_FINE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_MINUS); break; + case CMD_SPINDLE_OVR_STOP: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP); break; + case CMD_COOLANT_FLOOD_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_FLOOD_OVR_TOGGLE); break; + #ifdef ENABLE_M7 + case CMD_COOLANT_MIST_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_MIST_OVR_TOGGLE); break; + #endif + } + // Throw away any unfound extended-ASCII character by not passing it to the serial buffer. + } else { // Write character to buffer + next_head = serial_rx_buffer_head + 1; + if (next_head == RX_RING_BUFFER) { next_head = 0; } + + // Write data to buffer unless it is full. + if (next_head != serial_rx_buffer_tail) { + serial_rx_buffer[serial_rx_buffer_head] = data; + serial_rx_buffer_head = next_head; + } } - } + } } } - void serial_reset_read_buffer() { serial_rx_buffer_tail = serial_rx_buffer_head;