@@ -95,6 +95,7 @@ static uint32_t timeout_ms=0;
9595// will be checked by ISR Handler for which ones to call
9696static uint8_t uarts_active = 0 ;
9797static uart_status_t uart_status [NUM_UARTS ];
98+ static volatile int uart_err ;
9899// static uint8_t uart_never_reset_mask = 0;
99100
100101static int isValidBaudrate (uint32_t baudrate ) {
@@ -146,12 +147,9 @@ static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity)
146147 }
147148}
148149
149- // FIXME: Find a better way of doing this without a for loop
150- // FIXME: Fixed @ UART0 for TESTING BUGFIXES!!!
151150void 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 )) {
155153 MXC_UART_AsyncHandler (MXC_UART_GET_UART (i ));
156154 }
157155 }
@@ -161,6 +159,7 @@ void UART0_IRQHandler(void) {
161159// (e.g. txLen == txCnt)
162160static volatile void uartCallback (mxc_uart_req_t * req , int error ) {
163161 uart_status [MXC_UART_GET_IDX (req -> uart )] = UART_FREE ;
162+ uart_err = error ;
164163}
165164
166165// Construct an underlying UART object.
@@ -262,7 +261,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
262261 uarts_active |= (1 << self -> uart_id );
263262
264263
265- /* Enable UART interrupt */
264+ /* Setup UART interrupt */
266265 NVIC_ClearPendingIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
267266 NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
268267 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)
311310 };
312311}
313312
314- // todo: test
315313// Read characters. len is in characters NOT bytes!
316314size_t common_hal_busio_uart_read (busio_uart_obj_t * self ,
317315 uint8_t * data , size_t len , int * errcode )
318316{
319317 int err ;
318+ uint32_t start_time = 0 ;
320319 static size_t bytes_remaining ;
321320
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 ;
323326
324- MXC_UART_ClearFlags (self -> uart_regs , 0xFFFFFFFF );
325327 NVIC_EnableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
326328
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 ) ;
345347 }
346- NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
347348
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 ));
348369 return len ;
349370}
350371
351- //todo: test
352372// Write characters. len is in characters NOT bytes!
373+ // This function blocks until the timeout finishes
353374 size_t common_hal_busio_uart_write (busio_uart_obj_t * self ,
354375 const uint8_t * data , size_t len , int * errcode )
355376{
356377 int err ;
357378 uint32_t start_time = 0 ;
358379 static size_t bytes_remaining ;
359380
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 ;
360385 bytes_remaining = len ;
361386
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+ }
385408
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 ))) {
390412
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 );
396419 }
420+ }
397421
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" ));
399427 }
400- NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
401- return len ;
402428
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 ;
403437}
404438
405439 uint32_t common_hal_busio_uart_get_baudrate (busio_uart_obj_t * self )
0 commit comments