Example #1
0
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _kuart_prepare_rx_mix
* Returned Value   : void
* Comments         :
*    Configure and enable rx mix tansmit.
*
*END*----------------------------------------------------------------------*/
static void _kuart_prepare_rx_dma(IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr)
{
    DMA_TCD						tcd;
    KUART_INFO_STRUCT_PTR                  sci_info_ptr;
    UART_MemMapPtr                         sci_ptr;

    sci_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
    sci_ptr = sci_info_ptr->SCI_PTR;
    dma_tcd_reg2mem(&tcd, &(sci_ptr->D) , 1, sci_info_ptr->RX_BUF, int_io_dev_ptr->IQUEUE_SIZE);
    dma_transfer_submit(sci_info_ptr->RX_DCH, &tcd, &sci_info_ptr->RX_DMA_SEQ);
    dma_request_enable(sci_info_ptr->RX_DCH);
}
/*FUNCTION****************************************************************
*
* Function Name    : _dspi_dma_transfer
* Returned Value   : number of bytes transferred
* Comments         :
*   Internal routine performing actual DMA transfer of given width
*   If txbuf is NULL the function expects dummy pattern already prepared in dspi_info_ptr->TX_BUFFER
*
*END*********************************************************************/
static _mqx_int _dspi_dma_transfer
    (
        /* [IN] Device specific context structure */
        DSPI_DMA_INFO_STRUCT_PTR       dspi_info_ptr,

        /* [IN] Data to transmit */
        uint8_t                     *txbuf,

        /* [OUT] Received data */
        uint8_t                     *rxbuf,

        /* [IN] Length of transfer in bytes */
        uint32_t                        len,

        /* [IN] Width of data register access for DMA transfer */
        int                            regw
    )
{
    DMA_TCD                            tx_tcd;
    DMA_TCD                            rx_tcd;

    #if PSP_ENDIAN == MQX_LITTLE_ENDIAN
        if (regw > 1) {
            regw = -regw;
        }
    #endif

    if (NULL != rxbuf) {
        dma_tcd_reg2mem(&rx_tcd, &(dspi_info_ptr->DSPI_PTR->POPR), regw, rxbuf, len);
    }
    else {
        dma_tcd_reg2mem(&rx_tcd, &(dspi_info_ptr->DSPI_PTR->POPR), regw, dspi_info_ptr->RX_BUF, len);
        rx_tcd.LOOP_DST_OFFSET = -regw;
    }

    if (NULL != txbuf) {
        dma_tcd_mem2reg(&tx_tcd, &(dspi_info_ptr->DSPI_PTR->PUSHR), regw, txbuf, len);
    }
    else {
        dma_tcd_mem2reg(&tx_tcd, &(dspi_info_ptr->DSPI_PTR->PUSHR), regw, dspi_info_ptr->TX_BUF, len);
        tx_tcd.LOOP_SRC_OFFSET = -regw;
    }

    /* ensure that the semaphore is at zero count */
    while (_lwsem_poll(&dspi_info_ptr->EVENT_IO_FINISHED)) {}

    dma_transfer_submit(dspi_info_ptr->DMA_RX_CHANNEL, &rx_tcd, NULL);
    dma_transfer_submit(dspi_info_ptr->DMA_TX_CHANNEL, &tx_tcd, NULL);

    /* block the task until completion of the background operation */
    _lwsem_wait(&dspi_info_ptr->EVENT_IO_FINISHED);

    if (dma_channel_status(dspi_info_ptr->DMA_RX_CHANNEL, NULL, NULL)
        || dma_channel_status(dspi_info_ptr->DMA_TX_CHANNEL, NULL, NULL)
       )
    {
        return 0;
    }

    return len;
}