예제 #1
0
/**
 * \brief Try to allocate a DMA channel for on given controller.
 * \param pDmad  Pointer to DMA driver instance.
 * \param bXdmac xDMA controller ID (0 ~ 1).
 * \param bSrcID Source peripheral ID, 0xFF for memory.
 * \param bDstID Destination peripheral ID, 0xFF for memory.
 * \return Channel number if allocation sucessful, return
 * DMAD_ALLOC_FAILED if allocation failed.
 */
static uint32_t XDMAD_AllocateXdmacChannel( sXdmad *pXdmad,
                                            uint8_t bXdmac,
                                            uint8_t bSrcID,
                                            uint8_t bDstID)
{
    uint32_t i;
    /* Can't support peripheral to peripheral */
    if ((( bSrcID != XDMAD_TRANSFER_MEMORY ) && ( bDstID != XDMAD_TRANSFER_MEMORY )))
    {
        return XDMAD_ALLOC_FAILED;
    }
    /* dma transfer from peripheral to memory */
    if ( bDstID == XDMAD_TRANSFER_MEMORY)
    {
        if( (!XDMAIF_IsValidatedPeripherOnDma(bXdmac, bSrcID)) )
        {
            return XDMAD_ALLOC_FAILED;
        }
    }
    /* dma transfer from memory to peripheral */
    if ( bSrcID == XDMAD_TRANSFER_MEMORY )
    {
        if( (!XDMAIF_IsValidatedPeripherOnDma(bXdmac, bDstID)) )
        {
            return XDMAD_ALLOC_FAILED;
        }
    }

    for (i = 0; i < pXdmad->numChannels; i ++)
    {
        if ( pXdmad->XdmaChannels[bXdmac][i].state == XDMAD_STATE_FREE )
        {
            /* Allocate the channel */
            pXdmad->XdmaChannels[bXdmac][i].state = XDMAD_STATE_ALLOCATED;
            /* Get general informations */
            pXdmad->XdmaChannels[bXdmac][i].bSrcPeriphID = bSrcID;
            pXdmad->XdmaChannels[bXdmac][i].bDstPeriphID = bDstID;
            pXdmad->XdmaChannels[bXdmac][i].bSrcTxIfID =
                XDMAIF_Get_ChannelNumber(bXdmac, bSrcID, 0);
            pXdmad->XdmaChannels[bXdmac][i].bSrcRxIfID =
                XDMAIF_Get_ChannelNumber(bXdmac, bSrcID, 1);
            pXdmad->XdmaChannels[bXdmac][i].bDstTxIfID =
                XDMAIF_Get_ChannelNumber(bXdmac, bDstID, 0);
            pXdmad->XdmaChannels[bXdmac][i].bDstTxIfID =
                XDMAIF_Get_ChannelNumber(bXdmac, bDstID, 1);
            return ((bXdmac << 8)) | ((i) & 0xFF);
        }
    }
    return XDMAD_ALLOC_FAILED;
}
예제 #2
0
/**
 * \brief Configure the USART tx DMA source with Linker List mode.
 *
 * \param UsartChannel Pointer to USART dma channel
 * \returns 0 if the dma multibuffer configuration successfully; otherwise returns
 * USARTD_ERROR_XXX.
 */
static uint8_t _configureTxLinkList(Usart *pUsartHw, void *pXdmad, UsartChannel *pUsartTx)
{
    sXdmadCfg xdmadTxCfg;
    uint32_t xdmaCndc;
    uint32_t usartId;
    if ((unsigned int)pUsartHw == (unsigned int)USART0 ) usartId = ID_USART0;
    if ((unsigned int)pUsartHw == (unsigned int)USART1 ) usartId = ID_USART1;
    if ((unsigned int)pUsartHw == (unsigned int)USART2 ) usartId = ID_USART2;
    /* Setup TX Link List */
    xdmadTxCfg.mbr_ubc =   XDMA_UBC_NVIEW_NDV0 |
                           XDMA_UBC_NDE_FETCH_DIS|
                           XDMA_UBC_NSEN_UPDATED |  pUsartTx->BuffSize;

    xdmadTxCfg.mbr_sa = (uint32_t)pUsartTx->pBuff;
    xdmadTxCfg.mbr_da = (uint32_t)&pUsartHw->US_THR;
    xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
                         XDMAC_CC_MBSIZE_SINGLE |
                         XDMAC_CC_DSYNC_MEM2PER |
                         XDMAC_CC_CSIZE_CHK_1 |
                         XDMAC_CC_DWIDTH_BYTE|
                         XDMAC_CC_SIF_AHB_IF0 |
                         XDMAC_CC_DIF_AHB_IF1 |
                         XDMAC_CC_SAM_INCREMENTED_AM |
                         XDMAC_CC_DAM_FIXED_AM |
                         XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(  usartId, XDMAD_TRANSFER_TX ));

    xdmadTxCfg.mbr_bc = 0;
    xdmadTxCfg.mbr_sus = 0;
    xdmadTxCfg.mbr_dus =0;
    xdmaCndc = 0;

    if (XDMAD_ConfigureTransfer( pXdmad, pUsartTx->ChNum, &xdmadTxCfg, xdmaCndc, 0))
        return USARTD_ERROR;
    return 0;
}
예제 #3
0
파일: main.c 프로젝트: gstroe/Arm
/**
 *  \brief Start waiting USART data
 *  Start DMA, the 1st DMA buffer is free USART buffer assigned.
 */
static void _UsartDmaRx()
{
	sXdmad *pDmad = &dmad;
	sXdmadCfg xdmadUsartRxCfg;
	uint32_t xdmaUsartRxCndc, xdmaInt;
	xdmadUsartRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
							  | XDMAC_CC_MBSIZE_SINGLE
							  | XDMAC_CC_DSYNC_PER2MEM
							  | XDMAC_CC_CSIZE_CHK_1
							  | XDMAC_CC_DWIDTH_BYTE
							  | XDMAC_CC_SIF_AHB_IF1
							  | XDMAC_CC_DIF_AHB_IF1
							  | XDMAC_CC_SAM_FIXED_AM
							  | XDMAC_CC_DAM_INCREMENTED_AM
							  | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_USART, XDMAD_TRANSFER_RX));
	xdmadUsartRxCfg.mbr_sa = dmaRxLinkList.mbr_sa;
	xdmadUsartRxCfg.mbr_da = dmaRxLinkList.mbr_da;
	xdmadUsartRxCfg.mbr_ubc = DATAPACKETSIZE;
	xdmadUsartRxCfg.mbr_bc = 0;
	xdmaUsartRxCndc = 0;


	xdmaInt = XDMAC_CIE_BIE;

	XDMAD_ConfigureTransfer(pDmad, usartDmaRxChannel, &xdmadUsartRxCfg,
							 xdmaUsartRxCndc, (uint32_t)&dmaRxLinkList, xdmaInt);
	XDMAD_StartTransfer(pDmad, usartDmaRxChannel);
}
예제 #4
0
파일: main.c 프로젝트: gstroe/Arm
/**
 *  \brief Send single buffer data through DMA
 */
