24
24
* THE SOFTWARE.
25
25
*/
26
26
27
+ #if CIRCUITPY_BUSIO_UART
28
+
27
29
#include "shared-bindings/microcontroller/__init__.h"
28
30
#include "shared-bindings/microcontroller/Pin.h"
29
31
#include "supervisor/shared/tick.h"
@@ -144,18 +146,21 @@ static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity)
144
146
}
145
147
}
146
148
147
- // FIXME: Find a better way of doing t his without a for loop
148
- void UartISR (void ) {
149
- for (int i = 0 ; i < NUM_UARTS ; i ++ ) {
149
+ // FIXME: Find a better way of doing this without a for loop
150
+ // FIXME: Fixed @ UART0 for TESTING BUGFIXES!!!
151
+ void UART0_IRQHandler (void ) {
152
+ // MXC_UART_AsyncHandler(MXC_UART_GET_UART(0));
153
+ for (int i = 0 ; i < NUM_UARTS ; i ++ ) {
150
154
if (uarts_active & (1 << i ) ) {
151
155
MXC_UART_AsyncHandler (MXC_UART_GET_UART (i ));
152
- uart_status [i ] = UART_FREE ;
153
156
}
154
157
}
155
158
}
156
159
157
- void uartCallback (mxc_uart_req_t * req , int error ) {
158
-
160
+ // Callback gets called when AsyncRequest is COMPLETE
161
+ // (e.g. txLen == txCnt)
162
+ static volatile void uartCallback (mxc_uart_req_t * req , int error ) {
163
+ uart_status [MXC_UART_GET_IDX (req -> uart )] = UART_FREE ;
159
164
}
160
165
161
166
// Construct an underlying UART object.
@@ -256,17 +261,12 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
256
261
// Indicate to this module that the UART is active
257
262
uarts_active |= (1 << self -> uart_id );
258
263
259
- MXC_UART_ClearFlags (self -> uart_regs , self -> uart_regs -> int_fl );
260
264
261
265
/* Enable UART interrupt */
262
266
NVIC_ClearPendingIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
263
267
NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
264
268
NVIC_SetPriority (MXC_UART_GET_IRQ (self -> uart_id ), UART_PRIORITY );
265
- NVIC_SetVector (MXC_UART_GET_IRQ (self -> uart_id ), (uint32_t )UartISR );
266
-
267
- // FIXME: UART ISRs are NOT WORKING!
268
- // MXC_UART_EnableInt(self->uart_regs, ???)
269
- // NVIC_EnableIRQ(MXC_UART_GET_IRQ(self->uart_id));
269
+ NVIC_SetVector (MXC_UART_GET_IRQ (self -> uart_id ), (uint32_t )& UART0_IRQHandler );
270
270
271
271
return ;
272
272
}
@@ -321,23 +321,30 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self,
321
321
322
322
bytes_remaining = len * 4 ;
323
323
324
- while (bytes_remaining > 0 ) {
325
- mxc_uart_req_t uart_wr_req ;
326
- uart_wr_req .rxCnt = 0 ;
327
- uart_wr_req .txCnt = 0 ;
328
- uart_wr_req .rxData = data ;
329
- uart_wr_req .txData = NULL ;
330
- uart_wr_req .rxLen = (uint32_t )( (bytes_remaining >= 255 ) ? 255 : bytes_remaining );
331
- uart_wr_req .txLen = 0 ;
332
- uart_wr_req .uart = self -> uart_regs ;
324
+ MXC_UART_ClearFlags (self -> uart_regs , 0xFFFFFFFF );
325
+ NVIC_EnableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
333
326
334
- err = MXC_UART_Transaction (& uart_wr_req );
327
+ while (bytes_remaining > 0 ) {
328
+ mxc_uart_req_t uart_rd_req ;
329
+ uart_rd_req .rxCnt = 0 ;
330
+ uart_rd_req .txCnt = 0 ;
331
+ uart_rd_req .rxData = data ;
332
+ uart_rd_req .txData = NULL ;
333
+ uart_rd_req .rxLen = (uint32_t )( (bytes_remaining >= 255 ) ? 255 : bytes_remaining );
334
+ uart_rd_req .txLen = 0 ;
335
+ uart_rd_req .uart = self -> uart_regs ;
336
+ uart_rd_req .callback = (void * )uartCallback ;
337
+
338
+ err = MXC_UART_TransactionAsync (& uart_rd_req );
335
339
if (err != E_NO_ERROR ) {
336
340
* errcode = err ;
341
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
337
342
return ((len * 4 ) - bytes_remaining );
338
343
}
339
- bytes_remaining -= uart_wr_req .rxLen ;
344
+ bytes_remaining -= uart_rd_req .rxLen ;
340
345
}
346
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
347
+
341
348
return len ;
342
349
}
343
350
@@ -350,36 +357,49 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self,
350
357
uint32_t start_time = 0 ;
351
358
static size_t bytes_remaining ;
352
359
353
- bytes_remaining = len * 4 ;
360
+ bytes_remaining = len ;
361
+
362
+ MXC_UART_ClearFlags (self -> uart_regs , 0xFFFFFFFF );
363
+ NVIC_EnableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
354
364
355
365
while (bytes_remaining > 0 ) {
356
366
mxc_uart_req_t uart_wr_req ;
357
367
uart_wr_req .rxCnt = 0 ;
358
368
uart_wr_req .txCnt = 0 ;
359
369
uart_wr_req .rxData = NULL ;
360
370
uart_wr_req .txData = data ;
361
- uart_wr_req .txLen = ( uint32_t )( ( bytes_remaining >= 255 ) ? 255 : bytes_remaining ) ;
371
+ uart_wr_req .txLen = bytes_remaining ;
362
372
uart_wr_req .rxLen = 0 ;
363
373
uart_wr_req .uart = self -> uart_regs ;
374
+ uart_wr_req .callback = (void * )uartCallback ;
364
375
365
376
uart_status [self -> uart_id ] = UART_BUSY ;
366
377
start_time = supervisor_ticks_ms64 ();
367
- err = MXC_UART_Transaction (& uart_wr_req );
378
+ err = MXC_UART_TransactionAsync (& uart_wr_req );
368
379
if (err != E_NO_ERROR ) {
369
380
* errcode = err ;
370
- return ((len * 4 ) - bytes_remaining );
381
+ MXC_UART_AbortAsync (self -> uart_regs );
382
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
383
+ mp_raise_ConnectionError (MP_ERROR_TEXT ("\nERR: Requested bus is busy\n" ));
371
384
}
372
385
373
- // FIXME: NOT ENTERING ISR, NOT HANDLING TIMEOUT
374
386
// Wait for transaction completion
375
- // FIXME: Test timeout & status flags
376
- while ( (supervisor_ticks_ms64 () - start_time < 500 )
377
- && (uart_status [self -> uart_id ] != UART_FREE )
387
+ while ( (uart_status [self -> uart_id ] != UART_FREE ) &&
388
+ (supervisor_ticks_ms64 () - start_time < (self -> timeout * 1000 ))
378
389
) {};
379
390
380
- bytes_remaining -= uart_wr_req .txLen ;
391
+ // If the timeout gets hit, abort and error out
392
+ if (uart_status [self -> uart_id ] != UART_FREE ) {
393
+ MXC_UART_AbortAsync (self -> uart_regs );
394
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
395
+ mp_raise_ConnectionError (MP_ERROR_TEXT ("\nERR: Uart transaction timed out.\n" ));
396
+ }
397
+
398
+ bytes_remaining -= uart_wr_req .txCnt ;
381
399
}
400
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
382
401
return len ;
402
+
383
403
}
384
404
385
405
uint32_t common_hal_busio_uart_get_baudrate (busio_uart_obj_t * self )
@@ -438,3 +458,5 @@ void common_hal_busio_uart_never_reset(busio_uart_obj_t *self)
438
458
common_hal_never_reset_pin (self -> rts_pin );
439
459
// uart_never_reset_mask |= ( 1 << (self->uart_id) );
440
460
}
461
+
462
+ #endif // CIRCUITPY_BUSIO_UART
0 commit comments