示例#1
0
/*
** This configures the PaRAM set for the Dummy Transfer.
*/
static void TxDummyPaRAMConfEnable(void)
{
    EDMA3CCPaRAMEntry dummyPaRAMSet;

    EDMA3GetPaRAM(SOC_EDMA30CC_0_REGS, DUMMY_CH_NUM, &dummyPaRAMSet);

    dummyPaRAMSet.aCnt = 1;
    dummyPaRAMSet.bCnt = 0;
    dummyPaRAMSet.cCnt = 0;
    dummyPaRAMSet.srcAddr = 0;
    dummyPaRAMSet.destAddr = 0;
    dummyPaRAMSet.srcBIdx = 0;
    dummyPaRAMSet.destBIdx = 0;
    dummyPaRAMSet.srcCIdx = 0;
    dummyPaRAMSet.destCIdx = 0;
    dummyPaRAMSet.linkAddr = 0xFFFFu;
    dummyPaRAMSet.bCntReload = 0;
    dummyPaRAMSet.opt = 0;

    EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, DUMMY_CH_NUM, &dummyPaRAMSet);
}
示例#2
0
/**
 * Write block(s) from MMC/SD card. The implementation follows
 * '26.3.5 MMC/SD Mode Single-Block Read Operation Using EDMA' in 'spruh82a'.
 * @param  mmcsdCtrlInfo It holds the mmcsd control information.
 * @param  ptr           It determines the address from where data has to written
 * @param  block         It determines to which block data to be written (block >= 0)
 * @param  nblks         It determines the number of blocks to be written (nblks >= 1)
 * @retval 1             success
 * @retval 0             fail
 */