static void _UsartDmaTx(uint32_t dwDestAddr,
						 void *pBuffer, uint16_t wSize)
{
	sXdmad *pDmad = &dmad;
	/* Setup transfer */
	sXdmadCfg xdmadCfg;
	xdmadCfg.mbr_ubc = wSize;
	xdmadCfg.mbr_sa = (uint32_t) pBuffer;
	xdmadCfg.mbr_da = (uint32_t) dwDestAddr;
	xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
					   | XDMAC_CC_MEMSET_NORMAL_MODE
					   | XDMAC_CC_DSYNC_MEM2PER
					   | XDMAC_CC_CSIZE_CHK_1
					   | XDMAC_CC_DWIDTH_BYTE
					   | XDMAC_CC_SIF_AHB_IF1
					   | XDMAC_CC_DIF_AHB_IF1
					   | XDMAC_CC_SAM_INCREMENTED_AM
					   | XDMAC_CC_DAM_FIXED_AM
					   | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_USART, XDMAD_TRANSFER_TX));
	xdmadCfg.mbr_bc = 0;
	XDMAD_ConfigureTransfer(pDmad, usartDmaTxChannel, &xdmadCfg, 0, 0, (
								 XDMAC_CIE_BIE   |
								 XDMAC_CIE_DIE   |
								 XDMAC_CIE_FIE   |
								 XDMAC_CIE_RBIE  |
								 XDMAC_CIE_WBIE  |
								 XDMAC_CIE_ROIE));

	SCB_CleanDCache_by_Addr((uint32_t *)pBuffer, wSize);

	XDMAD_StartTransfer(pDmad, usartDmaTxChannel);
}
예제 #5
0
static uint8_t _Afe_configureLinkList(Afec *pAfeHw, void *pXdmad,
									  AfeCmd *pCommand)
{
	uint32_t xdmaCndc, xdmaInt;
	sXdmadCfg xdmadRxCfg;
	uint32_t afeId;

	if ((unsigned int)pAfeHw == (unsigned int)AFEC0) afeId = ID_AFEC0;

	if ((unsigned int)pAfeHw == (unsigned int)AFEC1) afeId = ID_AFEC1;

	/* Setup RX Link List */
	xdmadRxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 |
						 XDMA_UBC_NDE_FETCH_DIS |
						 XDMA_UBC_NDEN_UPDATED |
						 pCommand->RxSize;

	xdmadRxCfg.mbr_da = (uint32_t)pCommand->pRxBuff;
	xdmadRxCfg.mbr_sa = (uint32_t) & (pAfeHw->AFEC_LCDR);
	xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
						 XDMAC_CC_MBSIZE_SINGLE |
						 XDMAC_CC_DSYNC_PER2MEM |
						 XDMAC_CC_CSIZE_CHK_1 |
						 XDMAC_CC_DWIDTH_WORD |
						 XDMAC_CC_SIF_AHB_IF1 |
						 XDMAC_CC_DIF_AHB_IF1 |
						 XDMAC_CC_SAM_FIXED_AM |
						 XDMAC_CC_DAM_INCREMENTED_AM |
						 XDMAC_CC_PERID(
							 XDMAIF_Get_ChannelNumber(afeId, XDMAD_TRANSFER_RX));

	xdmadRxCfg.mbr_bc = 0;
	xdmadRxCfg.mbr_sus = 0;
	xdmadRxCfg.mbr_dus = 0;

	xdmaInt =  (XDMAC_CIE_BIE   |
				XDMAC_CIE_DIE   |
				XDMAC_CIE_FIE   |
				XDMAC_CIE_RBIE  |
				XDMAC_CIE_WBIE  |
				XDMAC_CIE_ROIE);
	xdmaCndc = 0;

	if (XDMAD_ConfigureTransfer(pXdmad, afeDmaRxChannel,
								 &xdmadRxCfg, xdmaCndc, 0, xdmaInt))
		return AFE_ERROR;

	return AFE_OK;
}
예제 #6
0
파일: dac_dma.c 프로젝트: AoLaD/rtems
static uint8_t _Dac_configureLinkList(Dacc *pDacHw, void *pXdmad,
									  DacCmd *pCommand)
{
	uint32_t xdmaCndc;
	sXdmadCfg xdmadCfg;
	uint32_t *pBuffer;
	/* Setup TX Link List */
	uint8_t i;
	pBuffer = (uint32_t *)pCommand->pTxBuff;

	for (i = 0; i < pCommand->TxSize; i++) {
		dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
									  | XDMA_UBC_NDE_FETCH_EN
									  | XDMA_UBC_NSEN_UPDATED
									  | XDMAC_CUBC_UBLEN(4);
		dmaWriteLinkList[i].mbr_sa = (uint32_t)pBuffer;
		dmaWriteLinkList[i].mbr_da =
			(uint32_t) & (pDacHw->DACC_CDR[pCommand->dacChannel]);

		if (i == (pCommand->TxSize - 1)) {
			if (pCommand->loopback)
				dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0];
			else
				dmaWriteLinkList[i].mbr_nda = 0;
		} else
			dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i + 1];

		pBuffer++;
	}

	xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
					   | XDMAC_CC_MBSIZE_SINGLE
					   | XDMAC_CC_DSYNC_MEM2PER
					   | XDMAC_CC_CSIZE_CHK_1
					   | XDMAC_CC_DWIDTH_WORD
					   | XDMAC_CC_SIF_AHB_IF1
					   | XDMAC_CC_DIF_AHB_IF1
					   | XDMAC_CC_SAM_INCREMENTED_AM
					   | XDMAC_CC_DAM_FIXED_AM
					   | XDMAC_CC_PERID(
							XDMAIF_Get_ChannelNumber(ID_DACC, XDMAD_TRANSFER_TX));
	xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
			   | XDMAC_CNDC_NDE_DSCR_FETCH_EN
			   | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
			   | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
	XDMAD_ConfigureTransfer(pXdmad, dacDmaTxChannel, &xdmadCfg, xdmaCndc,
							 (uint32_t)&dmaWriteLinkList[0], XDMAC_CIE_LIE);
	return DAC_OK;
}
예제 #7
0
파일: main.c 프로젝트: gstroe/Arm
/**
 *  \brief Start USART waiting data.
 */
static void _DmaUsartRx(void)
{
	uint32_t status;

	/* Read USART status */
	status = USART->US_CSR;
	if ((status & US_CSR_RXRDY) == US_CSR_RXRDY)
		status = USART->US_RHR; /* clear the US_CSR_RXRDY*/
	sXdmadCfg xdmadCfg;
	xdmadCfg.mbr_ubc = BUFFER_SIZE - 1;
	xdmadCfg.mbr_sa = (uint32_t)&USART->US_RHR;
	xdmadCfg.mbr_da = (uint32_t)pRecvBufferUSART;
	xdmadCfg.mbr_cfg =
			XDMAC_CC_TYPE_PER_TRAN |
			XDMAC_CC_MBSIZE_SINGLE |
			XDMAC_CC_DSYNC_PER2MEM |
			XDMAC_CC_CSIZE_CHK_1 |
			XDMAC_CC_DWIDTH_BYTE |
			XDMAC_CC_SIF_AHB_IF1 |
			XDMAC_CC_DIF_AHB_IF1 |
			XDMAC_CC_SAM_FIXED_AM |
			XDMAC_CC_DAM_INCREMENTED_AM |
			XDMAC_CC_PERID(
				XDMAIF_Get_ChannelNumber(ID_USART, XDMAD_TRANSFER_RX)
				);

	xdmadCfg.mbr_bc  = 0;
	xdmadCfg.mbr_ds  = 0;
	xdmadCfg.mbr_sus = 0;
	xdmadCfg.mbr_dus = 0;
	XDMAD_ConfigureTransfer(
			&dmad, usartDmaRxChannel, &xdmadCfg, 0, 0,
			XDMAC_CIE_BIE |
			XDMAC_CIE_DIE |
			XDMAC_CIE_FIE |
			XDMAC_CIE_RBIE |
			XDMAC_CIE_WBIE |
			XDMAC_CIE_ROIE);
	XDMAD_StartTransfer(&dmad, usartDmaRxChannel);
}
예제 #8
0
/**
 * \brief xDMA transfer PWM duty
 */
