status_t USART_TransferCreateHandleDMA(USART_Type *base, usart_dma_handle_t *handle, usart_dma_transfer_callback_t callback, void *userData, dma_handle_t *txDmaHandle, dma_handle_t *rxDmaHandle) { int32_t instance = 0; /* check 'base' */ assert(!(NULL == base)); if (NULL == base) { return kStatus_InvalidArgument; } /* check 'handle' */ assert(!(NULL == handle)); if (NULL == handle) { return kStatus_InvalidArgument; } instance = USART_GetInstance(base); memset(handle, 0, sizeof(*handle)); /* assign 'base' and 'handle' */ s_dmaPrivateHandle[instance].base = base; s_dmaPrivateHandle[instance].handle = handle; /* set tx/rx 'idle' state */ handle->rxState = kUSART_RxIdle; handle->txState = kUSART_TxIdle; handle->callback = callback; handle->userData = userData; handle->rxDmaHandle = rxDmaHandle; handle->txDmaHandle = txDmaHandle; /* Configure TX. */ if (txDmaHandle) { DMA_SetCallback(txDmaHandle, USART_TransferSendDMACallback, &s_dmaPrivateHandle[instance]); } /* Configure RX. */ if (rxDmaHandle) { DMA_SetCallback(rxDmaHandle, USART_TransferReceiveDMACallback, &s_dmaPrivateHandle[instance]); } return kStatus_Success; }
/** * Receive data on a UART interface * * @param[in] uart the UART interface * @param[out] data pointer to the buffer which will store incoming data * @param[in] expect_size number of bytes to receive * @param[out] recv_size number of bytes received * @param[in] timeout timeout in milisecond * * @return 0 : on success, EIO : if an error occurred with any step */ int32_t hal_uart_recv(uart_dev_t *uart, void *data, uint32_t expect_size, uint32_t *recv_size, uint32_t timeout) { USART_Type *base = (USART_Type *)s_uartBaseAddrs[uart->port]; uint8_t *data8 = (uint8_t *)data; uint32_t status; uint32_t count = 0; uint32_t instance = 0U; if(recv_size != NULL) *recv_size = 0; instance = USART_GetInstance(base); for (; expect_size > 0; expect_size--) { if (USART_IsRxFifoEnable(base)) { if((VFIFO->USART[instance].STATUSART & VFIFO_USART_STATUSART_RXEMPTY_MASK)) { return -EIO; } status = VFIFO->USART[instance].STATUSART; if (status & VFIFO_USART_STATUSART_BUSERR_MASK) { return -EIO; } status = VFIFO->USART[instance].RXDATSTATUSART; if (status & VFIFO_USART_RXDATSTATUSART_FRAMERR_MASK) { return -EIO; } if (status & VFIFO_USART_RXDATSTATUSART_PARITYERR_MASK) { return -EIO; } if (status & VFIFO_USART_RXDATSTATUSART_RXNOISE_MASK) { return -EIO; } *data8 = (status & VFIFO_USART_RXDATSTATUSART_RXDAT_MASK); } else { if (!(base->STAT & USART_STAT_RXRDY_MASK)) { return -EIO; } /* Check receive status */ status = base->STAT; if (status & USART_STAT_FRAMERRINT_MASK) { base->STAT |= USART_STAT_FRAMERRINT_MASK; return -EIO; } if (status & USART_STAT_PARITYERRINT_MASK) { base->STAT |= USART_STAT_PARITYERRINT_MASK; return -EIO; } if (status & USART_STAT_RXNOISEINT_MASK) { base->STAT |= USART_STAT_RXNOISEINT_MASK; return -EIO; } if (base->STAT & USART_STAT_OVERRUNINT_MASK) { base->STAT |= USART_STAT_OVERRUNINT_MASK; return -EIO; } *data8 = base->RXDAT; } data8++; count++; if(recv_size != NULL) *recv_size = count; } return 0; }