2424 * THE SOFTWARE.
2525 */
2626
27+ #if CIRCUITPY_BUSIO_UART
28+
2729#include "shared-bindings/microcontroller/__init__.h"
2830#include "shared-bindings/microcontroller/Pin.h"
2931#include "supervisor/shared/tick.h"
@@ -144,18 +146,21 @@ static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity)
144146 }
145147}
146148
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 ++ ) {
150154 if (uarts_active & (1 << i ) ) {
151155 MXC_UART_AsyncHandler (MXC_UART_GET_UART (i ));
152- uart_status [i ] = UART_FREE ;
153156 }
154157 }
155158}
156159
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 ;
159164}
160165
161166// Construct an underlying UART object.
@@ -256,17 +261,12 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
256261 // Indicate to this module that the UART is active
257262 uarts_active |= (1 << self -> uart_id );
258263
259- MXC_UART_ClearFlags (self -> uart_regs , self -> uart_regs -> int_fl );
260264
261265 /* Enable UART interrupt */
262266 NVIC_ClearPendingIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
263267 NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
264268 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 );
270270
271271 return ;
272272}
@@ -321,23 +321,30 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self,
321321
322322 bytes_remaining = len * 4 ;
323323
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 ));
333326
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 );
335339 if (err != E_NO_ERROR ) {
336340 * errcode = err ;
341+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
337342 return ((len * 4 ) - bytes_remaining );
338343 }
339- bytes_remaining -= uart_wr_req .rxLen ;
344+ bytes_remaining -= uart_rd_req .rxLen ;
340345 }
346+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
347+
341348 return len ;
342349}
343350
@@ -350,36 +357,49 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self,
350357 uint32_t start_time = 0 ;
351358 static size_t bytes_remaining ;
352359
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 ));
354364
355365 while (bytes_remaining > 0 ) {
356366 mxc_uart_req_t uart_wr_req ;
357367 uart_wr_req .rxCnt = 0 ;
358368 uart_wr_req .txCnt = 0 ;
359369 uart_wr_req .rxData = NULL ;
360370 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 ;
362372 uart_wr_req .rxLen = 0 ;
363373 uart_wr_req .uart = self -> uart_regs ;
374+ uart_wr_req .callback = (void * )uartCallback ;
364375
365376 uart_status [self -> uart_id ] = UART_BUSY ;
366377 start_time = supervisor_ticks_ms64 ();
367- err = MXC_UART_Transaction (& uart_wr_req );
378+ err = MXC_UART_TransactionAsync (& uart_wr_req );
368379 if (err != E_NO_ERROR ) {
369380 * 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" ));
371384 }
372385
373- // FIXME: NOT ENTERING ISR, NOT HANDLING TIMEOUT
374386 // 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 ))
378389 ) {};
379390
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 ;
381399 }
400+ NVIC_DisableIRQ (MXC_UART_GET_IRQ (self -> uart_id ));
382401 return len ;
402+
383403}
384404
385405 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)
438458 common_hal_never_reset_pin (self -> rts_pin );
439459 // uart_never_reset_mask |= ( 1 << (self->uart_id) );
440460}
461+
462+ #endif // CIRCUITPY_BUSIO_UART
0 commit comments