Skip to content

Commit 16a6800

Browse files
authored
Bugfix/desmakers 4270 serial.print is not allways working correctly in xmc for arduino version 3.5.0 (#322)
* fix: remove ringbuffer software implementation for uart tx
1 parent c2b9f42 commit 16a6800

File tree

1 file changed

+17
-64
lines changed

1 file changed

+17
-64
lines changed

cores/HardwareSerial.cpp

+17-64
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ HardwareSerial::HardwareSerial(XMC_UART_t *xmc_uart_config,
3232
RingBuffer *tx_buffer) {
3333
_XMC_UART_config = xmc_uart_config;
3434
_rx_buffer = rx_buffer;
35-
_tx_buffer = tx_buffer;
35+
_tx_buffer = tx_buffer; // TODO: replaced by TBUF (hardware register), can be actually removed
3636
}
3737

3838
// Public Methods //////////////////////////////////////////////////////////////
@@ -119,10 +119,12 @@ int HardwareSerial::available(void) {
119119
}
120120

121121
int HardwareSerial::availableForWrite(void) {
122-
int tail = _tx_buffer->_iTail; // Snapshot index affected by irq
123-
if (_tx_buffer->_iHead >= tail)
124-
return SERIAL_BUFFER_SIZE - 1 - _tx_buffer->_iHead + tail;
125-
return tail - _tx_buffer->_iHead - 1;
122+
int available = XMC_USIC_CH_GetTransmitBufferStatus(_XMC_UART_config->channel);
123+
if (available == XMC_USIC_CH_TBUF_STATUS_IDLE) {
124+
return 0;
125+
} else {
126+
return 1;
127+
} // TODO: should return bytes avaliable to write! need to enable txFIFO in the future
126128
}
127129

128130
int HardwareSerial::peek(void) {
@@ -144,59 +146,19 @@ int HardwareSerial::read(void) {
144146
}
145147

146148
void HardwareSerial::flush(void) {
147-
while (_tx_buffer->_iHead != _tx_buffer->_iTail)
148-
; // wait for transmit data to be sent
149-
150149
while (XMC_USIC_CH_GetTransmitBufferStatus(_XMC_UART_config->channel) ==
151150
XMC_USIC_CH_TBUF_STATUS_BUSY)
152151
;
153152
}
154153

155154
size_t HardwareSerial::write(const uint8_t uc_data) {
156-
// Is the hardware currently busy?
157-
#if defined(SERIAL_USE_U1C1)
158-
if (_tx_buffer->_iTail != _tx_buffer->_iHead)
159-
#else
160-
if ((XMC_USIC_CH_GetTransmitBufferStatus(_XMC_UART_config->channel) ==
161-
XMC_USIC_CH_TBUF_STATUS_BUSY) ||
162-
(_tx_buffer->_iTail != _tx_buffer->_iHead))
163-
#endif
164-
{
165-
// If busy we buffer
166-
int nextWrite = _tx_buffer->_iHead + 1;
167-
if (nextWrite >= SERIAL_BUFFER_SIZE)
168-
nextWrite = 0;
169-
170-
// This should always be false but in case transmission is completed before buffer, we need
171-
// to reenable IRQ
172-
if (XMC_USIC_CH_GetTransmitBufferStatus(_XMC_UART_config->channel) !=
173-
XMC_USIC_CH_TBUF_STATUS_BUSY) {
174-
XMC_UART_CH_EnableEvent(_XMC_UART_config->channel, XMC_UART_CH_EVENT_TRANSMIT_BUFFER);
175-
XMC_UART_CH_Transmit(_XMC_UART_config->channel,
176-
_tx_buffer->_aucBuffer[_tx_buffer->_iTail]);
177-
_tx_buffer->_iTail++;
178-
if (_tx_buffer->_iTail >= SERIAL_BUFFER_SIZE)
179-
_tx_buffer->_iTail %= SERIAL_BUFFER_SIZE; // If iTail is larger than Serial Buffer
180-
// Size calculate the correct index value
181-
}
182-
183-
unsigned long startTime = millis();
184-
while (_tx_buffer->_iTail == nextWrite) {
185-
if (millis() - startTime > 1000) {
186-
return 0; // Spin locks if we're about to overwrite the buffer. This continues once
187-
// the data is
188-
// sent
189-
}
190-
}
191-
192-
_tx_buffer->_aucBuffer[_tx_buffer->_iHead] = uc_data;
193-
_tx_buffer->_iHead = nextWrite;
194-
} else {
195-
// Make sure TX interrupt is enabled
196-
XMC_UART_CH_EnableEvent(_XMC_UART_config->channel, XMC_UART_CH_EVENT_TRANSMIT_BUFFER);
197-
// Bypass buffering and send character directly
198-
XMC_UART_CH_Transmit(_XMC_UART_config->channel, uc_data);
199-
}
155+
// Is the hardware currently busy?
156+
157+
// Make sure TX interrupt is enabled
158+
XMC_UART_CH_EnableEvent(_XMC_UART_config->channel, XMC_UART_CH_EVENT_TRANSMIT_BUFFER);
159+
// Bypass buffering and send character directly
160+
XMC_UART_CH_Transmit(_XMC_UART_config->channel, uc_data);
161+
200162
return 1;
201163
}
202164

@@ -220,20 +182,11 @@ void HardwareSerial::IrqHandler(void) {
220182
XMC_UART_CH_ClearStatusFlag(_XMC_UART_config->channel,
221183
XMC_UART_CH_STATUS_FLAG_TRANSMIT_BUFFER_INDICATION);
222184

223-
if (_tx_buffer->_iTail != _tx_buffer->_iHead) {
224-
XMC_UART_CH_Transmit(_XMC_UART_config->channel,
225-
_tx_buffer->_aucBuffer[_tx_buffer->_iTail]);
226-
_tx_buffer->_iTail++;
227-
if (_tx_buffer->_iTail >= SERIAL_BUFFER_SIZE)
228-
_tx_buffer->_iTail %= SERIAL_BUFFER_SIZE; // If iTail is larger than Serial Buffer
229-
// Size calculate the correct index value
230-
} else {
231-
// Mask off transmit interrupt so we don't get it any more
232-
XMC_UART_CH_DisableEvent(_XMC_UART_config->channel, XMC_UART_CH_EVENT_TRANSMIT_BUFFER);
233-
}
185+
// Mask off transmit interrupt so we don't get it any more
186+
XMC_UART_CH_DisableEvent(_XMC_UART_config->channel, XMC_UART_CH_EVENT_TRANSMIT_BUFFER);
234187
}
235188
}
236189

237190
//****************************************************************************
238191
// END OF FILE
239-
//****************************************************************************
192+
//****************************************************************************

0 commit comments

Comments
 (0)