示例#1
0
OSStatus host_platform_spi_transfer( bus_transfer_direction_t dir, uint8_t* buffer, uint16_t buffer_length )
{
    OSStatus result;
    int i;

    for(i=0; i<buffer_length; i++) {
        buffer_temp_32[i] = SPI0_TXCMD | (uint32_t)buffer[i];;
    }
    dmaSPITX.dmaChStcd = (edma_software_tcd_t *)mem_align(2 * sizeof(edma_software_tcd_t) * dmaSPITX.period, 32);
    dmaSPITX.srcAddr = (uint32_t)buffer_temp_32;
    dmaSPITX.length = buffer_length * 4;
    dmaSPIRX.dmaChStcd = (edma_software_tcd_t *)mem_align(2 * sizeof(edma_software_tcd_t) * dmaSPIRX.period, 32);
    dmaSPIRX.destAddr = (uint32_t)buffer;
    dmaSPIRX.length = buffer_length;
    
    MCU_CLOCKS_NEEDED();
    SPI0_CS_ENABLE;
    setup_edma_loop(&dmaSPITX);
    setup_edma_loop(&dmaSPIRX);

    EDMA_DRV_StartChannel(dmaSPIRX.dmaCh);
    EDMA_DRV_StartChannel(dmaSPITX.dmaCh);

    result = mico_rtos_get_semaphore( &spi_transfer_finished_semaphore, 100 );
    disable_edma_loop(&dmaSPIRX);
    disable_edma_loop(&dmaSPITX);
    SPI0_CS_DISABLE;
    MCU_CLOCKS_NOT_NEEDED();
    free_align(dmaSPITX.dmaChStcd);
    free_align(dmaSPIRX.dmaChStcd);
    return result;
}
示例#2
0
OSStatus spi_dma_transfer(const uint8_t* data_out, uint8_t* data_in, uint32_t size )
{
	uint32_t i,loop_count = MAX_LOOP_COUNT;
		
	spi_dma_sem = 0;

    for(i=0;i<size;i++)
      spi_tx_buffer[i] = (uint32_t)  *data_out++;
	
	
    write_dmaLoop.dmaChanNum = DMA_CH0;             
    write_dmaLoop.dmaCh = &dmaCh0;
    write_dmaLoop.type = kEDMAMemoryToPeripheral;
    write_dmaLoop.chSource = kDmaRequestMux0SPI0Tx;
   	write_dmaLoop.srcAddr = (uint32_t)spi_tx_buffer;
    write_dmaLoop.destAddr = (uint32_t)&SPI0->PUSHR;
    write_dmaLoop.length = size*4;
    write_dmaLoop.size = 4;
    write_dmaLoop.watermark = 4;
    write_dmaLoop.period = 1;
    write_dmaLoop.dmaCallBack = stop_tx_edma;

    setup_edma_loop(&write_dmaLoop);

   	read_dmaLoop.dmaChanNum = DMA_CH1;
   	read_dmaLoop.dmaCh = &dmaCh1;
   	read_dmaLoop.type = kEDMAPeripheralToMemory;
   	read_dmaLoop.chSource = kDmaRequestMux0SPI0Rx;
   	read_dmaLoop.srcAddr = (uint32_t)&SPI0->POPR;
	read_dmaLoop.destAddr = (uint32_t)data_in;
	read_dmaLoop.length = size;
    read_dmaLoop.size = 1;
   	read_dmaLoop.watermark = 1;
    read_dmaLoop.period = 1;
    read_dmaLoop.dmaCallBack = stop_rx_edma;

    setup_edma_loop(&read_dmaLoop);

	
   	EDMA_DRV_StartChannel(read_dmaLoop.dmaCh);	
	EDMA_DRV_StartChannel(write_dmaLoop.dmaCh);

	
	while(loop_count>0)
	{
		if(spi_dma_sem)
			return kNoErr;

		//loop_count--;
	}

	return kTimeoutErr;
}
示例#3
0
/*FUNCTION**********************************************************************
*
* Function Name : SND_RxConfigDataFormat
* Description	: Configure the audio file format in rx soundcard.
*  The soundcard includes a controller and a codec. The audio format includes 
*  sample rate, bit length and so on.
*END**************************************************************************/
snd_status_t SND_RxConfigDataFormat(sound_card_t *card, ctrl_data_format_t *format)
{
    audio_controller_t *ctrl = &card->controller;
    audio_codec_t *codec = &card->codec;

    ctrl->ops->Ctrl_RxConfigDataFormat(ctrl->instance, format);
    codec->ops->Codec_ConfigDataFormat(codec->handler, format->mclk, format->sample_rate, 
                                                                    format->bits);
    /* Configure dma */
#if USEDMA
    audio_buffer_t *buffer = &card->buffer;
    uint8_t sample_size = format->bits/8;
    uint32_t watermark = ctrl->ops->Ctrl_RxGetWatermark(ctrl->instance);
    if((sample_size == 3) || (format->bits & 0x7))
    {
        sample_size = 4;
    }
    uint32_t * desAddr = ctrl->ops->Ctrl_RxGetFifoAddr(ctrl->instance,ctrl->fifo_channel);
    EDMA_DRV_ConfigLoopTransfer(
            &ctrl->dma_channel, ctrl->stcd, kEDMAPeripheralToMemory,
             (uint32_t)desAddr, (uint32_t)buffer->buff, sample_size,
            sample_size * watermark, AUDIO_BUFFER_SIZE, AUDIO_BUFFER_BLOCK);
    EDMA_DRV_StartChannel(&ctrl->dma_channel);
#endif
    return kStatus_SND_Success;
}
示例#4
0
/*FUNCTION**********************************************************************
 *
 * Function Name : SND_RxStart
 * Description   : This function is used to start rx receive.
 *END**************************************************************************/