unsigned int
MMCSDWriteCmdSend(mmcsdCtrlInfo *ctrl, void *ptr, unsigned int block, unsigned int nblks) {
	// TODO: workaround for buggy WRITE_MULTI_BLOCK
	if (nblks > 1) {
		for (unsigned int i = 0; i < nblks; ++i) {
			unsigned int res = MMCSDWriteCmdSend(ctrl, ptr + i * MMCSD_MAX_BLOCK_LEN, block + i, 1);
			assert(res == 1);
		}
		return 1;
	}
	assert(nblks == 1);

	unsigned int status = 1; // 1 for success
	volatile struct st_mmcsd *mmc = ctrl->memBase;
	ER ercd;

	/* 1. Write the card's relative address to the MMC argument registers (MMCARGH and MMCARGL). */
	mmcsdCardInfo *card = ctrl->card;
	unsigned int address;
	/*
	 * TODO: check this -- ertl-liyixiao
	 * Address is in blks for high cap cards and in actual bytes
	 * for standard capacity cards
	 */
	assert(card->highCap);
	if (card->highCap)
		address = block;
	else
		address = block * card->blkLen;
	mmc->MMCARGHL = address;

	/* 2. Read card CSD to determine the card's maximum block length. */
	// TODO:
//	syslog(LOG_ERROR, "card->raw_csd[0]: 0x%08x", card->raw_csd[0]);
//	syslog(LOG_ERROR, "card->raw_csd[1]: 0x%08x", card->raw_csd[1]);
//	syslog(LOG_ERROR, "card->raw_csd[2]: 0x%08x", card->raw_csd[2]);
//	syslog(LOG_ERROR, "card->raw_csd[3]: 0x%08x", card->raw_csd[3]);
	syslog(LOG_ERROR, "MMCCTL: 0x%08x", mmc->MMCCTL);


	/* 3. Use the MMC command register (MMCCMD) to send the SET_BLOCKLEN command (if the block
	 length is different than the length used in the previous operation). The block length must be a multiple
	 of 512 bytes and less then the maximum block length specified in the CSD. */
	syslog(LOG_ERROR, "MMCCTL: 0x%08x", mmc->MMCCTL);
	syslog(LOG_ERROR, "MMCCLK: 0x%08x", mmc->MMCBLEN);
	// TODO:

	/* 4. Reset the FIFO (FIFORST bit in MMCFIFOCTL). */
	mmc->MMCFIFOCTL |= MMCSD_MMCFIFOCTL_FIFORST;
	mmc->MMCFIFOCTL &= ~MMCSD_MMCFIFOCTL_FIFORST;

	/* 5. Set the FIFO direction to send (FIFODIR bit in MMCFIFOCTL). */
	mmc->MMCFIFOCTL |= MMCSD_MMCFIFOCTL_FIFODIR;

	/* 6. Set the access width (ACCWD bits in MMCFIFOCTL). */
	mmc->MMCFIFOCTL &= ~MMCSD_MMCFIFOCTL_ACCWD;
	mmc->MMCFIFOCTL |= (MMCSD_MMCFIFOCTL_ACCWD_4BYTES << MMCSD_MMCFIFOCTL_ACCWD_SHIFT); // => 4 bytes

	/* 7. Set the FIFO threshold (FIFOLEV bit in MMCFIFOCTL). */
	mmc->MMCFIFOCTL |=  MMCSD_MMCFIFOCTL_FIFOLEV; // => 64 bytes

	/* 8. Set up DMA (DMA size needs to be greater than or equal to FIFOLEV setting). */
	CacheDataCleanBuff((unsigned int) ptr, (MMCSD_MAX_BLOCK_LEN * nblks)); // Clean data buffer to send
	arm926_drain_write_buffer(); // Memory barrier for data buffer to send
	ctrl->xferSetup(ctrl, 0, ptr, MMCSD_MAX_BLOCK_LEN, nblks);
	{
		syslog(LOG_ERROR, "origSrcAddr: 0x%08x", ptr);
		EDMA3CCPaRAMEntry param;
		EDMA3GetPaRAM(&EDMA3_CC0, EDMA3_CHA_MMCSD0_TX, &param);
		syslog(LOG_ERROR, "srcAddr: 0x%08x", param.srcAddr);
	}

	/* 9. Use MMCCMD to send the WRITE_BLOCK command to the card. */
#if defined(DEBUG)
	syslog(LOG_ERROR, "%s(): Use MMCCMD to send the WRITE_BLOCK/WRITE_MULTI_BLOCK command to the card.", __FUNCTION__);
#endif
	mmcsdCmd cmd;
	cmd.flags = SD_CMDRSP_R1 | SD_CMDRSP_WRITE | SD_CMDRSP_DATA;
	cmd.arg = address;
	cmd.nblks = nblks;
	if (nblks > 1) {
	    cmd.idx = SD_CMD(25);
	    cmd.flags |= SD_CMDRSP_ABORT;
	} else {
	    cmd.idx = SD_CMD(24);
	}
	status = MMCSDCmdSend(ctrl, &cmd);
	if (status == 0) {
		syslog(LOG_ERROR, "%s(): MMCSDCmdSend() failed.", __FUNCTION__);
		goto error_exit;
	}

	// CPU Mode
//	uint32_t *buf = ptr; // Assume uint32_t is little-endian

//	while (1) {
//		EDMA3CCPaRAMEntry param;
////		syslog(LOG_ERROR, "MMCSD0.MMCST0: 0x%08x", MMCSD0.MMCST0);
////		syslog(LOG_ERROR, "MMCSD0.MMCST1: 0x%08x", MMCSD0.MMCST1);
////		syslog(LOG_ERROR, "EDMA3_CC0.ER: 0x%08x", EDMA3_CC0.ER);
////		syslog(LOG_ERROR, "EDMA3_CC0.EMR: 0x%08x", EDMA3_CC0.EMR);
////		syslog(LOG_ERROR, "EDMA3_CC0.SER: 0x%08x", EDMA3_CC0.SER);
//		EDMA3GetPaRAM(&EDMA3_CC0, EDMA3_CHA_MMCSD0_TX, &param);
////		syslog(LOG_ERROR, "origSrcAddr: 0x%08x", ptr);
//		syslog(LOG_ERROR, "srcAddr: 0x%08x", param.srcAddr);
////		syslog(LOG_ERROR, "CCNT: %d", param.cCnt);
//
//		tslp_tsk(1000);
//	}

	/* 10. Set the DMATRIG bit in MMCCMD to trigger the first data transfer. */
#if DEBUG_PRINT
//	syslog(LOG_ERROR, "%s(): Set the DMATRIG bit, MMCCMD: 0x%08x=>0x%08x", __FUNCTION__, mmc->MMCCMD, mmc->MMCCMD | MMCSD_MMCCMD_DMATRIG);
#endif
//	mmc->MMCCMD /*|*/= MMCSD_MMCCMD_DMATRIG;

	/* 11. Wait for DMA sequence to complete. */
	status = ctrl->xferStatusGet(ctrl);
	if (status == 0) { assert(false); goto error_exit; }

error_exit:

	return status;

#if 0
  mmcsdCardInfo *card = ctrl->card;
  unsigned int status = 0;
  unsigned int address;
  mmcsdCmd cmd;

#if DEBUG_PRINT
  UARTprintf("----\r\n");
  UARTprintf("%s(0x%x)\r\n", __FUNCTION__, ctrl);
#endif


  }