static void _PwmDmaTransfer(void)
{
    sXdmadCfg xdmadCfg;
    uint32_t xdmaCndc;
    uint32_t i;
    for(i = 0; i < DUTY_BUFFER_LENGTH; i++){
        dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 
            | XDMA_UBC_NDE_FETCH_EN
            | XDMA_UBC_NSEN_UPDATED
            | XDMAC_CUBC_UBLEN(1);
        dmaWriteLinkList[i].mbr_sa = (uint32_t)(&dwDutys[i]);
        dmaWriteLinkList[i].mbr_da = (uint32_t)(&(PWM0->PWM_DMAR));
        if ( i == (DUTY_BUFFER_LENGTH - 1 )) {
            dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0];
        }
        else {
            dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i+1];
        }
    }

    xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN 
        | XDMAC_CC_MBSIZE_SINGLE 
        | XDMAC_CC_DSYNC_MEM2PER 
        | XDMAC_CC_CSIZE_CHK_1 
        | XDMAC_CC_DWIDTH_HALFWORD
        | XDMAC_CC_SIF_AHB_IF0 
        | XDMAC_CC_DIF_AHB_IF1 
        | XDMAC_CC_SAM_FIXED_AM 
        | XDMAC_CC_DAM_FIXED_AM 
        | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_PWM0, XDMAD_TRANSFER_TX ));
    xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 
        | XDMAC_CNDC_NDE_DSCR_FETCH_EN 
        | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
        | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
    XDMAD_ConfigureTransfer( &dmad, pwmDmaTxChannel, &xdmadCfg, xdmaCndc, (uint32_t)&dmaWriteLinkList[0], XDMAC_CIE_LIE);
    SCB_CleanInvalidateDCache();
    XDMAD_StartTransfer( &dmad, pwmDmaTxChannel);
}
예제 #9
0
파일: main.c 프로젝트: gstroe/Arm
/**
 *  \brief Start DMA sending/waiting data.
 */
static void _SscDma(volatile uint32_t *pReg, uint32_t dmaChannel,
					void *pBuffer, uint16_t wSize)
{
	sXdmad *pDmad = &dmad;
	sXdmadCfg xdmadCfg;


	xdmadCfg.mbr_ubc = wSize;
	xdmadCfg.mbr_sa = (uint32_t) pBuffer;
	xdmadCfg.mbr_da = (uint32_t) pReg;
	xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
					| XDMAC_CC_MBSIZE_SINGLE
					| XDMAC_CC_DSYNC_MEM2PER
					| XDMAC_CC_CSIZE_CHK_1
					| XDMAC_CC_DWIDTH_HALFWORD
					| XDMAC_CC_SIF_AHB_IF1
					| XDMAC_CC_DIF_AHB_IF1
					| XDMAC_CC_SAM_INCREMENTED_AM
					| XDMAC_CC_DAM_FIXED_AM
					| XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
									ID_SSC, XDMAD_TRANSFER_TX));
	xdmadCfg.mbr_bc = 0;
	xdmadCfg.mbr_ds = 0;
	xdmadCfg.mbr_sus = 0;
	xdmadCfg.mbr_dus = 0;

	memory_sync();
	XDMAD_ConfigureTransfer(pDmad, dmaChannel, &xdmadCfg, 0, 0, (
								 XDMAC_CIE_BIE   |
								 XDMAC_CIE_DIE   |
								 XDMAC_CIE_FIE   |
								 XDMAC_CIE_RBIE  |
								 XDMAC_CIE_WBIE  |
								 XDMAC_CIE_ROIE));
	SCB_CleanDCache_by_Addr((uint32_t *)pBuffer, wSize);
	XDMAD_StartTransfer(pDmad, dmaChannel);
	SSC_EnableTransmitter(SSC);
}
예제 #10
0
파일: main.c 프로젝트: gstroe/Arm
/**
 *  \brief Start USART sending data.
 */
static void _DmaUsartTx(void)
{
	sXdmadCfg xdmadCfg;

	xdmadCfg.mbr_ubc = BUFFER_SIZE;
	xdmadCfg.mbr_sa = (uint32_t)Buffer;
	xdmadCfg.mbr_da = (uint32_t)&USART->US_THR;
	xdmadCfg.mbr_cfg =
			XDMAC_CC_TYPE_PER_TRAN |
			XDMAC_CC_MBSIZE_SINGLE |
			XDMAC_CC_DSYNC_MEM2PER |
			XDMAC_CC_CSIZE_CHK_1 |
			XDMAC_CC_DWIDTH_BYTE |
			XDMAC_CC_SIF_AHB_IF1 |
			XDMAC_CC_DIF_AHB_IF1 |
			XDMAC_CC_SAM_INCREMENTED_AM |
			XDMAC_CC_DAM_FIXED_AM |
			XDMAC_CC_PERID(
				XDMAIF_Get_ChannelNumber(ID_USART, XDMAD_TRANSFER_TX)
				);

	xdmadCfg.mbr_bc  = 0;
	xdmadCfg.mbr_ds  = 0;
	xdmadCfg.mbr_sus = 0;
	xdmadCfg.mbr_dus = 0;
	XDMAD_ConfigureTransfer(
			&dmad, usartDmaTxChannel, &xdmadCfg, 0, 0,
			XDMAC_CIE_BIE |
			XDMAC_CIE_DIE |
			XDMAC_CIE_FIE |
			XDMAC_CIE_RBIE |
			XDMAC_CIE_WBIE |
			XDMAC_CIE_ROIE);

	SCB_CleanDCache_by_Addr((uint32_t*)Buffer, BUFFER_SIZE);
	XDMAD_StartTransfer(&dmad, usartDmaTxChannel);
}
예제 #11
0
/**
 * \brief Configure the DMA source and destination with Linker List mode.
 *
 * \param pCommand Pointer to command
  * \returns 0 if the dma multibuffer configuration successfully; otherwise returns
 * SPID_ERROR_XXX.
 */
static uint8_t _spid_configureLinkList(Spi *pSpiHw, void *pXdmad, SpidCmd *pCommand)
{
    sXdmadCfg xdmadRxCfg,xdmadTxCfg;
    uint32_t xdmaCndc;
    uint32_t spiId;
    if ((unsigned int)pSpiHw == (unsigned int)SPI0 ) spiId = ID_SPI0;
    if ((unsigned int)pSpiHw == (unsigned int)SPI1 ) spiId = ID_SPI1;
    
    
    
    /* Setup TX  */ 
        
    xdmadTxCfg.mbr_sa = (uint32_t)pCommand->pTxBuff;    
    
    xdmadTxCfg.mbr_da = (uint32_t)&pSpiHw->SPI_TDR;
    
    xdmadTxCfg.mbr_ubc =  XDMA_UBC_NVIEW_NDV0 |
                           XDMA_UBC_NDE_FETCH_DIS|
                           XDMA_UBC_NSEN_UPDATED | pCommand->TxSize;
    
    xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
                         XDMAC_CC_MBSIZE_SINGLE |
                         XDMAC_CC_DSYNC_MEM2PER |
                         XDMAC_CC_CSIZE_CHK_1 |
                         XDMAC_CC_DWIDTH_BYTE|
                         XDMAC_CC_SIF_AHB_IF0 |
                         XDMAC_CC_DIF_AHB_IF1 |
                         XDMAC_CC_SAM_INCREMENTED_AM |
                         XDMAC_CC_DAM_FIXED_AM |
                         XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(  spiId, XDMAD_TRANSFER_TX ));
        
   
    xdmadTxCfg.mbr_bc = 0;
    xdmadTxCfg.mbr_sus = 0;
    xdmadTxCfg.mbr_dus =0;
    
    /* Setup RX Link List */
    
    xdmadRxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 |
                         XDMA_UBC_NDE_FETCH_DIS|
                         XDMA_UBC_NDEN_UPDATED | pCommand->RxSize;
    
    xdmadRxCfg.mbr_da = (uint32_t)pCommand->pRxBuff;
    
    xdmadRxCfg.mbr_sa = (uint32_t)&pSpiHw->SPI_RDR;
    xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
                         XDMAC_CC_MBSIZE_SINGLE |
                         XDMAC_CC_DSYNC_PER2MEM |
                         XDMAC_CC_CSIZE_CHK_1 |
                         XDMAC_CC_DWIDTH_BYTE|
                         XDMAC_CC_SIF_AHB_IF1 |
                         XDMAC_CC_DIF_AHB_IF0 |
                         XDMAC_CC_SAM_FIXED_AM |
                         XDMAC_CC_DAM_INCREMENTED_AM |
                         XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(  spiId, XDMAD_TRANSFER_RX ));
    

    xdmadRxCfg.mbr_bc = 0;
    xdmadRxCfg.mbr_sus = 0;
    xdmadRxCfg.mbr_dus =0;

    xdmaCndc = 0;
    

    if (XDMAD_ConfigureTransfer( pXdmad, spiDmaRxChannel, &xdmadRxCfg, xdmaCndc, 0))
       return SPID_ERROR;
       
    if (XDMAD_ConfigureTransfer( pXdmad, spiDmaTxChannel, &xdmadTxCfg, xdmaCndc, 0))
        return SPID_ERROR;
    return 0;
}
예제 #12
0
/**
 * \brief Configure the UART Tx DMA mode.
 *
 * \param pUartHw   Pointer to UART instance
 * \param pXdmad    Pointer to XDMA instance
 * \param pUsartTx  Pointer to Usart Tx channel
 * \returns 0 if the dma multibuffer configuration successfully; otherwise returns
 * USARTD_ERROR_XXX.
 */
