📄 c5509_mmc.c
字号:
/* No further requests are scheduled - await reset */
ptrState->currPacket = NULL;
return;
}
if (mediaStr->atomicStatus == ISTATOMICREAD) {
pPacket->cmd = IOM_WRITE;
mediaStr->atomicStatus = ISTATOMICWRITE;
mediaStr->count = 0;
newRequest = 1;
}
else if (mediaStr->atomicStatus != ISTATOMICREAD) {
CALLBACK (mediaStr->pChan, pPacket, IOM_COMPLETED);
ptrState->currPacket =
(IOM_Packet *)QUE_dequeue (&ptrState->pendList);
if ((QUE_Elem *)ptrState->currPacket != &ptrState->pendList) {
newRequest = 1;
}
else {
ptrState->currPacket = NULL;
}
}
}
}
else if (pPacket->cmd == IOM_WRITE) {
/*
* If the entire sector has been written to, set the
* stateParameter to ISTDATADONEWRITE.
*/
if (mediaStr->count >= SECLEN) {
mediaStr->stateParameter = ISTDATADONEWRITE;
}
/* State where the request will call the callback. */
if (mediaStr->count > SECLEN) {
if (error) {
CALLBACK (mediaStr->pChan, pPacket, IOM_EBADIO);
/* No further requests are scheduled - await reset */
ptrState->currPacket = NULL;
return;
}
CALLBACK (mediaStr->pChan, pPacket, IOM_COMPLETED);
ptrState->currPacket = (IOM_Packet *)QUE_dequeue (&ptrState->pendList);
if ((QUE_Elem *)ptrState->currPacket != &ptrState->pendList) {
newRequest = 1;
}
else {
ptrState->currPacket = NULL;
}
flag = 0;
}
if (flag) {
if (mediaStr->atomicStatus == ISTATOMICWRITE) {
if (mediaStr->count >= mediaStr->offset &&
mediaStr->count < (mediaStr->length +
mediaStr->offset)) {
track = mediaStr->buf[mediaStr->count - mediaStr->offset];
}
else {
track = ptrState->buf[mediaStr->count];
}
}
else {
track = mediaStr->buf[mediaStr->count];
}
if (ptrState->drvrParams.byteOrder == MEDIA_BYTESWAP) {
track = MEDIA_SWAPBYTES (track);
}
_MMC_MMCDXR_SET (ptrState->mmcDevNum, track);
mediaStr->count++;
}
}
/*
* Checking for new requests in the request queue.
* In case of ABORT and FLUSH call the callback, else
* execute the request.
*/
if (newRequest == 1) {
if ((ptrState->currPacket->cmd == IOM_ABORT) ||
(ptrState->currPacket->cmd == IOM_FLUSH)) {
afChan = (C5509_MMC_ChanObj *)ptrState->currPacket->addr;
CALLBACK (afChan, ptrState->currPacket, IOM_COMPLETED);
ptrState->currPacket = (IOM_Packet *)QUE_dequeue (&ptrState->pendList);
if ((QUE_Elem *)ptrState->currPacket != &ptrState->pendList) {
newRequest = 1;
}
else {
newRequest = 0;
ptrState->currPacket = NULL;
}
}
if (newRequest == 1) {
mediaStr = (C5509_MMC_RdWrObj *)ptrState->currPacket->addr;
mediaStr->stateParameter = ISTGETSTATUS;
_MMC_MMCCIE_SET (ptrState->mmcDevNum, REGVALMMCIESTATUS);
MMC_sendCmd (ptrState->cslMMC,MMC_SEND_STATUS,
mediaStr->pChan->pHandle->drvrParams.mmcCardId,
MMC_STUFF_BITS, 0);
}
}
}
/*
* ======== isrMMC ========
*
* Interrupt handler for MMC
*/
static Void isrMMC(Ptr ptrAttr)
{
C5509_MMC_DevObj *ptrState = (C5509_MMC_DevObj *)ptrAttr;
IOM_Packet *pPacket = ptrState->currPacket;
C5509_MMC_RdWrObj *mediaStr;
volatile Uns regST0;
Uns busy;
Uns error;
error = 0;
if (pPacket == NULL) {
return;
}
mediaStr = (C5509_MMC_RdWrObj *)pPacket->addr;
regST0 = _MMC_MMCST0_GET (ptrState->mmcDevNum);
switch (mediaStr->stateParameter) {
case ISTGETSTATUS:
/*
* Check busy incase of RSPDNE.
* If busy resend MMC_SEND_STATUS else we proceed.
*/
if (regST0 & ST0RSPDNE) {
busy = ((_MMC_MMCRSP6_GET (ptrState->mmcDevNum) >> 8) & 1);
if (!busy) {
MMC_sendCmd (ptrState->cslMMC, MMC_SEND_STATUS,
mediaStr->pChan->pHandle->drvrParams.mmcCardId,
MMC_STUFF_BITS, 0);
}
else {
if (pPacket->cmd == IOM_READ) {
_MMC_MMCCIE_SET (ptrState->mmcDevNum,
REGVALMMCIEREAD);
mediaStr->stateParameter = ISTSENDREAD;
issueReadWrite (pPacket, ptrState);
}
else if (pPacket->cmd == IOM_WRITE) {
_MMC_MMCCIE_SET (ptrState->mmcDevNum,
REGVALMMCIEWRITE);
regST0 = _MMC_MMCST0_GET (ptrState->mmcDevNum);
mediaStr->stateParameter = ISTSENDWRITE;
issueReadWrite (pPacket, ptrState);
}
}
}
else if (regST0 & ST0TOUTRS) {
CALLBACK (mediaStr->pChan, pPacket, IOM_EBADIO);
ptrState->currPacket = NULL;
}
break;
case ISTSENDREAD:
if (regST0 & ST0DRRDY) {
_MMC_MMCST0_SET (ptrState->mmcDevNum, 0x0000);
handlerReadWrite (pPacket, ptrState, error);
}
else if (regST0 & (ST0CRCRD | ST0CRCRS | ST0TOUTRD | ST0TOUTRS)) {
CALLBACK (mediaStr->pChan, pPacket, IOM_EBADIO);
ptrState->currPacket = NULL;
}
break;
case ISTSENDWRITE:
if (regST0 & ST0DXRDY) {
handlerReadWrite (pPacket, ptrState, error);
}
else if (regST0 & (ST0CRCWR | ST0TOUTRS)) {
CALLBACK (mediaStr->pChan, pPacket, IOM_EBADIO);
ptrState->currPacket = NULL;
}
break;
case ISTDATADONEREAD:
/* Check if DATA done bit is set. */
if (!(regST0 & ST0DATDNE) && (regST0 & ST0CRCRD)) {
error = 1;
}
handlerReadWrite (pPacket, ptrState, error);
break;
case ISTDATADONEWRITE:
/* Check if DATA done bit is set. */
if (!(regST0 & ST0DATDNE) && (regST0 & ST0DRRDY)) {
error = 1;
}
handlerReadWrite (pPacket, ptrState, error);
break;
default:
break;
}
return;
}
/*
* ======== resetMMC ========
*
* Resets the cards and selects it. This is a helper function called
* by initMMC() and reinitializeMMC().
*/
static Int resetMMC(C5509_MMC_DevObj *ptrState)
{
/* Sets the operational voltage range. */
if (MMC_sendOpCond (ptrState->cslMMC, OPVOLTAGE)) {
return (IOM_EBADIO);
}
/* Send broadcast command to all cards to identify themselves. */
if (!MMC_sendAllCID (ptrState->cslMMC, &ptrState->cslMMC->cards->cid)) {
return (IOM_EBADIO);
}
/* Set the relative address. */
if (!MMC_setRca (ptrState->cslMMC, ptrState->cslMMC->cards,
ptrState->drvrParams.mmcCardId)) {
return (IOM_EBADIO);
}
/* Select the card. */
if (!MMC_selectCard (ptrState->cslMMC, ptrState->cslMMC->cards)) {
return (IOM_EBADIO);
}
return (IOM_COMPLETED);
}
/*
* ======== initMMC ========
*
* Initialization of the device takes place here, this is called during
* bind dev. Initializes and selects a given card.
*/
static Int initMMC(C5509_MMC_DevObj *ptrState, C5509_MMC_DevParams *mmcParams)
{
Int retval;
Uns intrMask;
volatile LgUns delay = 30000;
intrMask = HWI_disable ();
/* Reserves the MMC device, specified by mmcDevNumber. */
ptrState->cslMMC = MMC_open (ptrState->mmcDevNum);
if (ptrState->cslMMC == NULL) {
HWI_restore (intrMask);
return (IOM_EBADIO);
}
ptrState->cslMMC->cards = &ptrState->cslCards;
/* All except these two parameters are supplied by the application. */
mmcParams->devParams.dat3EdgeDetection = DAT3EDGEDETECTION;
mmcParams->devParams.enableClkPin = ENABLECLKPIN;
/* Initialize the controller in native mode. */
MMC_setupNative (ptrState->cslMMC, &mmcParams->devParams);
/* Send a broadcast GO_IDLE command. */
MMC_sendGoIdle (ptrState->cslMMC);
/* Sufficient delay is needed for the MMC to reset. */
while (delay--) {
}
if ((retval = resetMMC (ptrState)) != IOM_COMPLETED) {
MMC_close (ptrState->cslMMC);
ptrState->cslMMC = (MMC_Handle)NULL;
}
/* Look at logic carefully before adding a statement here. */
HWI_restore (intrMask);
return (retval);
}
/*
* ======== reinitializeMMC ========
*
* Re-initializes the MMC and selects the card.
* This function should be called whenever the MMC in UnPlugged
* and plugged back.
*/
static inline Int reinitializeMMC(C5509_MMC_DevObj *ptrState)
{
Int retval;
Uns intrMask;
intrMask = HWI_disable ();
retval = resetMMC (ptrState);
HWI_restore (intrMask);
return (retval);
}
/*
* ======== C5509_MMC_init ========
*
* Initialization function.
*/
Void C5509_MMC_init()
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -