Skip to content

Commit 3370978

Browse files
committed
Merge branch 'buffer-serial-tx'
2 parents 08de7f1 + 46653a6 commit 3370978

File tree

6 files changed

+46
-2
lines changed

6 files changed

+46
-2
lines changed

cores/arduino/RingBuffer.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ int RingBuffer::available()
6767
return delta;
6868
}
6969

70+
int RingBuffer::availableForStore()
71+
{
72+
if (_iHead >= _iTail)
73+
return SERIAL_BUFFER_SIZE - 1 - _iHead + _iTail;
74+
else
75+
return _iTail - _iHead - 1;
76+
}
77+
7078
int RingBuffer::peek()
7179
{
7280
if(_iTail == _iHead)

cores/arduino/RingBuffer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class RingBuffer
4040
void clear();
4141
int read_char();
4242
int available();
43+
int availableForStore();
4344
int peek();
4445
bool isFull();
4546

cores/arduino/SERCOM.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,16 @@ int SERCOM::writeDataUART(uint8_t data)
173173
return 1;
174174
}
175175

176+
void SERCOM::enableDataRegisterEmptyInterruptUART()
177+
{
178+
sercom->USART.INTENSET.reg |= SERCOM_USART_INTENSET_DRE;
179+
}
180+
181+
void SERCOM::disableDataRegisterEmptyInterruptUART()
182+
{
183+
sercom->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE;
184+
}
185+
176186
/* =========================
177187
* ===== Sercom SPI
178188
* =========================

cores/arduino/SERCOM.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ class SERCOM
163163
int writeDataUART(uint8_t data) ;
164164
bool isUARTError() ;
165165
void acknowledgeUARTError() ;
166+
void enableDataRegisterEmptyInterruptUART();
167+
void disableDataRegisterEmptyInterruptUART();
166168

167169
/* ========== SPI ========== */
168170
void initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder) ;

cores/arduino/Uart.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,13 @@ void Uart::end()
5050
{
5151
sercom->resetUART();
5252
rxBuffer.clear();
53+
txBuffer.clear();
5354
}
5455

5556
void Uart::flush()
5657
{
58+
while(txBuffer.available()); // wait until TX buffer is empty
59+
5760
sercom->flushUART();
5861
}
5962

@@ -63,6 +66,16 @@ void Uart::IrqHandler()
6366
rxBuffer.store_char(sercom->readDataUART());
6467
}
6568

69+
if (sercom->isDataRegisterEmptyUART()) {
70+
if (txBuffer.available()) {
71+
uint8_t data = txBuffer.read_char();
72+
73+
sercom->writeDataUART(data);
74+
} else {
75+
sercom->disableDataRegisterEmptyInterruptUART();
76+
}
77+
}
78+
6679
if (sercom->isUARTError()) {
6780
sercom->acknowledgeUARTError();
6881
// TODO: if (sercom->isBufferOverflowErrorUART()) ....
@@ -79,7 +92,7 @@ int Uart::available()
7992

8093
int Uart::availableForWrite()
8194
{
82-
return (sercom->isDataRegisterEmptyUART() ? 1 : 0);
95+
return txBuffer.availableForStore();
8396
}
8497

8598
int Uart::peek()
@@ -94,7 +107,16 @@ int Uart::read()
94107

95108
size_t Uart::write(const uint8_t data)
96109
{
97-
sercom->writeDataUART(data);
110+
if (sercom->isDataRegisterEmptyUART() && txBuffer.available() == 0) {
111+
sercom->writeDataUART(data);
112+
} else {
113+
while(txBuffer.isFull()); // spin lock until a spot opens up in the buffer
114+
115+
txBuffer.store_char(data);
116+
117+
sercom->enableDataRegisterEmptyInterruptUART();
118+
}
119+
98120
return 1;
99121
}
100122

cores/arduino/Uart.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class Uart : public HardwareSerial
4646
private:
4747
SERCOM *sercom;
4848
RingBuffer rxBuffer;
49+
RingBuffer txBuffer;
4950

5051
uint8_t uc_pinRX;
5152
uint8_t uc_pinTX;

0 commit comments

Comments
 (0)