static uint8_t _configureUartTxDma(Uart *pUartHw, void *pXdmad, UartChannel *pUartTx)
{
    sXdmadCfg xdmadTxCfg;
    uint32_t xdmaCndc, xdmaInt;
    uint32_t uartId, LLI_Size;
    uint8_t *pBuff = 0, i;
    if ((unsigned int)pUartHw == (unsigned int)UART0 ) uartId = ID_UART0;
    if ((unsigned int)pUartHw == (unsigned int)UART1 ) uartId = ID_UART1;
    if ((unsigned int)pUartHw == (unsigned int)UART2 ) uartId = ID_UART2;
    if ((unsigned int)pUartHw == (unsigned int)UART3 ) uartId = ID_UART3;
    if ((unsigned int)pUartHw == (unsigned int)UART4 ) uartId = ID_UART4;

    /* Setup TX  */ 
    if(pUartTx->dmaProgrammingMode < XDMAD_LLI)
    {
      xdmadTxCfg.mbr_ubc =    XDMA_UBC_NVIEW_NDV0 |
                              XDMA_UBC_NDE_FETCH_DIS|
                              XDMA_UBC_NSEN_UPDATED |  pUartTx->BuffSize;

      xdmadTxCfg.mbr_sa = (uint32_t)pUartTx->pBuff;
      xdmadTxCfg.mbr_da = (uint32_t)&pUartHw->UART_THR;
      xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
          XDMAC_CC_MBSIZE_SINGLE |
          XDMAC_CC_DSYNC_MEM2PER |
          XDMAC_CC_CSIZE_CHK_1 |
          XDMAC_CC_DWIDTH_BYTE|
          XDMAC_CC_SIF_AHB_IF0 |
          XDMAC_CC_DIF_AHB_IF1 |
          XDMAC_CC_SAM_INCREMENTED_AM |
          XDMAC_CC_DAM_FIXED_AM |
          XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(  uartId, XDMAD_TRANSFER_TX ));

      xdmadTxCfg.mbr_bc = 0;
      xdmadTxCfg.mbr_sus = 0;
      xdmadTxCfg.mbr_dus =0;
      xdmaCndc = 0;

      xdmaInt =  (XDMAC_CIE_BIE   |
                   XDMAC_CIE_DIE   |
                   XDMAC_CIE_FIE   |
                   XDMAC_CIE_RBIE  |
                   XDMAC_CIE_WBIE  |
                   XDMAC_CIE_ROIE);
    }
    
    if(pUartTx->dmaProgrammingMode == XDMAD_LLI)
    {
        LLI_Size = pUartTx->dmaLLI_Size;
        pBuff = pUartTx->pBuff;
        if(pLLIviewTx == NULL)
        {
          pLLIviewTx = malloc(sizeof(LinkedListDescriporView1)*LLI_Size);
        }
        xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
                               XDMAC_CC_MBSIZE_SINGLE |
                               XDMAC_CC_DSYNC_MEM2PER |
                               XDMAC_CC_MEMSET_NORMAL_MODE |
                               XDMAC_CC_CSIZE_CHK_1 |
                               XDMAC_CC_DWIDTH_BYTE |
                               XDMAC_CC_SIF_AHB_IF0 |
                               XDMAC_CC_DIF_AHB_IF1 |
                               XDMAC_CC_SAM_INCREMENTED_AM |
                               XDMAC_CC_DAM_FIXED_AM |
                               XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(  uartId, XDMAD_TRANSFER_TX ));
        xdmadTxCfg.mbr_bc = 0;
        for (i = 0; i < LLI_Size; i++) {
             pLLIviewTx[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
                                   XDMA_UBC_NSEN_UPDATED | 
                                   XDMA_UBC_NDEN_UNCHANGED |
                                   ((i== LLI_Size- 1)? ( (pUartTx->dmaRingBuffer)? XDMA_UBC_NDE_FETCH_EN : 0):  XDMA_UBC_NDE_FETCH_EN) | pUartTx->BuffSize;
                pLLIviewTx[i].mbr_da = (uint32_t)&pUartHw->UART_THR;
                pLLIviewTx[i].mbr_sa = (uint32_t)pBuff;
                pLLIviewTx[i].mbr_nda = (i == ( LLI_Size - 1))? ( (pUartTx->dmaRingBuffer)? (uint32_t)&pLLIviewTx[ 0] : 0 ):(uint32_t)&pLLIviewTx[ i + 1 ];
                pBuff += pUartTx->BuffSize;
            } 
        xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | 
                   XDMAC_CNDC_NDE_DSCR_FETCH_EN |
                   XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED|
                   XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
        
        xdmaInt = ((pUartTx->dmaRingBuffer)? XDMAC_CIE_BIE : XDMAC_CIE_LIE);       
    }
    if (XDMAD_ConfigureTransfer( pXdmad, pUartTx->ChNum, &xdmadTxCfg, xdmaCndc, (uint32_t)&pLLIviewTx[0], xdmaInt))
         return USARTD_ERROR;
    SCB_CleanInvalidateDCache();
    return 0;
}
예제 #13
0
/**
 * \brief Configure the UART Tx DMA mode.
 *
 * \param pUartHw   Pointer to UART instance
 * \param pXdmad    Pointer to XDMA instance
 * \param pUsartTx  Pointer to Usart Tx channel
 * \returns 0 if the dma multibuffer configuration successfully; otherwise 
 * returns USARTD_ERROR_XXX.
 */
