Updated for latest stream handling change. Fix for #10.

This commit is contained in:
Terje Io 2021-07-26 15:52:04 +02:00
parent ac334100bf
commit aa57e69426
7 changed files with 134 additions and 149 deletions

View File

@ -8,6 +8,11 @@ See [Compiling](#Compiling) for more information on building.
---
__Important!__ There is a "bug" in Teensyduino prior to v1.54 that may cause [periodic stalls](https://github.com/grblHAL/iMXRT1062/issues/6) in processing.
It is possible that this is only happening when networking is enabled and then not always so.
Regardless of whether networking is enabled or not it is recommended that [Teensyduino v1.54](https://www.pjrc.com/teensy/td_download.html) is used to build this driver.
---
#### Networking plugin
@ -188,4 +193,4 @@ git pull --recurse-submodules
[pio-teensy41]: https://docs.platformio.org/en/latest/boards/teensy/teensy41.html
---
2021-06-08
2021-07-11

View File

@ -360,13 +360,13 @@ static output_signal_t outputpin[] = {
{ .id = Output_StepC, .port = &stepC, .pin = C_STEP_PIN, .group = PinGroup_StepperStep },
#endif
#ifdef X2_STEP_PIN
{ .id = Output_StepX, .port = &stepX2, .pin = X2_STEP_PIN, .group = PinGroup_StepperStep },
{ .id = Output_StepX_2, .port = &stepX2, .pin = X2_STEP_PIN, .group = PinGroup_StepperStep },
#endif
#ifdef Y2_STEP_PIN
{ .id = Output_StepY, .port = &stepY2, .pin = Y2_STEP_PIN, .group = PinGroup_StepperStep },
{ .id = Output_StepY_2, .port = &stepY2, .pin = Y2_STEP_PIN, .group = PinGroup_StepperStep },
#endif
#ifdef Z2_STEP_PIN
{ .id = Output_StepZ, .port = &stepZ2, .pin = Z2_STEP_PIN, .group = PinGroup_StepperStep },
{ .id = Output_StepZ_2, .port = &stepZ2, .pin = Z2_STEP_PIN, .group = PinGroup_StepperStep },
#endif
{ .id = Output_DirX, .port = &dirX, .pin = X_DIRECTION_PIN, .group = PinGroup_StepperDir },
{ .id = Output_DirY, .port = &dirY, .pin = Y_DIRECTION_PIN, .group = PinGroup_StepperDir },
@ -381,13 +381,13 @@ static output_signal_t outputpin[] = {
{ .id = Output_DirC, .port = &dirC, .pin = C_DIRECTION_PIN, .group = PinGroup_StepperDir },
#endif
#ifdef X2_DIRECTION_PIN
{ .id = Output_DirX, .port = &dirX2, .pin = X2_DIRECTION_PIN, .group = PinGroup_StepperDir },
{ .id = Output_DirX_2, .port = &dirX2, .pin = X2_DIRECTION_PIN, .group = PinGroup_StepperDir },
#endif
#ifdef Y2_DIRECTION_PIN
{ .id = Output_DirY, .port = &dirY2, .pin = Y2_DIRECTION_PIN, .group = PinGroup_StepperDir },
{ .id = Output_DirY_2, .port = &dirY2, .pin = Y2_DIRECTION_PIN, .group = PinGroup_StepperDir },
#endif
#ifdef Z2_DIRECTION_PIN
{ .id = Output_DirZ, .port = &dirZ2, .pin = Z2_DIRECTION_PIN, .group = PinGroup_StepperDir },
{ .id = Output_DirZ_2, .port = &dirZ2, .pin = Z2_DIRECTION_PIN, .group = PinGroup_StepperDir },
#endif
#if !TRINAMIC_ENABLE
#ifdef STEPPERS_ENABLE_PIN
@ -552,7 +552,7 @@ static bool selectStream (const io_stream_t *stream)
if(!stream)
stream = active_stream == StreamType_Bluetooth ? serial_stream : last_serial_stream;
memcpy(&hal.stream, stream, offsetof(io_stream_t, enqueue_realtime_command));
memcpy(&hal.stream, stream, sizeof(io_stream_t));
#if ETHERNET_ENABLE
if(!hal.stream.write_all)
@ -562,8 +562,7 @@ static bool selectStream (const io_stream_t *stream)
hal.stream.write_all = hal.stream.write;
#endif
if(!hal.stream.enqueue_realtime_command)
hal.stream.enqueue_realtime_command = protocol_enqueue_realtime_command;
hal.stream.set_enqueue_rt_handler(protocol_enqueue_realtime_command);
if(hal.stream.disable)
hal.stream.disable(false);
@ -993,7 +992,7 @@ inline static limit_signals_t limitsGetState()
{
limit_signals_t signals = {0};
signals.min.mask = signals.min2.mask = settings.limits.invert.mask;
signals.min.mask = settings.limits.invert.mask;
#ifdef DUAL_LIMIT_SWITCHES
signals.min2.mask = settings.limits.invert.mask;
#endif
@ -1036,7 +1035,7 @@ inline static limit_signals_t limitsGetState()
#endif
if(settings.limits.invert.mask) {
signals.min.value ^= settings.limits.invert.mask;
signals.min.mask ^= settings.limits.invert.mask;
#ifdef DUAL_LIMIT_SWITCHES
signals.min2.mask ^= settings.limits.invert.mask;
#endif
@ -2098,18 +2097,12 @@ static void execute_realtime (uint_fast16_t state)
#endif
#ifdef DEBUGOUT
void debugOut (bool on)
{
digitalWrite(13, on); // LED
}
#endif
#ifdef UART_DEBUG
void uart_debug_write (char *s)
{
serialWriteS(s);
while(serialTxCount()); // Wait until message is delivered
}
#endif
// Cold restart (T4.x has no reset button)
@ -2147,7 +2140,7 @@ bool driver_init (void)
options[strlen(options) - 1] = '\0';
hal.info = "iMXRT1062";
hal.driver_version = "210703";
hal.driver_version = "210725";
#ifdef BOARD_NAME
hal.board = BOARD_NAME;
#endif
@ -2271,13 +2264,8 @@ bool driver_init (void)
hal.driver_cap.limits_pull_up = On;
hal.driver_cap.probe_pull_up = On;
#ifdef DEBUGOUT
hal.debug_out = debugOut;
#endif
#ifdef UART_DEBUG
serialInit(115200);
uart_debug_write(ASCII_EOL "UART Debug:" ASCII_EOL);
#if defined(DEBUGOUT) && USB_SERIAL_CDC > 0
debug_stream_init(serialInit(115200));
#endif
uint32_t i;

View File

@ -43,10 +43,6 @@
#define MCP3221_ENABLE 0
#endif
#if USB_SERIAL_CDC > 0
//#define UART_DEBUG // For development only - enable only with USB_SERIAL_CDC enabled and SPINDLE_HUANYANG disabled
#endif
// Timer assignments (for reference, Arduino libs does not follow the CMSIS style...)
//#define STEPPER_TIMER PIT0 (32 bit)
@ -227,8 +223,4 @@ void ioports_init (pin_group_pins_t *aux_inputs, pin_group_pins_t *aux_outputs);
void ioports_event (input_signal_t *input);
#endif
#ifdef UART_DEBUG
void uart_debug_write (char *s);
#endif
#endif // __DRIVER_H__

View File

@ -30,7 +30,7 @@ uint16_t MCP3221_read (void)
I2C_Receive(MCP3221_ADDRESS, value, 2, true);
return value[0] << 8 | value[1];
return (value[0] << 8) | value[1];
}
bool MCP3221_init (void)

View File

@ -42,6 +42,7 @@
#include <string.h>
#include "driver.h"
#include "grbl/protocol.h"
#define UART_CLOCK 24000000
#define CTRL_ENABLE (LPUART_CTRL_TE | LPUART_CTRL_RE | LPUART_CTRL_RIE | LPUART_CTRL_ILIE)
@ -142,20 +143,20 @@ void transmitterEnable(uint8_t pin)
static uint16_t tx_fifo_size;
static stream_tx_buffer_t txbuffer = {0};
static stream_rx_buffer_t rxbuffer = {0};
static enqueue_realtime_command_ptr enqueue_realtime_command = protocol_enqueue_realtime_command;
//
// serialGetC - returns -1 if no data available
//
static int16_t serialGetC (void)
{
int16_t data;
uint_fast16_t bptr = rxbuffer.tail;
uint_fast16_t tail = rxbuffer.tail; // Get buffer pointer
if(bptr == rxbuffer.head)
return -1; // no data available else EOF
if(tail == rxbuffer.head)
return -1; // no data available
data = rxbuffer.data[bptr++]; // Get next character, increment tmp pointer
rxbuffer.tail = bptr & (RX_BUFFER_SIZE - 1); // and update pointer
int16_t data = rxbuffer.data[tail]; // Get next character, increment tmp pointer
rxbuffer.tail = BUFNEXT(tail, rxbuffer); // and update pointer
return data;
}
@ -187,34 +188,27 @@ static void serialRxCancel (void)
{
serialRxFlush();
rxbuffer.data[rxbuffer.head] = ASCII_CAN;
rxbuffer.head = (rxbuffer.tail + 1) & (RX_BUFFER_SIZE - 1);
rxbuffer.head = BUFNEXT(rxbuffer.head, rxbuffer);
}
static bool serialPutC (const char c)
{
uint_fast16_t next_head;
// swr(c); return true;
// if (transmit_pin_baseReg_) DIRECT_WRITE_HIGH(transmit_pin_baseReg_, transmit_pin_bitmask_);
if(txbuffer.head == txbuffer.tail && ((UART.port->WATER >> 8) & 0x7) < tx_fifo_size) {
UART.port->DATA = c;
return true;
}
next_head = (txbuffer.head + 1) & (TX_BUFFER_SIZE - 1); // Get and update head pointer
uint_fast16_t next_head = BUFNEXT(txbuffer.head, txbuffer); // Get next head pointer
while(txbuffer.tail == next_head) { // Buffer full, block until space is available...
while(txbuffer.tail == next_head) { // Buffer full, block until space is available...
if(!hal.stream_blocking_callback())
return false;
}
txbuffer.data[txbuffer.head] = c; // Add data to buffer
txbuffer.head = next_head; // and update head pointer
txbuffer.data[txbuffer.head] = c; // Add data to buffer
txbuffer.head = next_head; // and update head pointer
__disable_irq();
// transmitting_ = 1;
UART.port->CTRL |= LPUART_CTRL_TIE; // (may need to handle this issue)BITBAND_SET_BIT(LPUART0_CTRL, TIE_BIT); // Enable TX interrupts
__enable_irq();
@ -287,6 +281,16 @@ static bool serialDisable (bool disable)
return true;
}
static enqueue_realtime_command_ptr serialSetRtHandler (enqueue_realtime_command_ptr handler)
{
enqueue_realtime_command_ptr prev = enqueue_realtime_command;
if(handler)
enqueue_realtime_command = handler;
return prev;
}
const io_stream_t *serialInit (uint32_t baud_rate)
{
PROGMEM static const io_stream_t stream = {
@ -305,7 +309,8 @@ const io_stream_t *serialInit (uint32_t baud_rate)
.cancel_read_buffer = serialRxCancel,
.suspend_read = serialSuspendInput,
.disable = serialDisable,
.set_baud_rate = serialSetBaudRate
.set_baud_rate = serialSetBaudRate,
.set_enqueue_rt_handler = serialSetRtHandler
};
*UART.ccm_register |= UART.ccm_value;
@ -376,69 +381,44 @@ uint16_t format = 0;
if (format & 0x100)
UART.port->BAUD |= LPUART_BAUD_SBNS;
//transmitterEnable(1);
return &stream;
}
static void uart_interrupt_handler (void)
{
uint_fast16_t bptr;
uint32_t data, ctrl = UART.port->CTRL;
uint32_t ctrl = UART.port->CTRL;
if ((ctrl & LPUART_CTRL_TIE) && (UART.port->STAT & LPUART_STAT_TDRE))
if((ctrl & LPUART_CTRL_TIE) && (UART.port->STAT & LPUART_STAT_TDRE))
{
bptr = txbuffer.tail;
uint_fast16_t tail = txbuffer.tail; // Get buffer pointer
do {
if(txbuffer.head != bptr) {
UART.port->DATA = txbuffer.data[bptr++]; // Put character in TXT register
bptr &= (TX_BUFFER_SIZE - 1); // and update tmp tail pointer
if(txbuffer.head != tail) {
UART.port->DATA = txbuffer.data[tail]; // Put character in TXT register
tail = BUFNEXT(tail, txbuffer); // and update tmp tail pointer
} else
break;
} while(((UART.port->WATER >> 8) & 0x7) < tx_fifo_size);
txbuffer.tail = bptr; // Update tail pinter
if(bptr == txbuffer.head) { // Disable TX interrups
if((txbuffer.tail = tail) == txbuffer.head) // Disable TX interrups
UART.port->CTRL &= ~LPUART_CTRL_TIE;
// UART.port->CTRL |= LPUART_CTRL_TCIE; // Actually wondering if we can just leave this one on...
}
}
if ((ctrl & LPUART_CTRL_TCIE) && (UART.port->STAT & LPUART_STAT_TC))
{
// transmitting_ = 0;
// if (transmit_pin_baseReg_) DIRECT_WRITE_LOW(transmit_pin_baseReg_, transmit_pin_bitmask_);
UART.port->CTRL &= ~LPUART_CTRL_TCIE;
}
if (UART.port->STAT & (LPUART_STAT_RDRF | LPUART_STAT_IDLE)) {
if(UART.port->STAT & (LPUART_STAT_RDRF | LPUART_STAT_IDLE)) {
while ((UART.port->WATER >> 24) & 0x7) {
bptr = (rxbuffer.head + 1) & (RX_BUFFER_SIZE - 1); // Get next head pointer
data = UART.port->DATA & 0xFF; // and read input (use only 8 bits of data)
if(bptr == rxbuffer.tail) { // If buffer full
rxbuffer.overflow = true; // flag overflow
} else {
#if MODBUS_ENABLE
rxbuffer.data[rxbuffer.head] = (char)data; // Add data to buffer
rxbuffer.head = bptr; // and update pointer
#else
if(data == CMD_TOOL_ACK && !rxbuffer.backup) {
stream_rx_backup(&rxbuffer);
hal.stream.read = serialGetC; // restore normal input
} else if(!hal.stream.enqueue_realtime_command((char)data)) {
rxbuffer.data[rxbuffer.head] = (char)data; // Add data to buffer
rxbuffer.head = bptr; // and update pointer
while((UART.port->WATER >> 24) & 0x7) {
uint32_t data = UART.port->DATA & 0xFF; // Read input (use only 8 bits of data)
if(!enqueue_realtime_command((char)data)) {
uint_fast16_t next_head = BUFNEXT(rxbuffer.head, rxbuffer); // Get next head pointer
if(next_head == rxbuffer.tail) // If buffer full
rxbuffer.overflow = true; // flag overflow
else {
rxbuffer.data[rxbuffer.head] = (char)data; // Add data to buffer
rxbuffer.head = next_head; // and update pointer
}
#endif
}
}

View File

@ -34,18 +34,21 @@
extern "C" {
#endif
#include "grbl/protocol.h"
#define BLOCK_RX_BUFFER_SIZE 20
static stream_block_tx_buffer_t txbuf = {0};
static char rxbuf[BLOCK_RX_BUFFER_SIZE];
static stream_rx_buffer_t usb_rxbuffer;
static stream_rx_buffer_t rxbuf;
static enqueue_realtime_command_ptr enqueue_realtime_command = protocol_enqueue_realtime_command;
/*
//
// Returns number of characters in serial input buffer
//
static uint16_t usb_serialRxCount (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
uint_fast16_t tail = rxbuf.tail, head = rxbuf.head;
return (uint16_t)BUFCOUNT(head, tail, RX_BUFFER_SIZE);
}
*/
@ -54,7 +57,7 @@ static uint16_t usb_serialRxCount (void)
//
static uint16_t usb_serialRxFree (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
uint_fast16_t tail = rxbuf.tail, head = rxbuf.head;
return (uint16_t)((RX_BUFFER_SIZE - 1) - BUFCOUNT(head, tail, RX_BUFFER_SIZE));
}
@ -64,7 +67,7 @@ static uint16_t usb_serialRxFree (void)
void usb_serialRxFlush (void)
{
SerialUSB.flush();
usb_rxbuffer.tail = usb_rxbuffer.head;
rxbuf.tail = rxbuf.head;
}
//
@ -72,9 +75,9 @@ void usb_serialRxFlush (void)
//
static void usb_serialRxCancel (void)
{
usb_rxbuffer.data[usb_rxbuffer.head] = CMD_RESET;
usb_rxbuffer.tail = usb_rxbuffer.head;
usb_rxbuffer.head = (usb_rxbuffer.tail + 1) & (RX_BUFFER_SIZE - 1);
rxbuf.data[rxbuf.head] = CMD_RESET;
rxbuf.tail = rxbuf.head;
rxbuf.head = BUFNEXT(rxbuf.head, rxbuf);
}
//
@ -158,20 +161,28 @@ static void usb_serialWrite (const char *s, uint16_t length)
//
static int16_t usb_serialGetC (void)
{
uint16_t bptr = usb_rxbuffer.tail;
if(bptr == usb_rxbuffer.head)
if(rxbuf.tail == rxbuf.head)
return -1; // no data available else EOF
char data = usb_rxbuffer.data[bptr++]; // Get next character, increment tmp pointer
usb_rxbuffer.tail = bptr & (RX_BUFFER_SIZE - 1); // and update pointer
char data = rxbuf.data[rxbuf.tail]; // Get next character, increment tmp pointer
rxbuf.tail = BUFNEXT(rxbuf.tail, rxbuf); // and update pointer
return (int16_t)data;
}
static bool usb_serialSuspendInput (bool suspend)
{
return stream_rx_suspend(&usb_rxbuffer, suspend);
return stream_rx_suspend(&rxbuf, suspend);
}
static enqueue_realtime_command_ptr usb_serialSetRtHandler (enqueue_realtime_command_ptr handler)
{
enqueue_realtime_command_ptr prev = enqueue_realtime_command;
if(handler)
enqueue_realtime_command = handler;
return prev;
}
const io_stream_t *usb_serialInit (void)
@ -186,6 +197,7 @@ const io_stream_t *usb_serialInit (void)
.read = usb_serialGetC,
.reset_read_buffer = usb_serialRxFlush,
.cancel_read_buffer = usb_serialRxCancel,
.set_enqueue_rt_handler = usb_serialSetRtHandler,
.suspend_read = usb_serialSuspendInput
};
@ -216,27 +228,25 @@ void usb_execute_realtime (uint_fast16_t state)
{
char c, *dp;
int avail, free;
static char tmpbuf[BLOCK_RX_BUFFER_SIZE];
if((avail = SerialUSB.available())) {
dp = rxbuf;
dp = tmpbuf;
free = usb_serialRxFree();
free = free > BLOCK_RX_BUFFER_SIZE ? BLOCK_RX_BUFFER_SIZE : free;
avail = SerialUSB.readBytes(rxbuf, avail > free ? free : avail);
avail = SerialUSB.readBytes(tmpbuf, avail > free ? free : avail);
while(avail--) {
c = *dp++;
if(c == CMD_TOOL_ACK && !usb_rxbuffer.backup) {
stream_rx_backup(&usb_rxbuffer);
hal.stream.read = usb_serialGetC; // restore normal input
} else if(!hal.stream.enqueue_realtime_command(c)) {
uint32_t bptr = (usb_rxbuffer.head + 1) & (RX_BUFFER_SIZE - 1); // Get next head pointer
if(bptr == usb_rxbuffer.tail) // If buffer full
usb_rxbuffer.overflow = On; // flag overflow,
if(!enqueue_realtime_command(c)) {
uint_fast16_t next_head = BUFNEXT(rxbuf.head, rxbuf); // Get next head pointer
if(next_head == rxbuf.tail) // If buffer full
rxbuf.overflow = On; // flag overflow,
else {
usb_rxbuffer.data[usb_rxbuffer.head] = c; // else add character data to buffer
usb_rxbuffer.head = bptr; // and update pointer
rxbuf.data[rxbuf.head] = c; // else add character data to buffer
rxbuf.head = next_head; // and update pointer
}
}
}

View File

@ -27,21 +27,23 @@
#include "usb_serial.h"
#include "driver.h"
#include "grbl/protocol.h"
#if USB_SERIAL_CDC == 2
#define BLOCK_RX_BUFFER_SIZE 20
static stream_block_tx_buffer_t txbuf = {0};
static char rxbuf[BLOCK_RX_BUFFER_SIZE];
static stream_rx_buffer_t usb_rxbuffer;
static stream_rx_buffer_t rxbuf;
static enqueue_realtime_command_ptr enqueue_realtime_command = protocol_enqueue_realtime_command;
/*
//
// Returns number of characters in serial input buffer
//
static uint16_t usb_serialRxCount (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
uint_fast16_t tail = rxbuf.tail, head = rxbuf.head;
return (uint16_t)BUFCOUNT(head, tail, RX_BUFFER_SIZE);
}
*/
@ -50,7 +52,8 @@ static uint16_t usb_serialRxCount (void)
//
static uint16_t usb_serialRxFree (void)
{
uint_fast16_t tail = usb_rxbuffer.tail, head = usb_rxbuffer.head;
uint_fast16_t tail = rxbuf.tail, head = rxbuf.head;
return (uint16_t)((RX_BUFFER_SIZE - 1) - BUFCOUNT(head, tail, RX_BUFFER_SIZE));
}
@ -60,7 +63,7 @@ static uint16_t usb_serialRxFree (void)
static void usb_serialRxFlush (void)
{
usb_serial_flush_input();
usb_rxbuffer.tail = usb_rxbuffer.head;
rxbuf.tail = rxbuf.head;
}
//
@ -68,9 +71,9 @@ static void usb_serialRxFlush (void)
//
static void usb_serialRxCancel (void)
{
usb_rxbuffer.data[usb_rxbuffer.head] = CMD_RESET;
usb_rxbuffer.tail = usb_rxbuffer.head;
usb_rxbuffer.head = (usb_rxbuffer.tail + 1) & (RX_BUFFER_SIZE - 1);
rxbuf.data[rxbuf.head] = CMD_RESET;
rxbuf.tail = rxbuf.head;
rxbuf.head = BUFNEXT(rxbuf.head, rxbuf);
}
//
@ -152,20 +155,28 @@ static void usb_serialWrite (const char *s, uint16_t length)
//
static int16_t usb_serialGetC (void)
{
uint16_t bptr = usb_rxbuffer.tail;
if(rxbuf.tail == rxbuf.head)
return -1; // no data available
if(bptr == usb_rxbuffer.head)
return -1; // no data available else EOF
char data = usb_rxbuffer.data[bptr++]; // Get next character, increment tmp pointer
usb_rxbuffer.tail = bptr & (RX_BUFFER_SIZE - 1); // and update pointer
char data = rxbuf.data[rxbuf.tail]; // Get next character, increment tmp pointer
rxbuf.tail = BUFNEXT(rxbuf.tail, rxbuf); // and update pointer
return (int16_t)data;
}
static bool usb_serialSuspendInput (bool suspend)
{
return stream_rx_suspend(&usb_rxbuffer, suspend);
return false;// stream_rx_suspend(&rxbuf, suspend);
}
static enqueue_realtime_command_ptr usb_serialSetRtHandler (enqueue_realtime_command_ptr handler)
{
enqueue_realtime_command_ptr prev = enqueue_realtime_command;
if(handler)
enqueue_realtime_command = handler;
return prev;
}
const io_stream_t *usb_serialInit(void)
@ -179,7 +190,8 @@ const io_stream_t *usb_serialInit(void)
.get_rx_buffer_free = usb_serialRxFree,
.reset_read_buffer = usb_serialRxFlush,
.cancel_read_buffer = usb_serialRxCancel,
.suspend_read = usb_serialSuspendInput
.suspend_read = usb_serialSuspendInput,
.set_enqueue_rt_handler = usb_serialSetRtHandler
};
// usb_serial_configure(); // Done somewhere already - do not call again
@ -200,27 +212,25 @@ void usb_execute_realtime (uint_fast16_t state)
{
char c, *dp;
int avail, free;
static char tmpbuf[BLOCK_RX_BUFFER_SIZE];
if((avail = usb_serial_available())) {
dp = rxbuf;
dp = tmpbuf;
free = usb_serialRxFree();
free = free > BLOCK_RX_BUFFER_SIZE ? BLOCK_RX_BUFFER_SIZE : free;
avail = usb_serial_read(rxbuf, avail > free ? free : avail);
avail = usb_serial_read(tmpbuf, avail > free ? free : avail);
while(avail--) {
c = *dp++;
if(c == CMD_TOOL_ACK && !usb_rxbuffer.backup) {
stream_rx_backup(&usb_rxbuffer);
hal.stream.read = usb_serialGetC; // restore normal input
} else if(!hal.stream.enqueue_realtime_command(c)) {
uint32_t bptr = (usb_rxbuffer.head + 1) & (RX_BUFFER_SIZE - 1); // Get next head pointer
if(bptr == usb_rxbuffer.tail) // If buffer full
usb_rxbuffer.overflow = On; // flag overflow,
if(!enqueue_realtime_command(c)) {
uint_fast16_t next_head = BUFNEXT(rxbuf.head, rxbuf); // Get next head pointer
if(next_head == rxbuf.tail) // If buffer full
rxbuf.overflow = On; // flag overflow,
else {
usb_rxbuffer.data[usb_rxbuffer.head] = c; // else add character data to buffer
usb_rxbuffer.head = bptr; // and update pointer
rxbuf.data[rxbuf.head] = c; // else add character data to buffer
rxbuf.head = next_head; // and update pointer
}
}
}