Exemplo n.º 1
0
/**
*
* API to setup ADMA2 descriptor table
*
*
* @param	InstancePtr is a pointer to the XSdPs instance.
* @param	BlkCnt - block count.
* @param	Buff pointer to data buffer.
*
* @return	None
*
* @note		None.
*
******************************************************************************/
void XSdPs_SetupADMA2DescTbl(XSdPs *InstancePtr, u32 BlkCnt, const u8 *Buff)
{
	u32 TotalDescLines = 0;
	u32 DescNum = 0;
	u32 BlkSize = 0;

	/*
	 * Setup ADMA2 - Write descriptor table and point ADMA SAR to it
	 */
	BlkSize = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
					XSDPS_BLK_SIZE_OFFSET);
	BlkSize = BlkSize & XSDPS_BLK_SIZE_MASK;

	if((BlkCnt*BlkSize) < XSDPS_DESC_MAX_LENGTH) {

		TotalDescLines = 1;

	}else {

		TotalDescLines = ((BlkCnt*BlkSize) / XSDPS_DESC_MAX_LENGTH);
		if ((BlkCnt * BlkSize) % XSDPS_DESC_MAX_LENGTH)
			TotalDescLines += 1;

	}

	for (DescNum = 0; DescNum < (TotalDescLines-1); DescNum++) {
		InstancePtr->Adma2_DescrTbl[DescNum].Address =
				(u32)(Buff + (DescNum*XSDPS_DESC_MAX_LENGTH));
		InstancePtr->Adma2_DescrTbl[DescNum].Attribute =
				XSDPS_DESC_TRAN | XSDPS_DESC_VALID;
		/*
		 * This will write '0' to length field which indicates 65536
		 */
		InstancePtr->Adma2_DescrTbl[DescNum].Length =
				(u16)XSDPS_DESC_MAX_LENGTH;
	}

	InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Address =
			(u32)(Buff + (DescNum*XSDPS_DESC_MAX_LENGTH));

	InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Attribute =
			XSDPS_DESC_TRAN | XSDPS_DESC_END | XSDPS_DESC_VALID;

	InstancePtr->Adma2_DescrTbl[TotalDescLines-1].Length =
			(BlkCnt*BlkSize) - (DescNum*XSDPS_DESC_MAX_LENGTH);


	XSdPs_WriteReg(InstancePtr->Config.BaseAddress, XSDPS_ADMA_SAR_OFFSET,
			(u32)&(InstancePtr->Adma2_DescrTbl[0]));

	Xil_DCacheFlushRange(&(InstancePtr->Adma2_DescrTbl[0]),
			sizeof(XSdPs_Adma2Descriptor) * 32);

}
Exemplo n.º 2
0
/**

* This function does SD command generation.
*
* @param	InstancePtr is a pointer to the instance to be worked on.
* @param	Cmd is the command to be sent.
* @param	Arg is the argument to be sent along with the command.
* 		This could be address or any other information
* @param	BlkCnt - Block count passed by the user.
*
* @return
* 		- XST_SUCCESS if initialization was successful
* 		- XST_FAILURE if failure - could be because another transfer
* 			is in progress or command or data inhibit is set
*
******************************************************************************/
s32 XSdPs_CmdTransfer(XSdPs *InstancePtr, u32 Cmd, u32 Arg, u32 BlkCnt)
{
	u32 PresentStateReg;
	u32 CommandReg;
	u32 StatusReg;
	s32 Status;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Check the command inhibit to make sure no other
	 * command transfer is in progress
	 */
	PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
			XSDPS_PRES_STATE_OFFSET);
	if ((PresentStateReg & XSDPS_PSR_INHIBIT_CMD_MASK) != 0U) {
		Status = XST_FAILURE;
		goto RETURN_PATH;
	}

	/* Write block count register */
	XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
			XSDPS_BLK_CNT_OFFSET, (u16)BlkCnt);

	XSdPs_WriteReg8(InstancePtr->Config.BaseAddress,
			XSDPS_TIMEOUT_CTRL_OFFSET, 0xEU);

	/* Write argument register */
	XSdPs_WriteReg(InstancePtr->Config.BaseAddress,
			XSDPS_ARGMT_OFFSET, Arg);

	XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
			XSDPS_NORM_INTR_STS_OFFSET, XSDPS_NORM_INTR_ALL_MASK);
	XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
			XSDPS_ERR_INTR_STS_OFFSET, XSDPS_ERROR_INTR_ALL_MASK);
	/* Command register is set to trigger transfer of command */
	CommandReg = XSdPs_FrameCmd(InstancePtr, Cmd);

	/*
	 * Mask to avoid writing to reserved bits 31-30
	 * This is necessary because 0x80000000 is used  by this software to
	 * distinguish between ACMD and CMD of same number
	 */
	CommandReg = CommandReg & 0x3FFFU;

	/*
	 * Check for data inhibit in case of command using DAT lines.
	 * For Tuning Commands DAT lines check can be ignored.
	 */
	if ((Cmd != CMD21) && (Cmd != CMD19)) {
		PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
				XSDPS_PRES_STATE_OFFSET);
		if (((PresentStateReg & (XSDPS_PSR_INHIBIT_DAT_MASK |
									XSDPS_PSR_INHIBIT_DAT_MASK)) != 0U) &&
				((CommandReg & XSDPS_DAT_PRESENT_SEL_MASK) != 0U)) {
			Status = XST_FAILURE;
			goto RETURN_PATH;
		}
	}

	XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_CMD_OFFSET,
			(u16)CommandReg);

	/* Polling for response for now */
	do {
		StatusReg = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
					XSDPS_NORM_INTR_STS_OFFSET);
		if ((Cmd == CMD21) || (Cmd == CMD19)) {
			if ((XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
					XSDPS_NORM_INTR_STS_OFFSET) & XSDPS_INTR_BRR_MASK) != 0U){
				XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
					XSDPS_NORM_INTR_STS_OFFSET, XSDPS_INTR_BRR_MASK);
				break;
			}
		}

		if ((StatusReg & XSDPS_INTR_ERR_MASK) != 0U) {
			Status = XSdPs_ReadReg16(InstancePtr->Config.BaseAddress,
									XSDPS_ERR_INTR_STS_OFFSET);
			if ((Status & ~XSDPS_INTR_ERR_CT_MASK) == 0) {
				Status = XSDPS_CT_ERROR;
			}
			 /* Write to clear error bits */
			XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
					XSDPS_ERR_INTR_STS_OFFSET,
					XSDPS_ERROR_INTR_ALL_MASK);
			goto RETURN_PATH;
		}
	} while((StatusReg & XSDPS_INTR_CC_MASK) == 0U);
	/* Write to clear bit */
	XSdPs_WriteReg16(InstancePtr->Config.BaseAddress,
			XSDPS_NORM_INTR_STS_OFFSET,
			XSDPS_INTR_CC_MASK);

	Status = XST_SUCCESS;

RETURN_PATH:
		return Status;

}