static uint8_t _configureUartTxDma(UartDma *pUartd, UartChannel *pUartTx)
{
	sXdmadCfg xdmadTxCfg;
	uint32_t xdmaCndc, xdmaInt, LLI_Size, i;
	uint8_t *pBuff = 0;
	Uart *pUartHwTx = pUartd->pUartHw;
	sXdmad* pXdmadTx = pUartd->pXdmad;
	

	/* Setup TX  */ 
	if(pUartTx->dmaProgrammingMode < XDMAD_LLI) {
	  xdmadTxCfg.mbr_ubc = pUartTx->BuffSize;

	  xdmadTxCfg.mbr_sa = (uint32_t)pUartTx->pBuff;
	  xdmadTxCfg.mbr_da = (uint32_t)&pUartHwTx->UART_THR;
	  xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
						   XDMAC_CC_MBSIZE_SIXTEEN |
						   XDMAC_CC_DSYNC_MEM2PER |
						   XDMAC_CC_CSIZE_CHK_1 |
						   XDMAC_CC_DWIDTH_BYTE|
						   XDMAC_CC_SIF_AHB_IF0 |
						   XDMAC_CC_DIF_AHB_IF1 |
						   XDMAC_CC_SAM_INCREMENTED_AM |
						   XDMAC_CC_DAM_FIXED_AM |
						   XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( 
								pUartd->uartId, XDMAD_TRANSFER_TX ));
	  
	  xdmadTxCfg.mbr_bc = 0;
	  if(pUartTx->dmaProgrammingMode == XDMAD_MULTI) {
		xdmadTxCfg.mbr_bc = pUartTx->dmaBlockSize;
	  }
	  xdmadTxCfg.mbr_sus = 0;
	  xdmadTxCfg.mbr_dus =0;
	  xdmadTxCfg.mbr_ds= 0;
	  xdmaCndc = 0;
	  /* Enable End of Block; Read Bus error;  Write Bus Error; 
		Overflow Error interrupt */
	  xdmaInt =  (XDMAC_CIE_BIE    |
				 XDMAC_CIE_RBIE  |
				 XDMAC_CIE_WBIE  |
				 XDMAC_CIE_ROIE);
			 
	} else if(pUartTx->dmaProgrammingMode == XDMAD_LLI) {
		LLI_Size = pUartTx->dmaBlockSize;
		pBuff = pUartTx->pBuff;
		if(pUartTx->pLLIview != NULL) {
		  free(pUartTx->pLLIview);
		  pUartTx->pLLIview = NULL;
		}
		
		pUartTx->pLLIview = malloc(sizeof(LinkedListDescriporView1)*LLI_Size);
		if( pUartTx->pLLIview == NULL) {
		  TRACE_ERROR(" Can not allocate memory to Tx LLI");
		  return USARTD_ERROR;
		}
		xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
							XDMAC_CC_MBSIZE_SIXTEEN |
							XDMAC_CC_DSYNC_MEM2PER |
							XDMAC_CC_MEMSET_NORMAL_MODE |
							XDMAC_CC_CSIZE_CHK_1 |
							XDMAC_CC_DWIDTH_BYTE |
							XDMAC_CC_SIF_AHB_IF0 |
							XDMAC_CC_DIF_AHB_IF1 |
							XDMAC_CC_SAM_INCREMENTED_AM |
							XDMAC_CC_DAM_FIXED_AM |
							XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( 
								pUartd->uartId, XDMAD_TRANSFER_TX ));
		xdmadTxCfg.mbr_bc = 0;
		for (i = 0; i < LLI_Size; i++) {
			 pUartTx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
								XDMA_UBC_NSEN_UPDATED | 
								XDMA_UBC_NDEN_UNCHANGED |
								((i== LLI_Size- 1)? ( (pUartTx->dmaRingBuffer)? 
								XDMA_UBC_NDE_FETCH_EN : 0): 
								XDMA_UBC_NDE_FETCH_EN) | pUartTx->BuffSize;
				pUartTx->pLLIview[i].mbr_da = (uint32_t)&pUartHwTx->UART_THR;
				pUartTx->pLLIview[i].mbr_sa = (uint32_t)pBuff;
				pUartTx->pLLIview[i].mbr_nda = (i == ( LLI_Size - 1))? 
					( (pUartTx->dmaRingBuffer)? (uint32_t)pUartTx->pLLIview : 0 ):
					(uint32_t)&pUartTx->pLLIview[ i + 1 ];
				pBuff += pUartTx->BuffSize;
			} 
		xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | 
				XDMAC_CNDC_NDE_DSCR_FETCH_EN |
				XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED|
				XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
		xdmaInt = ((pUartTx->dmaRingBuffer)? XDMAC_CIE_BIE : XDMAC_CIE_LIE);
			
	} else {
	  TRACE_ERROR("DmaProgState is incorrect \n\r");
	  return 1;
	}
	memory_barrier();
	if (XDMAD_ConfigureTransfer( pXdmadTx, pUartTx->ChNum, &xdmadTxCfg, xdmaCndc,
		(uint32_t)pUartTx->pLLIview, xdmaInt))
		 return USARTD_ERROR;
	return 0;
}
예제 #14
0
/**
 * \brief Receive and play audio with DMA.
 */
static void PlayRecording(void)
{
    uint32_t src;
    uint8_t i;
    uint32_t xdmaCndc;

    src = 0x20440000;
    for(i = 0; i < TOTAL_Buffers; i++){
        dmaReadLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 
            | XDMA_UBC_NDE_FETCH_EN
            | XDMA_UBC_NSEN_UPDATED 
            | XDMAC_CUBC_UBLEN(0x1000);
        dmaReadLinkList[i].mbr_sa  = (uint32_t)&(AUDIO_IF->SSC_RHR);
        dmaReadLinkList[i].mbr_da = (uint32_t)(src );
        if ( i == (TOTAL_Buffers - 1)){
            dmaReadLinkList[i].mbr_nda = (uint32_t)&dmaReadLinkList[0];
        }
        else {
            dmaReadLinkList[i].mbr_nda = (uint32_t)&dmaReadLinkList[i + 1];
        }
        src += (0x1000 * (BITS_BY_SLOT/8));
    }

    xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN 
        | XDMAC_CC_MBSIZE_SINGLE 
        | XDMAC_CC_DSYNC_PER2MEM 
        | XDMAC_CC_CSIZE_CHK_1 
        | XDMAC_CC_DWIDTH_HALFWORD
        | XDMAC_CC_SIF_AHB_IF1 
        | XDMAC_CC_DIF_AHB_IF0 
        | XDMAC_CC_SAM_FIXED_AM 
        | XDMAC_CC_DAM_INCREMENTED_AM 
        | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_SSC, XDMAD_TRANSFER_RX ));
    xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 
        | XDMAC_CNDC_NDE_DSCR_FETCH_EN 
        | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
        | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
    XDMAD_ConfigureTransfer( &dmad, sscDmaRxChannel, &xdmadCfg, xdmaCndc, (uint32_t)&dmaReadLinkList[0],XDMAC_CIE_LIE);
    SCB_CleanInvalidateDCache();
    src = 0x20440000;
    for(i = 0; i < TOTAL_Buffers; i++){
        dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 
            | XDMA_UBC_NDE_FETCH_EN
            | XDMA_UBC_NSEN_UPDATED
            | XDMAC_CUBC_UBLEN(0x1000);
        dmaWriteLinkList[i].mbr_sa = (uint32_t)(src );
        dmaWriteLinkList[i].mbr_da = (uint32_t)&(AUDIO_IF->SSC_THR);
        if ( i == (TOTAL_Buffers - 1 )) {
            dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0];
        }
        else {
            dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i+1];
        }
        src += (0x1000 * (BITS_BY_SLOT/8));
    }

    xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN 
        | XDMAC_CC_MBSIZE_SINGLE 
        | XDMAC_CC_DSYNC_MEM2PER 
        | XDMAC_CC_CSIZE_CHK_1 
        | XDMAC_CC_DWIDTH_HALFWORD
        | XDMAC_CC_SIF_AHB_IF0 
        | XDMAC_CC_DIF_AHB_IF1 
        | XDMAC_CC_SAM_INCREMENTED_AM 
        | XDMAC_CC_DAM_FIXED_AM 
        | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_SSC, XDMAD_TRANSFER_TX ));
    xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 
        | XDMAC_CNDC_NDE_DSCR_FETCH_EN 
        | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
        | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
    XDMAD_ConfigureTransfer( &dmad, sscDmaTxChannel, &xdmadCfg, xdmaCndc, (uint32_t)&dmaWriteLinkList[0],XDMAC_CIE_LIE);
    SCB_CleanInvalidateDCache();
    XDMAD_StartTransfer( &dmad, sscDmaRxChannel );
    SSC_EnableReceiver(AUDIO_IF);

    Wait(3000);
    /* Enable playback(SSC TX) */
    SCB_CleanInvalidateDCache();
    XDMAD_StartTransfer( &dmad, sscDmaTxChannel);
    SSC_EnableTransmitter(AUDIO_IF);
}
예제 #15
0
파일: qspi_dma.c 프로젝트: AoLaD/rtems
/**
 * \brief Configures the DMA for QSPI
 *
 * \param pQspidma  Pointer to QSPI DMA structure
 * \param Addr      Address to Read or write of QSPI flash memory
 * \param pBuffer   Pointer input/output buffer
 * \param ReadWrite Read or write memory flag
 * \returns 0 if the dma multibuffer configuration successfully; otherwise returns
 * QSPID_ERROR_XXX.
 */