void SND_RxStart(sound_card_t *card)
{
    audio_controller_t *ctrl = &card->controller;
#if !USEDMA
    audio_buffer_t *buffer = &card->buffer;
    ctrl->ops->Ctrl_ReceiveData(ctrl->instance, buffer->input_curbuff, buffer->size);
    ctrl->ops->Ctrl_RxSetIntCmd(ctrl->instance, true);
#else
    ctrl->ops->Ctrl_RxSetDmaCmd(ctrl->instance,true);
    EDMA_DRV_StartChannel(&card->controller.dma_channel);
#endif
    ctrl->ops->Ctrl_RxStart(ctrl->instance);
}
/*FUNCTION**********************************************************************
 *
 * Function Name : UART_DRV_EdmaStartReceiveData
 * Description   : Initiate (start) a receive by beginning the process of
 * receiving data and enabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static uart_status_t UART_DRV_EdmaStartReceiveData(uint32_t instance,
                                                   uint8_t * rxBuff,
                                                   uint32_t rxSize)
{
    assert(instance < UART_INSTANCE_COUNT);

    UART_Type * base = g_uartBase[instance];

    edma_transfer_config_t edmaRxConfig;
    edmaRxConfig.srcAddr            = UART_HAL_GetDataRegAddr(base);
    edmaRxConfig.destAddr           = (uint32_t)rxBuff;
    edmaRxConfig.srcTransferSize    = kEDMATransferSize_1Bytes;
    edmaRxConfig.destTransferSize   = kEDMATransferSize_1Bytes;
    edmaRxConfig.srcOffset          = 0U;
    edmaRxConfig.destOffset         = 1U;
    edmaRxConfig.srcLastAddrAdjust  = 0U;
    edmaRxConfig.destLastAddrAdjust = 0U;
    edmaRxConfig.srcModulo          = kEDMAModuloDisable;
    edmaRxConfig.destModulo         = kEDMAModuloDisable;
    edmaRxConfig.minorLoopCount     = 1U;
    edmaRxConfig.majorLoopCount     = rxSize;

    edma_software_tcd_t   stcd;

    /* Get current runtime structure. */
    uart_edma_state_t * uartEdmaState = (uart_edma_state_t *)g_uartStatePtr[instance];

    /* Check that we're not busy already receiving data from a previous function call. */
    if (uartEdmaState->isRxBusy)
    {
        return kStatus_UART_RxBusy;
    }

    /* Update UART DMA run-time structure. */
    uartEdmaState->isRxBusy = true;

    memset(&stcd, 0, sizeof(edma_software_tcd_t));

    /* Sets the descriptor basic transfer for the descriptor. */
    EDMA_DRV_PrepareDescriptorTransfer(&uartEdmaState->edmaUartRx, &stcd, &edmaRxConfig, true, true);

    /* Copies the software TCD configuration to the hardware TCD */
    EDMA_DRV_PushDescriptorToReg(&uartEdmaState->edmaUartRx, &stcd);

    /* Start DMA channel */
    EDMA_DRV_StartChannel(&uartEdmaState->edmaUartRx);

    return kStatus_UART_Success;
}
/*FUNCTION*********************************************************************
 *
 * Function Name : FLEXIO_Camera_DRV_ResetEdmaRx
 * Description   : Reset the EDMA transfer loop's destination address and loop
 * counter, which means the EDMA transfer would be reset to the initialized state.
 * This API would be called when VSYNC event happenned to make sure the data
 * from camera would not be misplaced. However, if there is other application
 * configuration can do the same thing, this API would not be necessary.
 *
 *END*************************************************************************/
