14
14
You should have received a copy of the GNU Lesser General Public
15
15
License along with this library; if not, write to the Free Software
16
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ Modified 23 November 2019 by Georg Icking-Konert
17
19
*/
18
20
19
21
#include < stdlib.h>
20
22
#include < stdio.h>
21
23
#include < string.h>
22
24
#include " UARTClass.h"
25
+ #include " Arduino.h"
23
26
24
27
// Constructors ////////////////////////////////////////////////////////////////
25
28
@@ -31,6 +34,9 @@ UARTClass::UARTClass( Uart *pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer *p
31
34
_pUart=pUart;
32
35
_dwIrq=dwIrq;
33
36
_dwId=dwId;
37
+
38
+ _isrRx = NULL ;
39
+ _isrTx = NULL ;
34
40
}
35
41
36
42
// Public Methods //////////////////////////////////////////////////////////////
@@ -162,17 +168,58 @@ size_t UARTClass::write( const uint8_t uc_data )
162
168
{
163
169
// Bypass buffering and send character directly
164
170
_pUart->UART_THR = uc_data;
171
+
172
+ // if custom routine attached, activate TXBUFE interrupt -> delay call until transmission finished
173
+ // must be done here explicitely because UART_TXRDY interrupt is not activated here
174
+ if (_isrTx != NULL ) {
175
+ _pUart->UART_IER = UART_IER_TXEMPTY;
176
+ }
165
177
}
178
+
166
179
return 1 ;
167
180
}
168
181
182
+ void UARTClass::attachInterrupt_Receive ( isrRx_t fn )
183
+ {
184
+ // pause interrupts
185
+ uint8_t oldISR = ((__get_PRIMASK () & 0x1 ) == 0 && (__get_FAULTMASK () & 0x1 ) == 0 ); noInterrupts ();
186
+
187
+ // set custom function
188
+ _isrRx = fn;
189
+
190
+ // restore old interrupt setting
191
+ if (oldISR != 0 ) { interrupts (); }
192
+ }
193
+
194
+ void UARTClass::attachInterrupt_Send ( isrTx_t fn )
195
+ {
196
+ // pause interrupts
197
+ uint8_t oldISR = ((__get_PRIMASK () & 0x1 ) == 0 && (__get_FAULTMASK () & 0x1 ) == 0 ); noInterrupts ();
198
+
199
+ // set custom function for TX empty
200
+ _isrTx = fn;
201
+
202
+ // restore old interrupt setting
203
+ if (oldISR != 0 ) { interrupts (); }
204
+ }
205
+
169
206
void UARTClass::IrqHandler ( void )
170
207
{
171
208
uint32_t status = _pUart->UART_SR ;
172
209
173
210
// Did we receive data?
174
- if ((status & UART_SR_RXRDY) == UART_SR_RXRDY)
175
- _rx_buffer->store_char (_pUart->UART_RHR );
211
+ if ((status & UART_SR_RXRDY) == UART_SR_RXRDY) {
212
+
213
+ // custom function was attached -> call it with data and status byte
214
+ if (_isrRx) {
215
+ _isrRx (_pUart->UART_RHR , status);
216
+ }
217
+ // no custom function attached -> store data in ring buffer
218
+ else {
219
+ _rx_buffer->store_char (_pUart->UART_RHR );
220
+ }
221
+
222
+ }
176
223
177
224
// Do we need to keep sending data?
178
225
if ((status & UART_SR_TXRDY) == UART_SR_TXRDY)
@@ -185,11 +232,29 @@ void UARTClass::IrqHandler( void )
185
232
{
186
233
// Mask off transmit interrupt so we don't get it anymore
187
234
_pUart->UART_IDR = UART_IDR_TXRDY;
235
+
236
+ // if custom routine attached, activate TXBUFE interrupt -> delay call until transmission finished
237
+ if (_isrTx != NULL ) {
238
+ _pUart->UART_IER = UART_IER_TXEMPTY;
239
+ }
240
+ }
241
+
242
+ }
243
+
244
+ // Is data transmission finished? Used for call of attached custom function at end of transmission?
245
+ if ((status & UART_SR_TXEMPTY) == UART_SR_TXEMPTY)
246
+ {
247
+ // Mask off interrupt so we don't get it anymore
248
+ _pUart->UART_IDR = UART_IDR_TXEMPTY;
249
+
250
+ // if custom routine attached, call it
251
+ if (_isrTx != NULL ) {
252
+ _isrTx ();
188
253
}
189
254
}
190
255
191
256
// Acknowledge errors
192
- if ((status & UART_SR_OVRE) == UART_SR_OVRE || (status & UART_SR_FRAME) == UART_SR_FRAME)
257
+ if ((status & UART_SR_OVRE) == UART_SR_OVRE || (status & UART_SR_FRAME) == UART_SR_FRAME || (status & UART_SR_RXBRK) == UART_SR_RXBRK )
193
258
{
194
259
// TODO: error reporting outside ISR
195
260
_pUart->UART_CR |= UART_CR_RSTSTA;
0 commit comments