/** * @brief Receives data from the SPI bus. * @details This asynchronous function starts a receive operation. * @post At the end of the operation the configured callback is invoked. * @note The buffers are organized as uint8_t arrays for data sizes below or * equal to 8 bits else it is organized as uint16_t arrays. * * @param[in] spip pointer to the @p SPIDriver object * @param[in] n number of words to receive * @param[out] rxbuf the pointer to the receive buffer * * @notapi */ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { tiva_udma_table_entry_t *primary = udmaControlTable.primary; if ((spip->config->cr0 & TIVA_CR0_DSS_MASK) < 8) { /* Configure for 8-bit transfers.*/ primary[spip->dmatxnr].srcendp = (volatile void *)&dummytx; primary[spip->dmatxnr].dstendp = &spip->ssi->DR; primary[spip->dmatxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_0 | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_0 | UDMA_CHCTL_ARBSIZE_4 | UDMA_CHCTL_XFERSIZE(n) | UDMA_CHCTL_XFERMODE_BASIC; primary[spip->dmarxnr].srcendp = &spip->ssi->DR; primary[spip->dmarxnr].dstendp = rxbuf+n-1; primary[spip->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_8 | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_0 | UDMA_CHCTL_ARBSIZE_4 | UDMA_CHCTL_XFERSIZE(n) | UDMA_CHCTL_XFERMODE_BASIC; } else { /* Configure for 16-bit transfers.*/ primary[spip->dmatxnr].srcendp = (volatile void *)&dummytx; primary[spip->dmatxnr].dstendp = &spip->ssi->DR; primary[spip->dmatxnr].chctl = UDMA_CHCTL_DSTSIZE_16 | UDMA_CHCTL_DSTINC_0 | UDMA_CHCTL_SRCSIZE_16 | UDMA_CHCTL_SRCINC_0 | UDMA_CHCTL_ARBSIZE_4 | UDMA_CHCTL_XFERSIZE(n) | UDMA_CHCTL_XFERMODE_BASIC; primary[spip->dmarxnr].srcendp = &spip->ssi->DR; primary[spip->dmarxnr].dstendp = rxbuf+(n*2)-1; primary[spip->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_16 | UDMA_CHCTL_DSTINC_16 | UDMA_CHCTL_SRCSIZE_16 | UDMA_CHCTL_SRCINC_0 | UDMA_CHCTL_ARBSIZE_4 | UDMA_CHCTL_XFERSIZE(n) | UDMA_CHCTL_XFERMODE_BASIC; } dmaChannelSingleBurst(spip->dmatxnr); dmaChannelPrimary(spip->dmatxnr); dmaChannelPriorityDefault(spip->dmatxnr); dmaChannelEnableRequest(spip->dmatxnr); dmaChannelSingleBurst(spip->dmarxnr); dmaChannelPrimary(spip->dmarxnr); dmaChannelPriorityDefault(spip->dmarxnr); dmaChannelEnableRequest(spip->dmarxnr); /* Enable DMA channels, when the TX channel is enabled the transfer starts.*/ dmaChannelEnable(spip->dmarxnr); dmaChannelEnable(spip->dmatxnr); }
/** * @brief Starts a receive operation on the UART peripheral. * @note The buffers are organized as uint8_t arrays for data sizes below * or equal to 8 bits else it is organized as uint16_t arrays. * * @param[in] uartp pointer to the @p UARTDriver object * @param[in] n number of data frames to send * @param[out] rxbuf the pointer to the receive buffer * * @notapi */ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { tiva_udma_table_entry_t *primary = udmaControlTable.primary; /* TODO: This assert should be moved to the dma helper driver */ osalDbgAssert((uint32_t)rxbuf >= SRAM_BASE, "rxbuf should be in SRAM region."); dmaChannelDisable(uartp->dmarxnr); /* Configure for 8-bit transfers.*/ primary[uartp->dmarxnr].srcendp = (void *)(uartp->uart + UART_O_DR); primary[uartp->dmarxnr].dstendp = (volatile void *)rxbuf+n-1; primary[uartp->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_8 | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_NONE | UDMA_CHCTL_ARBSIZE_4 | UDMA_CHCTL_XFERSIZE(n) | UDMA_CHCTL_XFERMODE_BASIC; dmaChannelSingleBurst(uartp->dmarxnr); dmaChannelPrimary(uartp->dmarxnr); dmaChannelPriorityDefault(uartp->dmarxnr); dmaChannelEnableRequest(uartp->dmarxnr); /* Enable DMA channel, transfer starts immediately.*/ dmaChannelEnable(uartp->dmarxnr); }
/** * @brief Sends data over the SPI bus. * @details This asynchronous function starts a transmit operation. * @post At the end of the operation the configured callback is invoked. * @note The buffers are organized as uint8_t arrays for data sizes below or * equal to 8 bits else it is organized as uint16_t arrays. * * @param[in] spip pointer to the @p SPIDriver object * @param[in] n number of words to send * @param[in] txbuf the pointer to the transmit buffer * * @notapi */ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { osalDbgAssert(n > XDMAC_MAX_BT_SIZE, "unsupported DMA transfer size"); /* Writing channel */ dmaChannelSetSource(spip->dmatx, txbuf); dmaChannelSetDestination(spip->dmatx, &spip->spi->SPI_TDR); dmaChannelSetTransactionSize(spip->dmatx, n); dmaChannelSetMode(spip->dmatx, spip->txdmamode); /* Reading channel */ dmaChannelSetSource(spip->dmarx, &spip->spi->SPI_RDR); dmaChannelSetDestination(spip->dmarx, &dummyrx); dmaChannelSetTransactionSize(spip->dmarx, n); dmaChannelSetMode(spip->dmarx, spip->rxdmamode); dmaChannelEnable(spip->dmarx); dmaChannelEnable(spip->dmatx); }
/** * @brief Puts the receiver in the UART_RX_IDLE state. * * @param[in] uartp pointer to the @p UARTDriver object */ static void uart_enter_rx_idle_loop(UARTDriver *uartp) { tiva_udma_table_entry_t *primary = udmaControlTable.primary; dmaChannelDisable(uartp->dmarxnr); /* Configure for 8-bit transfers.*/ primary[uartp->dmarxnr].srcendp = (void *)(uartp->uart + UART_O_DR); primary[uartp->dmarxnr].dstendp = (volatile void *)&uartp->rxbuf; primary[uartp->dmarxnr].chctl = UDMA_CHCTL_DSTSIZE_8 | UDMA_CHCTL_DSTINC_8 | UDMA_CHCTL_SRCSIZE_8 | UDMA_CHCTL_SRCINC_NONE | UDMA_CHCTL_ARBSIZE_4 | UDMA_CHCTL_XFERSIZE(1) | UDMA_CHCTL_XFERMODE_BASIC; dmaChannelSingleBurst(uartp->dmarxnr); dmaChannelPrimary(uartp->dmarxnr); dmaChannelPriorityDefault(uartp->dmarxnr); dmaChannelEnableRequest(uartp->dmarxnr); /* Enable DMA channel, transfer starts immediately.*/ dmaChannelEnable(uartp->dmarxnr); }