flexio_camera_status_t FLEXIO_Camera_DRV_ResetEdmaRx(
        flexio_camera_edma_handler_t *handler)
{

    uint32_t ret;
    edma_transfer_config_t rxEdmeConfigStruct;
    edma_software_tcd_t rxEdmaChnStcd[2];
    flexio_camera_dev_t *flexioCameraHwConfigPtr = &(handler->flexioCameraHwConfig);

    EDMA_DRV_StopChannel(&handler->rxEdmaChnState);
    
    /* 3. Configure the channel. */
    rxEdmeConfigStruct.srcAddr            = FLEXIO_Camera_HAL_GetRxBufferAddr(flexioCameraHwConfigPtr);
    rxEdmeConfigStruct.destAddr           = handler->userBufAddr;
    rxEdmeConfigStruct.srcTransferSize    = kEDMATransferSize_32Bytes;
    rxEdmeConfigStruct.destTransferSize   = kEDMATransferSize_32Bytes; 
    rxEdmeConfigStruct.srcOffset          = 0;
    rxEdmeConfigStruct.destOffset         = 4U * (flexioCameraHwConfigPtr->shifterCount); /* 4 byte per shifter, typically 32 byte for 8 shifters. */
    rxEdmeConfigStruct.srcLastAddrAdjust  = 0;
    rxEdmeConfigStruct.destLastAddrAdjust = -(int32_t)(handler->userBufLenByte);
    rxEdmeConfigStruct.srcModulo          = kEDMAModuloDisable;
    rxEdmeConfigStruct.destModulo         = kEDMAModuloDisable;
    rxEdmeConfigStruct.minorLoopCount     = rxEdmeConfigStruct.destOffset; /* the minor loop would read all the data in shifters one time per trigger. */
    rxEdmeConfigStruct.majorLoopCount     = (handler->userBufLenByte)/(rxEdmeConfigStruct.minorLoopCount);

    ret = EDMA_DRV_PrepareDescriptorTransfer( 
                                &handler->rxEdmaChnState,
                                rxEdmaChnStcd,
                                &rxEdmeConfigStruct,
                                false, /* Always disable transfer done interrupt. */
                                false  /* Always disable auto shutdown req. */ 
                                  );
    if (ret == kEDMAInvalidChannel)
    {
        return kStatus_FlexIO_Camera_Failed;
    }

    ret = EDMA_DRV_PushDescriptorToReg( &handler->rxEdmaChnState, rxEdmaChnStcd);
    if (ret == kEDMAInvalidChannel)
    {
        return kStatus_FlexIO_Camera_Failed;
    }
    EDMA_DRV_StartChannel(&handler->rxEdmaChnState);

    return kStatus_FlexIO_Camera_Success;
}
/*FUNCTION*********************************************************************
 *
 * Function Name : FLEXIO_Camera_DRV_StartEdmaRx
 * Description   : Start the flexio_camera_edma device. After the initializatioin,
 * the EDMA would be triggered and start the tranfer by calling this API. Then
 * the memory mapping can be executed.
 *
 *END*************************************************************************/