static uint8_t QSPID_configureQpsiDma(QspiDma_t *pQspidma, uint32_t Addr,
									  QspiBuffer_t *pBuffer, Access_t const ReadWrite)
{
	sXdmadCfg xdmadCfg, xdmadRxCfg, xdmadTxCfg;
	uint8_t chanNum;
	uint8_t qspi_id =  pQspidma->Qspid.qspiId;
	Qspi *pQspiHw = pQspidma->Qspid.pQspiHw;
	uint32_t xdmaCndc, xdmaInt, BurstSize, ChannelWidth;


	/* Setup DMA  for QSPI */

	if (pQspidma->Qspid.qspiMode == QSPI_MR_SMM_SPI) {
		// SPI mode
		/* SPI TX DMA config */
		xdmadTxCfg.mbr_sa   =   (uint32_t)pBuffer->pDataTx;
		xdmadTxCfg.mbr_da   =   (uint32_t)&pQspiHw->QSPI_TDR;
		xdmadTxCfg.mbr_ubc  =   (pBuffer->TxDataSize);

		xdmadTxCfg.mbr_cfg =  XDMAC_CC_TYPE_PER_TRAN |
							  XDMAC_CC_MBSIZE_SINGLE |
							  XDMAC_CC_DSYNC_MEM2PER |
							  XDMAC_CC_CSIZE_CHK_1 |
							  XDMAC_CC_DWIDTH_BYTE |
							  XDMAC_CC_SIF_AHB_IF0 |
							  XDMAC_CC_DIF_AHB_IF1 |
							  XDMAC_CC_SAM_INCREMENTED_AM |
							  XDMAC_CC_DAM_FIXED_AM |
							  XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
											 (qspi_id, XDMAD_TRANSFER_TX));

		xdmadTxCfg.mbr_bc = 0;
		xdmadTxCfg.mbr_sus = 0;
		xdmadTxCfg.mbr_dus = 0;

		/* SPI RX DMA config */

		xdmadRxCfg.mbr_da  =  (uint32_t)pBuffer->pDataRx;
		xdmadRxCfg.mbr_sa  =  (uint32_t)&pQspiHw->QSPI_RDR;
		xdmadRxCfg.mbr_ubc =   (pBuffer->RxDataSize);
		xdmadRxCfg.mbr_cfg =    XDMAC_CC_TYPE_PER_TRAN |
								XDMAC_CC_MBSIZE_SINGLE |
								XDMAC_CC_DSYNC_PER2MEM |
								XDMAC_CC_CSIZE_CHK_1 |
								XDMAC_CC_DWIDTH_BYTE |
								XDMAC_CC_SIF_AHB_IF1 |
								XDMAC_CC_DIF_AHB_IF0 |
								XDMAC_CC_SAM_FIXED_AM |
								XDMAC_CC_DAM_INCREMENTED_AM |
								XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
											   (qspi_id, XDMAD_TRANSFER_RX));

		xdmadRxCfg.mbr_bc = 0;
		xdmadRxCfg.mbr_sus = 0;
		xdmadRxCfg.mbr_dus = 0;
		xdmaCndc = 0;
		/* Put all interrupts on for non LLI list setup of DMA */
		xdmaInt =  (XDMAC_CIE_BIE   |
					XDMAC_CIE_RBIE  |
					XDMAC_CIE_WBIE  |
					XDMAC_CIE_ROIE);

		memory_barrier();

		if (XDMAD_ConfigureTransfer
			(pQspidma->pXdmad, pQspidma->RxChNum, &xdmadRxCfg, xdmaCndc, 0, xdmaInt))
			return QSPID_ERROR;

		if (XDMAD_ConfigureTransfer
			(pQspidma->pXdmad, pQspidma->TxChNum, &xdmadTxCfg, xdmaCndc, 0, xdmaInt))
			return QSPID_ERROR;

		return 0;

	} else {
		if (ReadWrite == WriteAccess) {
			xdmadCfg.mbr_sa = (uint32_t)pBuffer->pDataTx;
			xdmadCfg.mbr_da = (uint32_t)(QSPIMEM_ADDR | Addr);
			xdmadCfg.mbr_ubc =  (pBuffer->TxDataSize);
			chanNum =  pQspidma->TxChNum;
			ChannelWidth = XDMAC_CC_DWIDTH_BYTE;
			BurstSize = XDMAC_CC_MBSIZE_SIXTEEN;
		} else if (ReadWrite == ReadAccess) {
			xdmadCfg.mbr_da = (uint32_t)pBuffer->pDataRx;
			xdmadCfg.mbr_sa = (uint32_t)(QSPIMEM_ADDR | Addr);
			xdmadCfg.mbr_ubc =  ((pBuffer->RxDataSize >> 2));
			chanNum =  pQspidma->RxChNum;
			ChannelWidth = XDMAC_CC_DWIDTH_WORD;
			BurstSize = XDMAC_CC_MBSIZE_SIXTEEN;
		} else {
예제 #16
0
/**
 * \brief Configure the UART Rx DMA mode.
 *
 * \param pUartHw   Pointer to UART instance
 * \param pXdmad    Pointer to XDMA instance
 * \param pUsartRx  Pointer to Usart Rx channel
 * \returns 0 if the dma multibuffer configuration successfully; otherwise 
 * returns USARTD_ERROR_XXX.
 */
static uint8_t _configureUartRxDma(UartDma *pUartd ,  UartChannel *pUartRx)
{
	sXdmadCfg xdmadRxCfg;
	uint32_t xdmaCndc, xdmaInt;
	uint32_t i, LLI_Size;
	Uart *pUartHwRx = pUartd->pUartHw;
	sXdmad* pXdmadRx = pUartd->pXdmad;
	uint8_t *pBuff = 0;
	
	/* Setup RX Single block */
	if(pUartRx->dmaProgrammingMode < XDMAD_LLI) {
	  xdmadRxCfg.mbr_ubc = pUartRx->BuffSize;
	  xdmadRxCfg.mbr_da = (uint32_t)pUartRx->pBuff;

	  xdmadRxCfg.mbr_sa = (uint32_t)&pUartHwRx->UART_RHR;
	  xdmadRxCfg.mbr_cfg =  XDMAC_CC_TYPE_PER_TRAN |
							XDMAC_CC_MBSIZE_SIXTEEN |
							XDMAC_CC_DSYNC_PER2MEM |
							XDMAC_CC_CSIZE_CHK_1 |
							XDMAC_CC_DWIDTH_BYTE |
							XDMAC_CC_SIF_AHB_IF1 |
							XDMAC_CC_DIF_AHB_IF0 |
							XDMAC_CC_SAM_FIXED_AM |
							XDMAC_CC_DAM_INCREMENTED_AM |
							XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
								( pUartd->uartId, XDMAD_TRANSFER_RX ));

	  xdmadRxCfg.mbr_bc = 0;
	  if(pUartRx->dmaProgrammingMode == XDMAD_MULTI) {
		xdmadRxCfg.mbr_bc = pUartRx->dmaBlockSize;
	  }
	  xdmadRxCfg.mbr_sus = 0;
	  xdmadRxCfg.mbr_dus =0;
	  xdmaCndc = 0;
	  
	  /* Put all interrupts on for non LLI list setup of DMA */
	  xdmaInt =  (XDMAC_CIE_BIE   |
				 XDMAC_CIE_DIE   |
				 XDMAC_CIE_FIE   |
				 XDMAC_CIE_RBIE  |
				 XDMAC_CIE_WBIE  |
				 XDMAC_CIE_ROIE);
			 
	} else if(pUartRx->dmaProgrammingMode == XDMAD_LLI) {
	/* Setup RX Link List */
		LLI_Size = pUartRx->dmaBlockSize;
		pBuff = pUartRx->pBuff;
		if(pUartRx->pLLIview != NULL)	{
		  free(pUartRx->pLLIview);
		  pUartRx->pLLIview = NULL;
		}
		
		pUartRx->pLLIview = malloc(sizeof(LinkedListDescriporView1)*LLI_Size);
		if( pUartRx->pLLIview == NULL) {
		  TRACE_ERROR(" Can not allocate memory to Rx LLI");
		  return USARTD_ERROR;
		}
		xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
							XDMAC_CC_MBSIZE_SIXTEEN |
							XDMAC_CC_DSYNC_PER2MEM |
							XDMAC_CC_MEMSET_NORMAL_MODE |
							XDMAC_CC_CSIZE_CHK_1 |
							XDMAC_CC_DWIDTH_BYTE |
							XDMAC_CC_SIF_AHB_IF1 |
							XDMAC_CC_DIF_AHB_IF0 |
							XDMAC_CC_SAM_FIXED_AM |
							XDMAC_CC_DAM_INCREMENTED_AM |
							XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( 
								pUartd->uartId, XDMAD_TRANSFER_RX ));
		xdmadRxCfg.mbr_bc = 0;
		for (i = 0; i < LLI_Size; i++) {
			 pUartRx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
								XDMA_UBC_NSEN_UNCHANGED | 
								XDMA_UBC_NDEN_UPDATED |
								((i== LLI_Size- 1)? ( (pUartRx->dmaRingBuffer)?
								XDMA_UBC_NDE_FETCH_EN : 0): 
								XDMA_UBC_NDE_FETCH_EN) | pUartRx->BuffSize;
				pUartRx->pLLIview[i].mbr_sa = (uint32_t)&pUartHwRx->UART_RHR;
				pUartRx->pLLIview[i].mbr_da = (uint32_t)pBuff;
				pUartRx->pLLIview[i].mbr_nda = (i == ( LLI_Size - 1))? 
					( (pUartRx->dmaRingBuffer)? (uint32_t)pUartRx->pLLIview : 0 ):
					(uint32_t)&pUartRx->pLLIview[ i + 1 ];
				pBuff += pUartRx->BuffSize;
			} 
		xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | 
				   XDMAC_CNDC_NDE_DSCR_FETCH_EN |
				   XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED|
				   XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
		
		xdmaInt = ((pUartRx->dmaRingBuffer)? XDMAC_CIE_BIE : XDMAC_CIE_LIE);
		
	} else {
	  return 1;
	}
	memory_barrier();
	if (XDMAD_ConfigureTransfer( pXdmadRx, pUartRx->ChNum, &xdmadRxCfg,
			xdmaCndc, (uint32_t)pUartRx->pLLIview, xdmaInt))
		 return USARTD_ERROR;
	return 0;
}
예제 #17
0
/**
 * \brief Configure the SPI/SMC tx/rx DMA.
 * \returns 0 if the xDMA configuration successfully; otherwise returns
 * ILI9488_ERROR_XXX.
 */