void EDMAAppEDMA3Test()
{
    volatile unsigned int index = 0u;
    volatile unsigned int count = 0u;
    EDMA3CCPaRAMEntry paramSet;
    unsigned char data = 0u;
    volatile unsigned int retVal = 0u;
    unsigned int isTestPassed = false;
    unsigned int numEnabled = 0u;
    unsigned int aCount = EDMAAPP_MAX_ACOUNT;
    unsigned int bCount = EDMAAPP_MAX_BCOUNT;
    unsigned int cCount = EDMAAPP_MAX_CCOUNT;

    /* Initalize source and destination buffers */
    for (count = 0u; count < (aCount * bCount * cCount); count++)
    {
        SrcBuff[count] = data++;
        /*
        ** No need to initialize the destination buffer as it is
        ** being invalidated.
        */
    }

    /* Request DMA channel and TCC */
    retVal = EDMA3RequestChannel(EDMAAPP_EDMACC_BASE_ADDRESS,
                                 EDMAAPP_DMA_CH_TYPE, EDMAAPP_DMA_CH_NUM,
                                 EDMAAPP_DMA_TCC_NUM, EDMAAPP_DMA_EVTQ);

    /* Registering Callback Function */
    EDMAAppCallbackFxn[EDMAAPP_DMA_TCC_NUM] = &EDMAAppCallback;

    if(TRUE == retVal)
    {
        /* Fill the PaRAM Set with transfer specific information */
        paramSet.srcAddr = (unsigned int)(SrcBuff);
        paramSet.destAddr = (unsigned int)(DstBuff);

        paramSet.aCnt = (unsigned short)aCount;
        paramSet.bCnt = (unsigned short)bCount;
        paramSet.cCnt = (unsigned short)cCount;

        /* Setting up the SRC/DES Index */
        paramSet.srcBIdx = (short)aCount;
        paramSet.destBIdx = (short)aCount;

        if(EDMA3_SYNC_A == EDMAAPP_DMA_SYNC_TYPE)
        {
            /* A Sync Transfer Mode */
            paramSet.srcCIdx = (short)aCount;
            paramSet.destCIdx = (short)aCount;
        }
        else
        {
            /* AB Sync Transfer Mode */
            paramSet.srcCIdx = ((short)aCount * (short)bCount);
            paramSet.destCIdx = ((short)aCount * (short)bCount);
        }

        /* Configure the paramset with NULL link */
        paramSet.linkAddr = (unsigned short)0xFFFFu;

        paramSet.bCntReload = (unsigned short)0u;
        paramSet.opt = 0u;

        /* Src & Dest are in INCR modes */
        paramSet.opt &= ~(EDMA3CC_OPT_SAM | EDMA3CC_OPT_DAM);

        /* Program the TCC */
        paramSet.opt |= ((EDMAAPP_DMA_TCC_NUM << EDMA3CC_OPT_TCC_SHIFT)
                         & EDMA3CC_OPT_TCC);

        /* Enable Intermediate & Final transfer completion interrupt */
        paramSet.opt |= (1u << EDMA3CC_OPT_ITCINTEN_SHIFT);
        paramSet.opt |= (1u << EDMA3CC_OPT_TCINTEN_SHIFT);

        if(EDMA3_SYNC_A == EDMAAPP_DMA_SYNC_TYPE)
        {
            paramSet.opt &= ~EDMA3CC_OPT_SYNCDIM;
        }
        else
        {
            /* AB Sync Transfer Mode */
            paramSet.opt |= (1u << EDMA3CC_OPT_SYNCDIM_SHIFT);
        }

        /* Now, write the PaRAM Set. */
        EDMA3SetPaRAM(EDMAAPP_EDMACC_BASE_ADDRESS, EDMAAPP_DMA_CH_NUM,
                      &paramSet);

        EDMA3GetPaRAM(EDMAAPP_EDMACC_BASE_ADDRESS, EDMAAPP_DMA_CH_NUM,
                      &paramSet);
    }

    /*
    ** Since the transfer is going to happen in Manual mode of EDMA3
    ** operation, we have to 'Enable the Transfer' multiple times.
    ** Number of times depends upon the Mode (A/AB Sync)
    ** and the different counts.
    */
    if(TRUE == retVal)
    {
        /* Need to activate next param */
        if(EDMA3_SYNC_A == EDMAAPP_DMA_SYNC_TYPE)
        {
            numEnabled = bCount * cCount;
        }
        else
        {
            /* AB Sync Transfer Mode */
            numEnabled = cCount;
        }

        for(index = 0u; index < numEnabled; index++)
        {
            IrqRaised = EDMAAPP_IRQ_STATUS_XFER_INPROG;

            /*
            ** Now enable the transfer as many times as calculated above.
            */
            retVal = EDMA3EnableTransfer(EDMAAPP_EDMACC_BASE_ADDRESS,
                                         EDMAAPP_DMA_CH_NUM,
                                         EDMAAPP_DMA_TRIG_MODE);

            /* Wait for the Completion ISR. */
            while(EDMAAPP_IRQ_STATUS_XFER_INPROG == IrqRaised)
            {
                /*
                ** Wait for the Completion ISR on Master Channel.
                ** You can insert your code here to do something
                ** meaningful.
                */
            }

            /* Check the status of the completed transfer */
            if(IrqRaised < (int)EDMAAPP_IRQ_STATUS_XFER_INPROG)
            {
                /* Some error occured, break from the FOR loop. */
                ConsoleUtilsPrintf("\r\nEDMA3Test: Event Miss Occured!!!\r\n");

                /* Clear the error bits first */
                EDMA3ClearErrorBits(EDMAAPP_EDMACC_BASE_ADDRESS,
                                    EDMAAPP_DMA_CH_NUM, EDMAAPP_DMA_EVTQ);
                break;
            }
        }
    }

    /* Match the Source and Destination Buffers. */
    if(TRUE == retVal)
    {
        for(index = 0u; index < (aCount * bCount * cCount); index++)
        {
            if(SrcBuff[index] != DstBuff[index])
            {
                isTestPassed = false;
                ConsoleUtilsPrintf("EDMA3Test: Data write-read matching FAILED.\r\n");
                ConsoleUtilsPrintf("The mismatch happened at index : %d\r\n",
                                   ((int)index + 1u));
                break;
            }
        }

        if(index == (aCount * bCount * cCount))
        {
            isTestPassed = true;
            ConsoleUtilsPrintf("EDMA3Test: Data write-read matching PASSED.\r\n");
        }

        /* Free the previously allocated channel. */
        retVal = EDMA3FreeChannel(EDMAAPP_EDMACC_BASE_ADDRESS,
                                  EDMAAPP_DMA_CH_TYPE, EDMAAPP_DMA_CH_NUM,
                                  EDMAAPP_DMA_TRIG_MODE, EDMAAPP_DMA_TCC_NUM,
                                  EDMAAPP_DMA_EVTQ);

        /* Unregister Callback Function */
        EDMAAppCallbackFxn[EDMAAPP_DMA_TCC_NUM] = NULL;

        if(TRUE != retVal)
        {
            ConsoleUtilsPrintf("EDMA3Test: EDMA3_DRV_freeChannel() FAILED.\r\n");
        }
    }

    if(true == isTestPassed)
    {
        ConsoleUtilsPrintf("EDMA3Test PASSED.\r\n");
    }
    else
    {
        ConsoleUtilsPrintf("EDMA3Test FAILED\r\n");
    }
}