flexio_camera_status_t FLEXIO_Camera_DRV_StartEdmaRx(
        flexio_camera_edma_handler_t *handler)
{
    uint32_t ret;
    flexio_camera_dev_t *flexioCameraHwConfigPtr = &(handler->flexioCameraHwConfig);
    
    /* Clear the flexio flags. */
    FLEXIO_Camera_HAL_ClearRxBufferFullFlag(flexioCameraHwConfigPtr);
    /* Enable the DMA trigger of the first shifter. */
    FLEXIO_Camera_HAL_SetRxBufferDmaCmd(flexioCameraHwConfigPtr, 0x01, true);

    ret = EDMA_DRV_StartChannel(&handler->rxEdmaChnState);
    if (ret == kEDMAInvalidChannel)
    {
        return kStatus_FlexIO_Camera_Failed;
    }

    return kStatus_FlexIO_Camera_Success;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : QSPI_DRV_ReadDataEdma
 * Description   : Read data from QSPI rx FIFO/Buffer using EDMA way. This function
 * will open dma enable bit and transfer data in ISR.
 *
 *END**************************************************************************/
void QSPI_DRV_ReadDataEdma(uint32_t instance, uint32_t * addr, uint32_t size)
{
    QuadSPI_Type * base = g_qspiBase[instance]; 
    edma_transfer_config_t config = {0};
    /* Update internal state */
    g_qspiState[instance]->rxSize = size;
    g_qspiState[instance]->rxAddr = addr;
    g_qspiState[instance]->rxFinishedBytes = 0;
    if (!g_qspiState[instance]->rxUseDma)
    {
        /* Request edma channel */
        uint8_t channel = 0;
        channel = EDMA_DRV_RequestChannel(kEDMAAnyChannel, g_qspiState[instance]->rxSource,
               &g_qspiState[instance]->rxEdmaChn);
        if (channel == kEDMAInvalidChannel)
        {
            return;
        }
        EDMA_DRV_InstallCallback(&g_qspiState[instance]->rxEdmaChn, 
            QSPI_DRV_RxEdmaCallback, g_qspiState[instance]);
        g_qspiState[instance]->rxUseDma = true;
    }
    config.destAddr = (uint32_t)addr;
    config.destOffset = 4;
    config.destTransferSize = kEDMATransferSize_4Bytes;
    /* AHB buffer or ARDB */
    config.srcAddr = QSPI_HAL_GetRxFifoAddr(base);
    config.srcTransferSize = kEDMATransferSize_4Bytes;
    config.srcOffset = 0;
    config.minorLoopCount = 4 * g_qspiState[instance]->rxWatermark;
    config.majorLoopCount = size/config.minorLoopCount;
    EDMA_DRV_PrepareDescriptorTransfer(&g_qspiState[instance]->rxEdmaChn, STCD_ADDR(g_qspiState[instance]->rxEdmaTCD),
            &config, true, true);
    EDMA_DRV_PushDescriptorToReg(&g_qspiState[instance]->rxEdmaChn, STCD_ADDR(g_qspiState[instance]->rxEdmaTCD));
    EDMA_DRV_StartChannel(&g_qspiState[instance]->rxEdmaChn);
    /* Enable dma request */
    QSPI_HAL_SetDmaCmd(base, kQspiRxBufferDrainDmaFlag, true);
    /* Enable interrupt to clear the underrun. */
    QSPI_HAL_SetIntCmd(base, kQspiRxBufferOverflow, true);
    /* Enable module */
    QSPI_HAL_EnableModule(base);
    g_qspiState[instance]->isRxBusy = true;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : QSPI_DRV_WriteDataEdma
 * Description   : Write data into QSPI tx FIFO using EDMA. This function
 * will open dma enable bit and transfer data using EDMA.
 *
 *END**************************************************************************/
qspi_status_t QSPI_DRV_WriteDataEdma(uint32_t instance, uint32_t * addr, uint32_t size)
{
    QuadSPI_Type * base = g_qspiBase[instance];
    edma_transfer_config_t config = {0};
    /* Update internal state */
    g_qspiState[instance]->txSize = size;
    g_qspiState[instance]->txAddr = addr;
    g_qspiState[instance]->txFinishedBytes = 0;
    /* Request edma channel */
    if (!g_qspiState[instance]->txUseDma)
    {
        uint8_t channel = 0;
        channel = EDMA_DRV_RequestChannel(kEDMAAnyChannel, g_qspiState[instance]->txSource,
               &g_qspiState[instance]->txEdmaChn);
        if (channel == kEDMAInvalidChannel)
        {
            return kStatus_QSPI_Fail;
        }
        EDMA_DRV_InstallCallback(&g_qspiState[instance]->txEdmaChn, 
            QSPI_DRV_TxEdmaCallback, g_qspiState[instance]);
        g_qspiState[instance]->txUseDma = true;
    }
    config.srcAddr = (uint32_t)addr;
    config.destAddr = QSPI_HAL_GetTxFifoAddr(base);
    config.destTransferSize = kEDMATransferSize_4Bytes;
    config.srcTransferSize = kEDMATransferSize_4Bytes;
    config.destOffset = 0;
    config.srcOffset = 4;
    config.minorLoopCount = 4 * (FSL_FEATURE_QSPI_TXFIFO_DEPTH -g_qspiState[instance]->txWatermark);
    config.majorLoopCount = size/config.minorLoopCount;
    EDMA_DRV_PrepareDescriptorTransfer(&g_qspiState[instance]->txEdmaChn, STCD_ADDR(g_qspiState[instance]->txEdmaTCD),
            &config, true, true);
    EDMA_DRV_PushDescriptorToReg(&g_qspiState[instance]->txEdmaChn, STCD_ADDR(g_qspiState[instance]->txEdmaTCD));
    EDMA_DRV_StartChannel(&g_qspiState[instance]->txEdmaChn);
    /* Enable dma request */
    QSPI_HAL_SetDmaCmd(base, kQspiTxBufferFillDmaFlag, true);
    /* Enable interrupt to clear the underrun. */
    QSPI_HAL_SetIntCmd(base, kQspiTxBufferUnderrun, true);
    /* Enable module */
    QSPI_HAL_EnableModule(base);
    g_qspiState[instance]->isTxBusy = true;
    return kStatus_QSPI_Success;
}