static uint8_t _ILI9488DmaConfigureRxTx(void)
{
    uint32_t txAddress,rxAddress;
    sXdmad *pXdmad;
    pXdmad = ili9488Dma.xdmaD;

#if !defined(BOARD_LCD_SMC)
    txAddress = (uint32_t)&ILI9488_SPI->SPI_TDR;
    rxAddress = (uint32_t)&ILI9488_SPI->SPI_RDR;
    ili9488Dma.xdmadExtTxCfg.mbr_cfg =
        XDMAC_CC_TYPE_PER_TRAN
        | XDMAC_CC_DSYNC_MEM2PER
        | XDMAC_CC_DWIDTH_BYTE
        | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ili9488Dma.spiId, XDMAD_TRANSFER_TX ));

    ili9488Dma.xdmadExtRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_DSYNC_PER2MEM |
                                       XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ili9488Dma.spiId, XDMAD_TRANSFER_RX ));
#else
    txAddress = rxAddress =(uint32_t)ILI9488_BASE_ADDRESS;
    ili9488Dma.xdmadExtTxCfg.mbr_cfg = XDMAC_CC_DWIDTH_HALFWORD;
    ili9488Dma.xdmadExtRxCfg.mbr_cfg = 0;
#endif

    /* Setup DMA TX channel */
    ili9488Dma.xdmadTxCfg.mbr_sa = 0;
    ili9488Dma.xdmadTxCfg.mbr_da = txAddress;
    ili9488Dma.xdmadTxCfg.mbr_ubc =  XDMA_UBC_NVIEW_NDV0 |  XDMA_UBC_NDE_FETCH_DIS| XDMA_UBC_NSEN_UPDATED ;

    ili9488Dma.xdmadTxCfg.mbr_cfg =
        XDMAC_CC_TYPE_MEM_TRAN
        | XDMAC_CC_MBSIZE_SINGLE
        | XDMAC_CC_CSIZE_CHK_1
        | XDMAC_CC_SIF_AHB_IF0
        | XDMAC_CC_DIF_AHB_IF1
        | XDMAC_CC_SAM_INCREMENTED_AM
        | XDMAC_CC_DAM_FIXED_AM;

    ili9488Dma.xdmadTxCfg.mbr_cfg |= ili9488Dma.xdmadExtTxCfg.mbr_cfg;

    ili9488Dma.xdmadTxCfg.mbr_bc = 0;
    ili9488Dma.xdmadTxCfg.mbr_sus = 0;
    ili9488Dma.xdmadTxCfg.mbr_dus = 0;

    /* Setup RX DMA channel */
    ili9488Dma.xdmadRxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 | XDMA_UBC_NDE_FETCH_DIS | XDMA_UBC_NDEN_UPDATED ;
    ili9488Dma.xdmadRxCfg.mbr_da = 0;
    ili9488Dma.xdmadRxCfg.mbr_sa = rxAddress;

    ili9488Dma.xdmadRxCfg.mbr_cfg =
        XDMAC_CC_TYPE_MEM_TRAN
        | XDMAC_CC_MBSIZE_SINGLE
        | XDMAC_CC_CSIZE_CHK_1
        | XDMAC_CC_DWIDTH_WORD
        | XDMAC_CC_SIF_AHB_IF1
        | XDMAC_CC_DIF_AHB_IF0
        | XDMAC_CC_SAM_FIXED_AM
        | XDMAC_CC_DAM_INCREMENTED_AM;

    ili9488Dma.xdmadRxCfg.mbr_cfg |= ili9488Dma.xdmadExtRxCfg.mbr_cfg;
    ili9488Dma.xdmadRxCfg.mbr_bc = 0;
    ili9488Dma.xdmadRxCfg.mbr_sus = 0;
    ili9488Dma.xdmadRxCfg.mbr_dus =0;

    /* Put all interrupts on for non LLI list setup of DMA */
    ili9488Dma.xdmaInt =  (XDMAC_CIE_BIE
                           | XDMAC_CIE_RBIE
                           | XDMAC_CIE_WBIE
                           | XDMAC_CIE_ROIE);

    if (XDMAD_ConfigureTransfer( pXdmad, ili9488Dma.ili9488DmaRxChannel, &ili9488Dma.xdmadRxCfg, 0, 0, ili9488Dma.xdmaInt))
        return ILI9488_ERROR_DMA_CONFIGURE;

    if (XDMAD_ConfigureTransfer( pXdmad, ili9488Dma.ili9488DmaTxChannel, &ili9488Dma.xdmadTxCfg, 0, 0, ili9488Dma.xdmaInt))
        return ILI9488_ERROR_DMA_CONFIGURE;
    return 0;
}
예제 #18
0
static uint32_t _MciDMA(sMcid *pMcid, uint32_t bFByte, uint8_t bRd)
{
    Hsmci *pHw = pMcid->pMciHw;
    sXdmad *pXdmad = pMcid->pXdmad;
    sSdmmcCommand *pCmd = pMcid->pCmd;
    sXdmadCfg xdmadRxCfg,xdmadTxCfg;
    uint32_t xdmaCndc;
    uint32_t hsmciId;
    uint8_t i;
    uint32_t totalSize = pCmd->wNbBlocks * pCmd->wBlockSize;
    uint32_t maxXSize;
    uint32_t memAddress;
    uint8_t  bMByte;

    if (pMcid->dwXfrNdx >= totalSize) return 0;
    /* Prepare DMA transfer */
    if(pCmd->wBlockSize != 1) {
        pMcid->dwXSize = totalSize - pMcid->dwXfrNdx;
        hsmciId = ((unsigned int)pHw == (unsigned int)HSMCI0 )? ID_HSMCI0: ID_HSMCI1;
        if (bRd) {
            //printf("_MciDMA read %d,%d \n\r",pCmd->wBlockSize, pCmd->bCmd );
            for ( i = 0; i < pCmd->wNbBlocks; i++) {
                dmaLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
                                         | (( i == pCmd->wNbBlocks - 1) ? 0: XDMA_UBC_NDE_FETCH_EN)
                                         | XDMA_UBC_NDEN_UPDATED
                                         | pCmd->wBlockSize /4 ;
                dmaLinkList[i].mbr_sa  = (uint32_t)&(pHw->HSMCI_FIFO[i]);
                dmaLinkList[i].mbr_da = (uint32_t)&pCmd->pData[i * pCmd->wBlockSize];
                if ( i == pCmd->wNbBlocks - 1)
                    dmaLinkList[i].mbr_nda = 0;
                else
                    dmaLinkList[i].mbr_nda = (uint32_t)&dmaLinkList[ i + 1 ];
            }
            xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
                                 | XDMAC_CC_MBSIZE_SINGLE
                                 | XDMAC_CC_DSYNC_PER2MEM
                                 | XDMAC_CC_CSIZE_CHK_1
                                 | XDMAC_CC_DWIDTH_WORD
                                 | XDMAC_CC_SIF_AHB_IF1
                                 | XDMAC_CC_DIF_AHB_IF0
                                 | XDMAC_CC_SAM_FIXED_AM
                                 | XDMAC_CC_DAM_INCREMENTED_AM
                                 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( 0, hsmciId, XDMAD_TRANSFER_RX ));
            xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
                       | XDMAC_CNDC_NDE_DSCR_FETCH_EN
                       | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
                       | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
            if (XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh, &xdmadRxCfg, xdmaCndc, (uint32_t)&dmaLinkList[0])) {
                return 0;
            }
            if (XDMAD_StartTransfer(pXdmad,pMcid->dwDmaCh)) {
                return 0;
            }
            //Write
        } else {
            //printf("_MciDMA write %d,%d \n\r",pCmd->wBlockSize, pCmd->bCmd );
            for ( i = 0; i < pCmd->wNbBlocks; i++) {
                dmaLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
                                         |(( i == pCmd->wNbBlocks - 1) ? 0: XDMA_UBC_NDE_FETCH_EN)
                                         | XDMA_UBC_NDEN_UPDATED
                                         | pCmd->wBlockSize /4 ;
                dmaLinkList[i].mbr_sa = (uint32_t)&pCmd->pData[i * pCmd->wBlockSize];
                dmaLinkList[i].mbr_da = (uint32_t)&(pHw->HSMCI_FIFO[i]);
                if ( i == pCmd->wNbBlocks - 1) dmaLinkList[i].mbr_nda = 0;
                else dmaLinkList[i].mbr_nda = (uint32_t)&dmaLinkList[ i + 1 ];
            }
            xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
                                 | XDMAC_CC_MBSIZE_SINGLE
                                 | XDMAC_CC_DSYNC_MEM2PER
                                 | XDMAC_CC_CSIZE_CHK_1
                                 | XDMAC_CC_DWIDTH_WORD
                                 | XDMAC_CC_SIF_AHB_IF0
                                 | XDMAC_CC_DIF_AHB_IF1
                                 | XDMAC_CC_SAM_INCREMENTED_AM
                                 | XDMAC_CC_DAM_FIXED_AM
                                 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( 0, hsmciId, XDMAD_TRANSFER_TX ));
            xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
                       | XDMAC_CNDC_NDE_DSCR_FETCH_EN
                       | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
                       | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
            if(XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh, &xdmadTxCfg, xdmaCndc, (uint32_t)&dmaLinkList[0])) {
                return 0;
            }
            if (XDMAD_StartTransfer(pXdmad,pMcid->dwDmaCh)) {
                return 0;
            }
        }
    } else {
        /* Memory address and alignment */
        memAddress = (uint32_t)&pCmd->pData[pMcid->dwXfrNdx];
        bMByte = bFByte ? 1 : (((memAddress & 0x3) || (totalSize & 0x3)));
        /* P to M: Max size is P size */
        if (bRd) {
            maxXSize = bFByte ? MAX_DMA_SIZE : (MAX_DMA_SIZE * 4);
        }
        /* M to P: Max size is M size */
        else {
            maxXSize = bMByte ? MAX_DMA_SIZE : (MAX_DMA_SIZE * 4);
        }
        /* Update index */
        pMcid->dwXSize = totalSize - pMcid->dwXfrNdx;
        if (pMcid->dwXSize > maxXSize) {
            pMcid->dwXSize = maxXSize;
        }
        /* Prepare DMA transfer */
        if (bRd) {
            xdmadRxCfg.mbr_ubc = bFByte ? pMcid->dwXSize : toWCOUNT(pMcid->dwXSize);
            xdmadRxCfg.mbr_sa = (uint32_t)&(pHw->HSMCI_RDR);
            xdmadRxCfg.mbr_da = (uint32_t)memAddress;
            xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
                                 XDMAC_CC_MEMSET_NORMAL_MODE |
                                 XDMAC_CC_DSYNC_PER2MEM|
                                 XDMAC_CC_CSIZE_CHK_1 |
                                 (bFByte ? XDMAC_CC_DWIDTH_BYTE : XDMAC_CC_DWIDTH_WORD) |
                                 XDMAC_CC_SIF_AHB_IF1 |
                                 XDMAC_CC_DIF_AHB_IF0 |
                                 XDMAC_CC_SAM_FIXED_AM |
                                 XDMAC_CC_DAM_INCREMENTED_AM;
            xdmadRxCfg.mbr_bc = 0;
            XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh, &xdmadRxCfg, 0, 0);
            //CP15_coherent_dcache_for_dma ((uint32_t)memAddress, ((uint32_t)memAddress + (pMcid->dwXSize)));
        } else {
            xdmadTxCfg.mbr_ubc = toWCOUNT(pMcid->dwXSize);
            xdmadTxCfg.mbr_sa = (uint32_t)memAddress;
            xdmadTxCfg.mbr_da = (uint32_t)&(pHw->HSMCI_TDR);
            xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
                                 XDMAC_CC_MEMSET_NORMAL_MODE |
                                 XDMAC_CC_DSYNC_MEM2PER |
                                 XDMAC_CC_CSIZE_CHK_1 |
                                 (bFByte ? XDMAC_CC_DWIDTH_BYTE : XDMAC_CC_DWIDTH_WORD) |
                                 XDMAC_CC_SIF_AHB_IF0 |
                                 XDMAC_CC_DIF_AHB_IF1 |
                                 XDMAC_CC_SAM_INCREMENTED_AM |
                                 XDMAC_CC_DAM_FIXED_AM;
            xdmadTxCfg.mbr_bc = 0;
            XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh, &xdmadTxCfg, 0, 0);
        }
        XDMAD_StartTransfer(pXdmad, pMcid->dwDmaCh);
    }

    return 1;
}