@@ -95,6 +95,7 @@ static uint32_t timeout_ms=0;
95
95
// will be checked by ISR Handler for which ones to call
96
96
static uint8_t uarts_active = 0 ;
97
97
static uart_status_t uart_status [NUM_UARTS ];
98
+ static volatile int uart_err ;
98
99
// static uint8_t uart_never_reset_mask = 0;
99
100
100
101
static int isValidBaudrate (uint32_t baudrate ) {
@@ -146,12 +147,9 @@ static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity)
146
147
}
147
148
}
148
149
149
- // FIXME: Find a better way of doing this without a for loop
150
- // FIXME: Fixed @ UART0 for TESTING BUGFIXES!!!
151
150
void UART0_IRQHandler (void ) {
152
- // MXC_UART_AsyncHandler(MXC_UART_GET_UART(0));
153
- for (int i = 0 ; i < NUM_UARTS ; i ++ ) {
154
- if (uarts_active & (1 << i ) ) {
151
+ for (int i = 0 ; i < NUM_UARTS ; i ++ ) {
152
+ if (uarts_active & (1 << i )) {
155
153
MXC_UART_AsyncHandler (MXC_UART_GET_UART (i ));
156
154
}
157
155
}
@@ -161,6 +159,7 @@ void UART0_IRQHandler(void) {
161
159
// (e.g. txLen == txCnt)
162
160
static volatile void uartCallback (mxc_uart_req_t * req , int error ) {
163
161
uart_status [MXC_UART_GET_IDX (req -> uart )] = UART_FREE ;
162
+ uart_err = error ;
164
163
}
165
164
166
165
// Construct an underlying UART object.
@@ -262,7 +261,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
262
261
uarts_active |= (1 << self -> uart_id );
263
262
264
263
265
- /* Enable UART interrupt */
264
+ /* Setup UART interrupt */
266
265
NVIC_ClearPendingIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
267
266
NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
268
267
NVIC_SetPriority (MXC_UART_GET_IRQ (self -> uart_id ), UART_PRIORITY );
@@ -311,95 +310,130 @@ bool common_hal_busio_uart_deinited(busio_uart_obj_t *self)
311
310
};
312
311
}
313
312
314
- // todo: test
315
313
// Read characters. len is in characters NOT bytes!
316
314
size_t common_hal_busio_uart_read (busio_uart_obj_t * self ,
317
315
uint8_t * data , size_t len , int * errcode )
318
316
{
319
317
int err ;
318
+ uint32_t start_time = 0 ;
320
319
static size_t bytes_remaining ;
321
320
322
- bytes_remaining = len * 4 ;
321
+ // Setup globals & status tracking
322
+ uart_err = E_NO_ERROR ;
323
+ uarts_active |= (1 << self -> uart_id );
324
+ uart_status [self -> uart_id ] = UART_BUSY ;
325
+ bytes_remaining = len ;
323
326
324
- MXC_UART_ClearFlags (self -> uart_regs , 0xFFFFFFFF );
325
327
NVIC_EnableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
326
328
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 );
339
- if ( err != E_NO_ERROR ) {
340
- * errcode = err ;
341
- NVIC_DisableIRQ ( MXC_UART_GET_IRQ ( self -> uart_id )) ;
342
- return (( len * 4 ) - bytes_remaining );
343
- }
344
- bytes_remaining -= uart_rd_req . rxLen ;
329
+ mxc_uart_req_t uart_rd_req ;
330
+ uart_rd_req . rxCnt = 0 ;
331
+ uart_rd_req .txCnt = 0 ;
332
+ uart_rd_req .rxData = data ;
333
+ uart_rd_req .txData = NULL ;
334
+ uart_rd_req .rxLen = bytes_remaining ;
335
+ uart_rd_req .txLen = 0 ;
336
+ uart_rd_req .uart = self -> uart_regs ;
337
+ uart_rd_req .callback = ( void * ) uartCallback ;
338
+
339
+ // Initiate the read transaction
340
+ start_time = supervisor_ticks_ms64 ( );
341
+ err = MXC_UART_TransactionAsync ( & uart_rd_req );
342
+ if ( err != E_NO_ERROR ) {
343
+ * errcode = err ;
344
+ MXC_UART_AbortAsync ( self -> uart_regs );
345
+ NVIC_DisableIRQ ( MXC_UART_GET_IRQ ( self -> uart_id ));
346
+ mp_raise_RuntimeError_varg ( MP_ERROR_TEXT ( "\nERR: Error starting trasaction: %d\n" ), err ) ;
345
347
}
346
- NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
347
348
349
+ // Wait for transaction completion or timeout
350
+ while ( (uart_status [self -> uart_id ] != UART_FREE ) &&
351
+ (supervisor_ticks_ms64 () - start_time < (self -> timeout * 1000 ))) {
352
+ }
353
+
354
+ // If the timeout gets hit, abort and error out
355
+ if (uart_status [self -> uart_id ] != UART_FREE ) {
356
+ MXC_UART_AbortAsync (self -> uart_regs );
357
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
358
+ mp_raise_RuntimeError (MP_ERROR_TEXT ("\nERR: Uart transaction timed out.\n" ));
359
+ }
360
+
361
+ // Check for errors from the callback
362
+ else if (uart_err != E_NO_ERROR ) {
363
+ MXC_UART_AbortAsync (self -> uart_regs );
364
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
365
+ mp_raise_RuntimeError_varg (MP_ERROR_TEXT ("MAX32 ERR: %d\n" ), uart_err );
366
+ }
367
+
368
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
348
369
return len ;
349
370
}
350
371
351
- //todo: test
352
372
// Write characters. len is in characters NOT bytes!
373
+ // This function blocks until the timeout finishes
353
374
size_t common_hal_busio_uart_write (busio_uart_obj_t * self ,
354
375
const uint8_t * data , size_t len , int * errcode )
355
376
{
356
377
int err ;
357
378
uint32_t start_time = 0 ;
358
379
static size_t bytes_remaining ;
359
380
381
+ // Setup globals & status tracking
382
+ uart_err = E_NO_ERROR ;
383
+ uarts_active |= (1 << self -> uart_id );
384
+ uart_status [self -> uart_id ] = UART_BUSY ;
360
385
bytes_remaining = len ;
361
386
362
- MXC_UART_ClearFlags (self -> uart_regs , 0xFFFFFFFF );
363
- NVIC_EnableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
364
-
365
- while (bytes_remaining > 0 ) {
366
- mxc_uart_req_t uart_wr_req ;
367
- uart_wr_req .rxCnt = 0 ;
368
- uart_wr_req .txCnt = 0 ;
369
- uart_wr_req .rxData = NULL ;
370
- uart_wr_req .txData = data ;
371
- uart_wr_req .txLen = bytes_remaining ;
372
- uart_wr_req .rxLen = 0 ;
373
- uart_wr_req .uart = self -> uart_regs ;
374
- uart_wr_req .callback = (void * )uartCallback ;
375
-
376
- uart_status [self -> uart_id ] = UART_BUSY ;
377
- start_time = supervisor_ticks_ms64 ();
378
- err = MXC_UART_TransactionAsync (& uart_wr_req );
379
- if (err != E_NO_ERROR ) {
380
- * errcode = err ;
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" ));
384
- }
387
+ mxc_uart_req_t uart_wr_req = {};
388
+
389
+ // Setup transaction
390
+ uart_wr_req .rxCnt = 0 ;
391
+ uart_wr_req .txCnt = 0 ;
392
+ uart_wr_req .rxData = NULL ;
393
+ uart_wr_req .txData = data ;
394
+ uart_wr_req .txLen = bytes_remaining ;
395
+ uart_wr_req .rxLen = 0 ;
396
+ uart_wr_req .uart = self -> uart_regs ;
397
+ uart_wr_req .callback = (void * )uartCallback ;
398
+
399
+ // Start the transaction
400
+ start_time = supervisor_ticks_ms64 ();
401
+ err = MXC_UART_TransactionAsync (& uart_wr_req );
402
+ if (err != E_NO_ERROR ) {
403
+ * errcode = err ;
404
+ MXC_UART_AbortAsync (self -> uart_regs );
405
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
406
+ mp_raise_ConnectionError (MP_ERROR_TEXT ("\nERR: Requested bus is busy\n" ));
407
+ }
385
408
386
- // Wait for transaction completion
387
- while ( (uart_status [self -> uart_id ] != UART_FREE ) &&
388
- (supervisor_ticks_ms64 () - start_time < (self -> timeout * 1000 ))
389
- ) {};
409
+ // Wait for transaction completion or timeout
410
+ while ( (uart_status [self -> uart_id ] != UART_FREE ) &&
411
+ (supervisor_ticks_ms64 () - start_time < (self -> timeout * 1000 ))) {
390
412
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" ));
413
+ // Call the handler and abort if errors
414
+ uart_err = MXC_UART_AsyncHandler (MXC_UART_GET_UART (0 ));
415
+ if (uart_err != E_NO_ERROR ) {
416
+ MXC_UART_AbortAsync (MXC_UART_GET_UART (0 ));
417
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (0 ));
418
+ mp_raise_RuntimeError_varg (MP_ERROR_TEXT ("MAX32 ERR: %d\n" ), uart_err );
396
419
}
420
+ }
397
421
398
- bytes_remaining -= uart_wr_req .txCnt ;
422
+ // If the timeout gets hit, abort and error out
423
+ if (uart_status [self -> uart_id ] != UART_FREE ) {
424
+ MXC_UART_AbortAsync (self -> uart_regs );
425
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
426
+ mp_raise_ConnectionError (MP_ERROR_TEXT ("\nERR: Uart transaction timed out.\n" ));
399
427
}
400
- NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
401
- return len ;
402
428
429
+ // Check for errors from the callback
430
+ else if (uart_err != E_NO_ERROR ) {
431
+ MXC_UART_AbortAsync (self -> uart_regs );
432
+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
433
+ mp_raise_RuntimeError_varg (MP_ERROR_TEXT ("MAX32 ERR: %d\n" ), uart_err );
434
+ }
435
+
436
+ return len ;
403
437
}
404
438
405
439
uint32_t common_hal_busio_uart_get_baudrate (busio_uart_obj_t * self )
0 commit comments