|
|
@ -28,9 +28,8 @@
|
|
|
|
* Modified 28 September 2010 by Mark Sproul
|
|
|
|
* Modified 28 September 2010 by Mark Sproul
|
|
|
|
* Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
|
|
|
|
* Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
#include "MarlinSerial.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "stepper.h"
|
|
|
|
#include "MarlinSerial.h"
|
|
|
|
#include "Marlin.h"
|
|
|
|
#include "Marlin.h"
|
|
|
|
|
|
|
|
|
|
|
|
// Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.)
|
|
|
|
// Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.)
|
|
|
@ -38,15 +37,16 @@
|
|
|
|
#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
|
|
|
|
#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
|
|
|
|
|
|
|
|
|
|
|
|
#if UART_PRESENT(SERIAL_PORT)
|
|
|
|
#if UART_PRESENT(SERIAL_PORT)
|
|
|
|
ring_buffer_r rx_buffer = { { 0 }, 0, 0 };
|
|
|
|
ring_buffer_r rx_buffer = { { 0 }, 0, 0 };
|
|
|
|
#if TX_BUFFER_SIZE > 0
|
|
|
|
#if TX_BUFFER_SIZE > 0
|
|
|
|
ring_buffer_t tx_buffer = { { 0 }, 0, 0 };
|
|
|
|
ring_buffer_t tx_buffer = { { 0 }, 0, 0 };
|
|
|
|
static bool _written;
|
|
|
|
static bool _written;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(EMERGENCY_PARSER)
|
|
|
|
#if ENABLED(EMERGENCY_PARSER)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "stepper.h"
|
|
|
|
#include "language.h"
|
|
|
|
#include "language.h"
|
|
|
|
|
|
|
|
|
|
|
|
// Currently looking for: M108, M112, M410
|
|
|
|
// Currently looking for: M108, M112, M410
|
|
|
@ -134,13 +134,12 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#endif // EMERGENCY_PARSER
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FORCE_INLINE void store_char(unsigned char c) {
|
|
|
|
FORCE_INLINE void store_char(unsigned char c) {
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
uint8_t h = rx_buffer.head;
|
|
|
|
const uint8_t h = rx_buffer.head,
|
|
|
|
uint8_t i = (uint8_t)(h + 1) & (RX_BUFFER_SIZE - 1);
|
|
|
|
i = (uint8_t)(h + 1) & (RX_BUFFER_SIZE - 1);
|
|
|
|
|
|
|
|
|
|
|
|
// if we should be storing the received character into the location
|
|
|
|
// if we should be storing the received character into the location
|
|
|
|
// just before the tail (meaning that the head would advance to the
|
|
|
|
// just before the tail (meaning that the head would advance to the
|
|
|
@ -162,8 +161,8 @@
|
|
|
|
FORCE_INLINE void _tx_udr_empty_irq(void) {
|
|
|
|
FORCE_INLINE void _tx_udr_empty_irq(void) {
|
|
|
|
// If interrupts are enabled, there must be more data in the output
|
|
|
|
// If interrupts are enabled, there must be more data in the output
|
|
|
|
// buffer. Send the next byte
|
|
|
|
// buffer. Send the next byte
|
|
|
|
uint8_t t = tx_buffer.tail;
|
|
|
|
const uint8_t t = tx_buffer.tail,
|
|
|
|
uint8_t c = tx_buffer.buffer[t];
|
|
|
|
c = tx_buffer.buffer[t];
|
|
|
|
tx_buffer.tail = (t + 1) & (TX_BUFFER_SIZE - 1);
|
|
|
|
tx_buffer.tail = (t + 1) & (TX_BUFFER_SIZE - 1);
|
|
|
|
|
|
|
|
|
|
|
|
M_UDRx = c;
|
|
|
|
M_UDRx = c;
|
|
|
@ -189,14 +188,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef M_USARTx_RX_vect
|
|
|
|
#ifdef M_USARTx_RX_vect
|
|
|
|
ISR(M_USARTx_RX_vect) {
|
|
|
|
ISR(M_USARTx_RX_vect) {
|
|
|
|
unsigned char c = M_UDRx;
|
|
|
|
const unsigned char c = M_UDRx;
|
|
|
|
store_char(c);
|
|
|
|
store_char(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// Public Methods
|
|
|
|
// Public Methods
|
|
|
|
|
|
|
|
|
|
|
|
void MarlinSerial::begin(long baud) {
|
|
|
|
void MarlinSerial::begin(const long baud) {
|
|
|
|
uint16_t baud_setting;
|
|
|
|
uint16_t baud_setting;
|
|
|
|
bool useU2X = true;
|
|
|
|
bool useU2X = true;
|
|
|
|
|
|
|
|
|
|
|
@ -204,9 +203,7 @@
|
|
|
|
// hard-coded exception for compatibility with the bootloader shipped
|
|
|
|
// hard-coded exception for compatibility with the bootloader shipped
|
|
|
|
// with the Duemilanove and previous boards and the firmware on the 8U2
|
|
|
|
// with the Duemilanove and previous boards and the firmware on the 8U2
|
|
|
|
// on the Uno and Mega 2560.
|
|
|
|
// on the Uno and Mega 2560.
|
|
|
|
if (baud == 57600) {
|
|
|
|
if (baud == 57600) useU2X = false;
|
|
|
|
useU2X = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (useU2X) {
|
|
|
|
if (useU2X) {
|
|
|
@ -240,14 +237,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
void MarlinSerial::checkRx(void) {
|
|
|
|
void MarlinSerial::checkRx(void) {
|
|
|
|
if (TEST(M_UCSRxA, M_RXCx)) {
|
|
|
|
if (TEST(M_UCSRxA, M_RXCx)) {
|
|
|
|
uint8_t c = M_UDRx;
|
|
|
|
const uint8_t c = M_UDRx;
|
|
|
|
store_char(c);
|
|
|
|
store_char(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int MarlinSerial::peek(void) {
|
|
|
|
int MarlinSerial::peek(void) {
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
int v = rx_buffer.head == rx_buffer.tail ? -1 : rx_buffer.buffer[rx_buffer.tail];
|
|
|
|
const int v = rx_buffer.head == rx_buffer.tail ? -1 : rx_buffer.buffer[rx_buffer.tail];
|
|
|
|
CRITICAL_SECTION_END;
|
|
|
|
CRITICAL_SECTION_END;
|
|
|
|
return v;
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -255,10 +252,9 @@
|
|
|
|
int MarlinSerial::read(void) {
|
|
|
|
int MarlinSerial::read(void) {
|
|
|
|
int v;
|
|
|
|
int v;
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
uint8_t t = rx_buffer.tail;
|
|
|
|
const uint8_t t = rx_buffer.tail;
|
|
|
|
if (rx_buffer.head == t) {
|
|
|
|
if (rx_buffer.head == t)
|
|
|
|
v = -1;
|
|
|
|
v = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
v = rx_buffer.buffer[t];
|
|
|
|
v = rx_buffer.buffer[t];
|
|
|
|
rx_buffer.tail = (uint8_t)(t + 1) & (RX_BUFFER_SIZE - 1);
|
|
|
|
rx_buffer.tail = (uint8_t)(t + 1) & (RX_BUFFER_SIZE - 1);
|
|
|
@ -269,8 +265,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t MarlinSerial::available(void) {
|
|
|
|
uint8_t MarlinSerial::available(void) {
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
uint8_t h = rx_buffer.head,
|
|
|
|
const uint8_t h = rx_buffer.head,
|
|
|
|
t = rx_buffer.tail;
|
|
|
|
t = rx_buffer.tail;
|
|
|
|
CRITICAL_SECTION_END;
|
|
|
|
CRITICAL_SECTION_END;
|
|
|
|
return (uint8_t)(RX_BUFFER_SIZE + h - t) & (RX_BUFFER_SIZE - 1);
|
|
|
|
return (uint8_t)(RX_BUFFER_SIZE + h - t) & (RX_BUFFER_SIZE - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -290,13 +286,13 @@
|
|
|
|
#if TX_BUFFER_SIZE > 0
|
|
|
|
#if TX_BUFFER_SIZE > 0
|
|
|
|
uint8_t MarlinSerial::availableForWrite(void) {
|
|
|
|
uint8_t MarlinSerial::availableForWrite(void) {
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
uint8_t h = tx_buffer.head;
|
|
|
|
const uint8_t h = tx_buffer.head,
|
|
|
|
uint8_t t = tx_buffer.tail;
|
|
|
|
t = tx_buffer.tail;
|
|
|
|
CRITICAL_SECTION_END;
|
|
|
|
CRITICAL_SECTION_END;
|
|
|
|
return (uint8_t)(TX_BUFFER_SIZE + h - t) & (TX_BUFFER_SIZE - 1);
|
|
|
|
return (uint8_t)(TX_BUFFER_SIZE + h - t) & (TX_BUFFER_SIZE - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MarlinSerial::write(uint8_t c) {
|
|
|
|
void MarlinSerial::write(const uint8_t c) {
|
|
|
|
_written = true;
|
|
|
|
_written = true;
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
CRITICAL_SECTION_START;
|
|
|
|
bool emty = (tx_buffer.head == tx_buffer.tail);
|
|
|
|
bool emty = (tx_buffer.head == tx_buffer.tail);
|
|
|
@ -312,7 +308,7 @@
|
|
|
|
CRITICAL_SECTION_END;
|
|
|
|
CRITICAL_SECTION_END;
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uint8_t i = (tx_buffer.head + 1) & (TX_BUFFER_SIZE - 1);
|
|
|
|
const uint8_t i = (tx_buffer.head + 1) & (TX_BUFFER_SIZE - 1);
|
|
|
|
|
|
|
|
|
|
|
|
// If the output buffer is full, there's nothing for it other than to
|
|
|
|
// If the output buffer is full, there's nothing for it other than to
|
|
|
|
// wait for the interrupt handler to empty it a bit
|
|
|
|
// wait for the interrupt handler to empty it a bit
|
|
|
@ -372,25 +368,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MarlinSerial::print(char c, int base) {
|
|
|
|
void MarlinSerial::print(char c, int base) {
|
|
|
|
print((long) c, base);
|
|
|
|
print((long)c, base);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MarlinSerial::print(unsigned char b, int base) {
|
|
|
|
void MarlinSerial::print(unsigned char b, int base) {
|
|
|
|
print((unsigned long) b, base);
|
|
|
|
print((unsigned long)b, base);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MarlinSerial::print(int n, int base) {
|
|
|
|
void MarlinSerial::print(int n, int base) {
|
|
|
|
print((long) n, base);
|
|
|
|
print((long)n, base);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MarlinSerial::print(unsigned int n, int base) {
|
|
|
|
void MarlinSerial::print(unsigned int n, int base) {
|
|
|
|
print((unsigned long) n, base);
|
|
|
|
print((unsigned long)n, base);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MarlinSerial::print(long n, int base) {
|
|
|
|
void MarlinSerial::print(long n, int base) {
|
|
|
|
if (base == 0) {
|
|
|
|
if (base == 0)
|
|
|
|
write(n);
|
|
|
|
write(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (base == 10) {
|
|
|
|
else if (base == 10) {
|
|
|
|
if (n < 0) {
|
|
|
|
if (n < 0) {
|
|
|
|
print('-');
|
|
|
|
print('-');
|
|
|
@ -398,9 +393,8 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printNumber(n, 10);
|
|
|
|
printNumber(n, 10);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else
|
|
|
|
printNumber(n, base);
|
|
|
|
printNumber(n, base);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MarlinSerial::print(unsigned long n, int base) {
|
|
|
|
void MarlinSerial::print(unsigned long n, int base) {
|
|
|
|