接下来我们来看看CSDIOControllerBase类,该类实现了主控制器驱动的硬件实现,定义了很多成员变量和函数,如有错误,欢迎指正.
CSDIOControllerBase原型如下:
- class CSDIOControllerBase
- {
- public:
- explicit CSDIOControllerBase( PSDCARD_HC_CONTEXT pHCContext );
- virtual ~CSDIOControllerBase();
-
- PSDCARD_HC_CONTEXT GetHostContext() const;
-
- virtual BOOL InterpretCapabilities( LPCTSTR pszRegistryPath );
- void OnPowerUp();
- void OnPowerDown();
- void PreDeinit();
-
- protected:
-
- virtual BOOL InitializeHardware( BOOL bOnPowerUp = FALSE ) = 0;
- virtual void DeinitializeHardware( BOOL bOnPowerDown = FALSE ) = 0;
- virtual BOOL CustomSetup( LPCTSTR pszRegistryPath ) = 0;
- virtual BOOL IsCardWriteProtected() = 0;
- virtual BOOL IsCardPresent() = 0;
-
- protected:
-
- volatile S3C2410X_SDI_REG *vm_pSDIReg;
- volatile S3C2410X_IOPORT_REG *vm_pIOPreg;
- volatile S3C2410X_CLKPWR_REG *vm_pCLKPWR;
- volatile S3C2410X_DMA_REG *vm_pDMAreg;
-
- DWORD m_dwSDIOIrq;
- DWORD m_dwSDIOSysIntr;
-
- PBYTE m_pDMABuffer;
- PHYSICAL_ADDRESS m_pDMABufferPhys;
- DWORD m_dwDMAChannel;
- DWORD m_dwDMAIrq;
- DWORD m_dwDMASysIntr;
-
- DWORD m_dwPollingTimeout;
-
- char m_chCardDetectGPIO;
- DWORD m_dwCardDetectMask;
- DWORD m_dwCardDetectFlag;
- DWORD m_dwCardDetectControlMask;
- DWORD m_dwCardDetectControlFlag;
- DWORD m_dwCardDetectPullupMask;
- DWORD m_dwCardDetectPullupFlag;
-
- char m_chCardReadWriteGPIO;
- DWORD m_dwCardReadWriteMask;
- DWORD m_dwCardReadWriteFlag;
- DWORD m_dwCardReadWriteControlMask;
- DWORD m_dwCardReadWriteControlFlag;
- DWORD m_dwCardReadWritePullupMask;
- DWORD m_dwCardReadWritePullupFlag;
-
- PSDCARD_HC_CONTEXT m_pHCContext;
- HANDLE m_hResponseReceivedEvent;
-
- int m_nCardDetectIstThreadPriority;
- HANDLE m_hCardInsertInterruptEvent;
- HANDLE m_hCardInsertInterruptThread;
-
- int m_nSDIOIstThreadPriority;
- HANDLE m_hSDIOInterruptEvent;
- HANDLE m_hSDIOInterruptThread;
-
- int m_nControllerIstThreadPriority;
- HANDLE m_hControllerInterruptEvent;
- HANDLE m_hControllerInterruptThread;
-
- int m_DMAIstThreadPriority;
- HANDLE m_hDMAInterruptEvent;
- HANDLE m_hDMAInterruptThread;
-
- BOOL m_bReinsertTheCard;
- BOOL m_bUseDMAForTransfer;
- BOOL m_bDriverShutdown;
- CRITICAL_SECTION m_ControllerCriticalSection;
- BOOL m_bDevicePresent;
- WCHAR m_rgchRegPath[256];
- SDHCDSTATE m_CurrentState;
- BOOL m_bSendInitClocks;
- DWORD m_dwLastTypeOfTransfer;
-
- DWORD m_dwNumBytesToTransfer;
- DWORD m_dwNumBytesUnaligned;
- DWORD m_dwNumBytesExtra;
-
- DWORD m_dwSDIBusWidth;
- DWORD m_dwClockRate;
-
- BOOL m_fCardInTheSlot;
- BOOL m_fHandleBusyCheckOnCommand38;
- DWORD m_dwDMATransferTimeoutFactor;
- DWORD m_dwDMATransferTimeoutConstant;
-
- SD_API_STATUS SendCommand(UINT16 Cmd, UINT32 Arg, UINT16 respType, BOOL bDataTransfer);
- SD_API_STATUS GetCommandResponse(PSD_BUS_REQUEST pRequest);
- DWORD SetClockRate(DWORD dwClockRate);
- BOOL IsCardBusy(UINT16 inData);
-
- BOOL SetupDmaXfer(PSD_BUS_REQUEST pRequest);
-
- BOOL SetupPollingXfer(PSD_BUS_REQUEST pRequest);
- BOOL PollingTransmit(PSD_BUS_REQUEST pRequest, DWORD dwLen);
- BOOL PollingReceive(PSD_BUS_REQUEST pRequest, DWORD dwLen);
-
- inline void MMC_Hardware_PowerUp();
- inline void MMC_Hardware_PowerDown();
- inline void Stop_SDI_Hardware();
- inline void Set_SDI_Bus_Width_1Bit();
- inline void Set_SDI_Bus_Width_4Bit();
- inline DWORD Get_SDI_Bus_Width();
- inline void Wait_80_SDI_Clock_Cycles();
- inline void Start_SDI_Clock();
- inline void Stop_SDI_Clock();
- inline BOOL Is_SDI_Clock_Running();
- inline void Enable_SDIO_Interrupts();
- inline void Disable_SDIO_Interrupts();
- inline BOOL Is_SDIO_Interrupt_Enabled();
- inline void Ack_SDIO_Interrupts();
- inline void Enable_SDIO_DMA_Channel();
- inline void Disable_SDIO_DMA_Channel();
- inline void Stop_SDIO_DMA_Channel();
-
-
- virtual DWORD CardDetectThread();
- virtual DWORD IOInterruptIstThread();
- virtual DWORD TransferIstThread();
-
-
- SD_API_STATUS Deinitialize();
- SD_API_STATUS Initialize();
- BOOLEAN CancelIoHandler(DWORD dwSlot, PSD_BUS_REQUEST pRequest);
- SD_API_STATUS BusRequestHandler(DWORD dwSlot, PSD_BUS_REQUEST pRequest);
- SD_API_STATUS SlotOptionHandler(DWORD dwSlot, SD_SLOT_OPTION_CODE Option, PVOID pData, ULONG OptionSize);
-
-
- static DWORD SD_CardDetectThread(CSDIOControllerBase *pController);
- static DWORD SD_IOInterruptIstThread(CSDIOControllerBase *pController);
- static DWORD SD_TransferIstThread(CSDIOControllerBase *pController);
-
-
- static SD_API_STATUS SDHCDDeinitialize(PSDCARD_HC_CONTEXT pHCContext);
- static SD_API_STATUS SDHCDInitialize(PSDCARD_HC_CONTEXT pHCContext);
- static BOOLEAN SDHCDCancelIoHandler(PSDCARD_HC_CONTEXT pHCContext, DWORD dwSlot, PSD_BUS_REQUEST pRequest);
- static SD_API_STATUS SDHCDBusRequestHandler(PSDCARD_HC_CONTEXT pHCContext, DWORD dwSlot, PSD_BUS_REQUEST pRequest);
- static SD_API_STATUS SDHCDSlotOptionHandler(PSDCARD_HC_CONTEXT pHCContext, DWORD dwSlot,
- SD_SLOT_OPTION_CODE Option, PVOID pData, ULONG OptionSize);
- };
其中有几个纯虚函数是由继承类实现的(CSDIOController类,sdiocontroller.cpp)
virtual BOOL InitializeHardware( BOOL bOnPowerUp = FALSE ) = 0;
virtual void DeinitializeHardware( BOOL bOnPowerDown = FALSE ) = 0;
virtual BOOL CustomSetup( LPCTSTR pszRegistryPath ) = 0;
virtual BOOL IsCardWriteProtected() = 0;
virtual BOOL IsCardPresent() = 0;
下面我们来一一看看每个成员函数:
1.构造函数CSDIOControllerBase
初始化成员变量,大部分初始化为0或NULL,当前状态m_CurrentState设为Idle
- CSDIOControllerBase::CSDIOControllerBase( PSDCARD_HC_CONTEXT pHCContext )
- {
- vm_pSDIReg = NULL;
- vm_pIOPreg = NULL;
- vm_pCLKPWR = NULL;
- vm_pDMAreg = NULL;
- m_pDMABuffer = NULL;
- m_dwDMAChannel = 0;
-
- m_pHCContext = pHCContext;
-
- m_hResponseReceivedEvent = NULL;
- m_nCardDetectIstThreadPriority = 0;
- m_hCardInsertInterruptEvent = NULL;
- m_hCardInsertInterruptThread = NULL;
-
- m_nSDIOIstThreadPriority = 0;
- m_hSDIOInterruptEvent = NULL;
- m_hSDIOInterruptThread = NULL;
-
- m_nControllerIstThreadPriority = 0;
- m_hControllerInterruptEvent = NULL;
- m_hControllerInterruptThread = NULL;
-
- m_DMAIstThreadPriority = 0;
- m_hDMAInterruptEvent = NULL;
- m_hDMAInterruptThread = NULL;
-
- m_bUseDMAForTransfer = FALSE;
- m_bDriverShutdown = FALSE;
-
- m_bDevicePresent = FALSE;
- m_CurrentState = Idle;
- m_bSendInitClocks = TRUE;
- m_dwLastTypeOfTransfer = SD_READ;
-
- m_dwNumBytesToTransfer = 0;
- m_dwNumBytesUnaligned = 0;
- m_dwNumBytesExtra = 0;
-
- m_rgchRegPath[0] = 0;
- m_dwSDIBusWidth = 0;
-
- m_bReinsertTheCard = FALSE;
-
- m_fHandleBusyCheckOnCommand38 = FALSE;
- m_dwDMATransferTimeoutFactor = 8;
- m_dwDMATransferTimeoutConstant = 3000;
-
- m_fCardInTheSlot = FALSE;
- }
2.~CSDIOControllerBase
未做任何工作.
3.PreDeinit
这个函数被SDH_PreDeinit调用,m_bDriverShutdown为FALSE时调用Deinitialize进行资源释放.
- void CSDIOControllerBase::PreDeinit()
- {
- if( !m_bDriverShutdown )
- {
- Deinitialize();
- }
- }
4.Initialize
该函数被SDHCDInitialize调用.
(1)设置crtical section临界访问,然后映射GPIO寄存器空SDI控制器,时钟能源管理寄存器,DMA控制器IO地址空间. 然后分配内存给DMA传输(64KB大小).
接着初始化寄存器
(2)MMC_Hardware_PowerUp设置CLKCON使能SDI PCLK.
(3)设置GPIO寄存器使能SDI功能
(4)SetClockRate设置SDI时钟(100HZ)
(5)设置SDI寄存器模式,little edian,512 bytes per block,设置timeout,reset fifo
(6)创建SD卡检测事件m_hCardInsertInterruptEvent及线程SD_CardDetectThread
(7)创建接收应答事件m_hResponseReceivedEvent
(8)创建IST线程m_hSDIOInterruptThread处理SDIO数据传输中断事件m_hSDIOInterruptEvent,并初始化中断
(9)设置DMA传输中断事件m_hDMAInterruptEvent和线程m_hDMAInterruptThread
(10)调用继承类InitializeHardware函数.
(11)出错处理,调用Deinitialize
- SD_API_STATUS CSDIOControllerBase::Initialize()
- {
- DEBUGMSG (SDCARD_ZONE_INIT,(TEXT("SDHCDInitialize starts")));
- SD_API_STATUS status = SD_API_STATUS_SUCCESS;
- DWORD threadID;
-
- InitializeCriticalSection(&m_ControllerCriticalSection);
-
-
- vm_pIOPreg = (S3C2410X_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2410X_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
- if (vm_pIOPreg == NULL)
- {
- DEBUGMSG (1,(TEXT("GPIO registers not allocated")));
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
- if (!VirtualCopy((PVOID)vm_pIOPreg, (PVOID)(S3C2410X_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2410X_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) {
- DEBUGMSG (1,(TEXT("GPIO registers not mapped")));
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
- DEBUGMSG (1,(TEXT("GPIO registers mapped to %x"), vm_pIOPreg));
-
-
- vm_pSDIReg = (S3C2410X_SDI_REG *)VirtualAlloc(0, sizeof(S3C2410X_SDI_REG), MEM_RESERVE, PAGE_NOACCESS);
- if (vm_pSDIReg == NULL)
- {
- DEBUGMSG (1,(TEXT("SDI control registers not allocated/n/r")));
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
- if (!VirtualCopy((PVOID)vm_pSDIReg, (PVOID)(S3C2410X_BASE_REG_PA_SDI >> 8), sizeof(S3C2410X_SDI_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) {
- DEBUGMSG (1,(TEXT("SDI control registers not mapped/n/r")));
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
- DEBUGMSG (1,(TEXT("SDI control registers mapped to %x/n/r"), vm_pSDIReg));
-
- vm_pCLKPWR = (S3C2410X_CLKPWR_REG *)VirtualAlloc(0, sizeof(S3C2410X_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS);
- if (vm_pCLKPWR == NULL)
- {
- DEBUGMSG (1,(TEXT("Clock & Power Management Special Register not allocated/n/r")));
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
- if (!VirtualCopy((PVOID)vm_pCLKPWR, (PVOID)(S3C2410X_BASE_REG_PA_CLOCK_POWER >> 8), sizeof(S3C2410X_CLKPWR_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) {
- DEBUGMSG (1,(TEXT("Clock & Power Management Special Register not mapped/n/r")));
- goto INIT_ERROR;
- }
- DEBUGMSG (1,(TEXT("Clock & Power Management Special Register mapped to %x/n/r"), vm_pCLKPWR));
-
- if( m_dwDMAChannel != 0xffffffff )
- {
-
- vm_pDMAreg = (S3C2410X_DMA_REG *)VirtualAlloc(0, sizeof(S3C2410X_DMA_REG), MEM_RESERVE, PAGE_NOACCESS);
- if (vm_pDMAreg == NULL)
- {
- DEBUGMSG (1,(TEXT("DMA Register not allocated/n/r")));
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
- if (!VirtualCopy((PVOID)vm_pDMAreg, (PVOID)(S3C2410X_BASE_REG_PA_DMA >> 8), sizeof(S3C2410X_DMA_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) {
- DEBUGMSG (1,(TEXT("DMA Register not mapped/n/r")));
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
- DEBUGMSG (1,(TEXT("DMA Register mapped to %x/n/r"), vm_pDMAreg));
-
-
- DMA_ADAPTER_OBJECT dmaAdapter;
- dmaAdapter.ObjectSize = sizeof(dmaAdapter);
- dmaAdapter.InterfaceType = Internal;
- dmaAdapter.BusNumber = 0;
- m_pDMABuffer = (PBYTE)HalAllocateCommonBuffer( &dmaAdapter, MAXIMUM_DMA_TRANSFER_SIZE, &m_pDMABufferPhys, FALSE );
- if( m_pDMABuffer == NULL )
- {
- RETAILMSG(1, (TEXT("SHCDriver: - Unable to allocate memory for DMA buffers!/r/n")));
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
- }
-
-
- MMC_Hardware_PowerUp();
-
-
- vm_pIOPreg->GPEUP &= 0xF83F;
- vm_pIOPreg->GPECON |= 0x2AA800;
-
-
- SetClockRate(SD_DEFAULT_CARD_ID_CLOCK_RATE);
-
- vm_pSDIReg->SDICON |= LITTLE_ENDIAN_BYTE_ORDER;
- vm_pSDIReg->SDICON |= RESET_FIFO;
- vm_pSDIReg->SDIBSIZE = BYTES_PER_SECTOR;
- vm_pSDIReg->SDIDTIMER = MAX_DATABUSY_TIMEOUT;
-
-
- m_hCardInsertInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
-
- if(NULL == m_hCardInsertInterruptEvent)
- {
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
-
- m_bDevicePresent = FALSE;
-
- m_hCardInsertInterruptThread = CreateThread(NULL, 0,
- (LPTHREAD_START_ROUTINE)SD_CardDetectThread,
- this, 0, &threadID);
-
- if(NULL == m_hCardInsertInterruptThread)
- {
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
-
-
-
- m_hResponseReceivedEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
-
- if(NULL == m_hResponseReceivedEvent)
- {
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
-
-
-
- m_hSDIOInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
-
- if(NULL == m_hSDIOInterruptEvent)
- {
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
-
-
- if(!InterruptInitialize (m_dwSDIOSysIntr, m_hSDIOInterruptEvent,
- NULL, 0))
- {
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
-
- m_hSDIOInterruptThread = CreateThread(NULL, 0,
- (LPTHREAD_START_ROUTINE)SD_IOInterruptIstThread,
- this, 0, &threadID);
-
- if(NULL == m_hSDIOInterruptThread)
- {
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
-
-
- m_hDMAInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
-
- if(NULL == m_hDMAInterruptEvent)
- {
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
-
-
- if(!InterruptInitialize (m_dwDMASysIntr, m_hDMAInterruptEvent,
- NULL, 0))
- {
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
-
- m_hDMAInterruptThread = CreateThread(NULL, 0,
- (LPTHREAD_START_ROUTINE)SD_TransferIstThread,
- this, 0, &threadID);
-
- if(NULL == m_hDMAInterruptThread)
- {
- status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
- goto INIT_ERROR;
- }
-
- m_dwLastTypeOfTransfer = SD_READ;
- m_bUseDMAForTransfer = FALSE;
-
- if( !InitializeHardware() )
- {
- DEBUGMSG (1,(TEXT("InitializeHardware failed!/n/r")));
- status = SD_API_STATUS_UNSUCCESSFUL;
- goto INIT_ERROR;
- }
-
- INIT_ERROR:
-
- if(!SD_API_SUCCESS(status))
- {
- Deinitialize();
- }
-
- DEBUGMSG (SDCARD_ZONE_INIT,(TEXT("SDHCDInitialize ends")));
- return status;
- }
5.Deinitialize
Deinitialize用来关闭Initialize创建的事件IST线程,释放DMA buffer,关闭SDI power等
- SD_API_STATUS CSDIOControllerBase::Deinitialize()
- {
- DEBUGMSG (SDCARD_ZONE_INIT,(TEXT("SDHCDDeinitialize starts")));
-
- m_bDriverShutdown = TRUE;
-
-
- InterruptDisable (m_dwSDIOSysIntr);
- SetEvent(m_hResponseReceivedEvent);
- InterruptDisable (m_dwDMASysIntr);
-
- if(NULL != m_hResponseReceivedEvent)
- {
- CloseHandle(m_hResponseReceivedEvent);
- m_hResponseReceivedEvent = NULL;
- }
-
- if(NULL != m_hSDIOInterruptThread)
- {
- WaitForSingleObject(m_hSDIOInterruptThread, INFINITE);
- CloseHandle(m_hSDIOInterruptThread);
- m_hSDIOInterruptThread = NULL;
- }
-
- if(NULL != m_hSDIOInterruptEvent)
- {
- CloseHandle(m_hSDIOInterruptEvent);
- m_hSDIOInterruptEvent = NULL;
- }
-
- if(NULL != m_hDMAInterruptThread)
- {
- WaitForSingleObject(m_hDMAInterruptThread, INFINITE);
- CloseHandle(m_hDMAInterruptThread);
- m_hDMAInterruptThread = NULL;
- }
-
- if(NULL != m_hDMAInterruptEvent)
- {
- CloseHandle(m_hDMAInterruptEvent);
- m_hDMAInterruptEvent = NULL;
- }
-
- if(NULL != m_hCardInsertInterruptThread)
- {
- WaitForSingleObject(m_hCardInsertInterruptThread, INFINITE);
- CloseHandle(m_hCardInsertInterruptThread);
- m_hCardInsertInterruptThread = NULL;
- }
-
- if(NULL != m_hCardInsertInterruptEvent)
- {
- CloseHandle(m_hCardInsertInterruptEvent);
- m_hCardInsertInterruptEvent = NULL;
- }
-
- if( m_dwDMAChannel != 0xffffffff )
- {
-
- HalFreeCommonBuffer( NULL, 0, m_pDMABufferPhys, m_pDMABuffer, FALSE );
- }
-
-
- MMC_Hardware_PowerDown();
-
- DeleteCriticalSection(&m_ControllerCriticalSection);
-
- DEBUGMSG (SDCARD_ZONE_INIT,(TEXT("SDHCDDeinitialize ends")));
- return SD_API_STATUS_SUCCESS;
- }
6.CancelIoHandler
CancelIoHandler被SDHCDCancelIoHandler调用.首先调用Stop_SDI_Hardware设置SDIDCON强制停止数据传输.调用SDHCDReleaseHCLock释放lock,最后调用SDHCDIndicateBusRequestComplete使用Cancel状态(SD_API_STATUS_CANCELED)来完成Bus请求.
- BOOLEAN CSDIOControllerBase::CancelIoHandler(DWORD dwSlot, PSD_BUS_REQUEST pRequest)
- {
- DEBUGMSG (SDCARD_ZONE_FUNC,(TEXT("SDHCDCancelIoHandler starts")));
-
-
- Stop_SDI_Hardware();
-
-
- SDHCDReleaseHCLock(m_pHCContext);
-
-
- SDHCDIndicateBusRequestComplete(m_pHCContext, pRequest,SD_API_STATUS_CANCELED);
-
- DEBUGMSG (SDCARD_ZONE_FUNC,(TEXT("SDHCDCancelIoHandler ends")));
- return TRUE;
- }
7.SlotOptionHandler
CancelIoHandler被SDHCDSlotOptionHandler调用.Slot选项变化时该函数被调用.
(1)SDHCDSetSlotPower:设置slot power,因为系统一直工作在3.3V,不会变化,这里不做任何处理.
(2)SDHCDSetSlotInterface:设置slot接口模式,根据输入数据(pData)设置4bit还是1bit bus模式,调用SetClockRate设置SDI时钟频率.
(3)SDHCDEnableSDIOInterrupts:调用Enable_SDIO_Interrupts使能SDIO中断.
(4)SDHCDDisableSDIOInterrupts:调用Disable_SDIO_Interrupts禁止SDIO中断.
(5)SDHCDAckSDIOInterrupt:调用Ack_SDIO_Interrupts和InterruptDone(m_dwSDIOSysIntr)确认SDIO中断完成.
(6)SDHCDGetWriteProtectStatus:调用IsCardWriteProtected获得写保护状态.
(7)SDHCDQueryBlockCapability:查询Block性能参数.通过输入参数pData来获得ReadBlockSize,WriteBlockSize并根据设定的最大最小值进行修正.
(8)SDHCDGetSlotInfo:获得特定slot的信息.调用SDHCDSetSlotCapabilities等函数设置slot参数,如电压,时钟频率,上电延时等.
- SD_API_STATUS CSDIOControllerBase::SlotOptionHandler(DWORD dwSlot, SD_SLOT_OPTION_CODE Option,
- PVOID pData, ULONG OptionSize)
- {
- DEBUGMSG (SDCARD_ZONE_FUNC,(TEXT("SDHCDSlotOptionHandler starts")));
-
- SD_API_STATUS status = SD_API_STATUS_SUCCESS;
- PSD_HOST_BLOCK_CAPABILITY pBlockCaps;
-
- switch(Option)
- {
- case SDHCDSetSlotPower:
- DEBUGMSG (SDCARD_ZONE_INFO,(TEXT("SDHCDSlotOptionHandler option=SDHCDSetSlotPower")));
-
- break;
-
- case SDHCDSetSlotInterface:
- DEBUGMSG (SDCARD_ZONE_INFO,(TEXT("SDHCDSlotOptionHandler option=SDHCDSetSlotInterface")));
-
- if(((PSD_CARD_INTERFACE)pData)->InterfaceMode == SD_INTERFACE_SD_4BIT)
- {
- Set_SDI_Bus_Width_4Bit();
- }else
- {
-
- Set_SDI_Bus_Width_1Bit();
- }
-
-
- ((PSD_CARD_INTERFACE)pData)->ClockRate = SetClockRate(((PSD_CARD_INTERFACE)pData)->ClockRate);
- break;
-
- case SDHCDEnableSDIOInterrupts:
- DEBUGMSG (SDCARD_ZONE_INFO,(TEXT("SDHCDSlotOptionHandler option=SDHCDEnableSDIOInterrupts")));
- Enable_SDIO_Interrupts();
- break;
-
- case SDHCDDisableSDIOInterrupts:
- DEBUGMSG (SDCARD_ZONE_INFO,(TEXT("SDHCDSlotOptionHandler option=SDHCDDisableSDIOInterrupts")));
- Disable_SDIO_Interrupts();
- break;
-
- case SDHCDAckSDIOInterrupt:
-
- DEBUGMSG (SDCARD_ZONE_INFO,(TEXT("SDHCDSlotOptionHandler option=SDHCDAckSDIOInterrupt")));
-
- Ack_SDIO_Interrupts();
- InterruptDone(m_dwSDIOSysIntr);
- break;
-
- case SDHCDGetWriteProtectStatus:
- DEBUGMSG (SDCARD_ZONE_INFO,(TEXT("SDHCDSlotOptionHandler option=SDHCDGetWriteProtectStatus")));
- ((PSD_CARD_INTERFACE)pData)->WriteProtected = IsCardWriteProtected();
- break;
-
- case SDHCDQueryBlockCapability:
-
- DEBUGMSG (SDCARD_ZONE_INFO,(TEXT("SDHCDSlotOptionHandler option=SDHCDQueryBlockCapability")));
- pBlockCaps = (PSD_HOST_BLOCK_CAPABILITY)pData;
-
- DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("SDHCD:SDHCDSlotOptionHandler() - Read Block Length: %d , Read Blocks: %d/n"),
- pBlockCaps->ReadBlockSize, pBlockCaps->ReadBlocks));
-
- DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("SDHCD:SDHCDSlotOptionHandler() - Write Block Length: %d , Write Blocks: %d/n"),
- pBlockCaps->WriteBlockSize, pBlockCaps->WriteBlocks));
-
- pBlockCaps = (PSD_HOST_BLOCK_CAPABILITY)pData;
-
-
- if (pBlockCaps->ReadBlockSize < MINIMUM_BLOCK_TRANSFER_SIZE )
- {
- pBlockCaps->ReadBlockSize = MINIMUM_BLOCK_TRANSFER_SIZE;
- }
-
- if (pBlockCaps->WriteBlockSize < MINIMUM_BLOCK_TRANSFER_SIZE )
- {
- pBlockCaps->WriteBlockSize = MINIMUM_BLOCK_TRANSFER_SIZE;
- }
-
- if (pBlockCaps->ReadBlockSize > MAXIMUM_BLOCK_TRANSFER_SIZE )
- {
- pBlockCaps->ReadBlockSize = MAXIMUM_BLOCK_TRANSFER_SIZE;
- }
-
- if (pBlockCaps->WriteBlockSize > MAXIMUM_BLOCK_TRANSFER_SIZE )
- {
- pBlockCaps->WriteBlockSize = MAXIMUM_BLOCK_TRANSFER_SIZE;
- }
- break;
-
- case SDHCDGetSlotInfo:
- DEBUGMSG (SDCARD_ZONE_INFO,(TEXT("SDHCDSlotOptionHandler option=SDHCDGetSlotInfo")));
- if( OptionSize != sizeof(SDCARD_HC_SLOT_INFO) || pData == NULL )
- {
- status = SD_API_STATUS_INVALID_PARAMETER;
- }
- else
- {
- PSDCARD_HC_SLOT_INFO pSlotInfo = (PSDCARD_HC_SLOT_INFO)pData;
-
-
- SDHCDSetSlotCapabilities(pSlotInfo, SD_SLOT_SD_4BIT_CAPABLE |
- SD_SLOT_SD_1BIT_CAPABLE |
- SD_SLOT_SDIO_CAPABLE |
- SD_SLOT_SDIO_INT_DETECT_4BIT_MULTI_BLOCK);
-
- SDHCDSetVoltageWindowMask(pSlotInfo, (SD_VDD_WINDOW_3_2_TO_3_3 | SD_VDD_WINDOW_3_3_TO_3_4));
-
-
- SDHCDSetDesiredSlotVoltage(pSlotInfo, SD_VDD_WINDOW_3_2_TO_3_3);
-
- SDHCDSetMaxClockRate(pSlotInfo, MAX_SDI_BUS_TRANSFER_SPEED);
-
-
- SDHCDSetPowerUpDelay(pSlotInfo, 300);
- }
- break;
-
- default:
- DEBUGMSG (SDCARD_ZONE_WARN,(TEXT("SDHCDSlotOptionHandler option=SD_API_STATUS_INVALID_PARAMETER")));
- status = SD_API_STATUS_INVALID_PARAMETER;
-
- }
- DEBUGMSG (SDCARD_ZONE_FUNC,(TEXT("SDHCDSlotOptionHandler ends")));
- return status;
- }
8.BusRequestHandler
BusRequestHandler被SDHCDBusRequestHandler调用,用来处理总线请求.
首先复位FIFO和状态寄存器,然后使能SDI CLOCK,计算要传输数据大小,判断是否DMA传输以及是否4字节对齐,4字节整数倍来进行DMA传输(SetupDmaXfer)或者轮询IO传输(SetupPollingXfer).
接着判断传输的是单独命令还是命令和数据,第一次传输命令时需延时80个clock周期.SendCommand最后一个参数表示是传输命令(FALSE)还是命令和数据(TRUE).
最后设置设置事件m_hResponseReceivedEvent来通知传输IST命令应答发生.
- SD_API_STATUS CSDIOControllerBase::BusRequestHandler(DWORD dwSlot, PSD_BUS_REQUEST pRequest)
- {
- DEBUGMSG (SDCARD_ZONE_FUNC,(TEXT("BusRequestHandler starts (CMD:%d)"), pRequest->CommandCode));
- SD_API_STATUS status;
-
-
- vm_pSDIReg->SDICON |= RESET_FIFO;
- vm_pSDIReg->SDIDSTA = 0xffff;
- vm_pSDIReg->SDIDCON = 0;
- vm_pSDIReg->SDICSTA = 0xffff;
- vm_pSDIReg->SDICCON = 0;
-
- Start_SDI_Clock();
-
-
- m_dwNumBytesToTransfer = pRequest->BlockSize * pRequest->NumBlocks;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if( ( m_dwDMAChannel == 0xffffffff ) || (!IS_BUFFER_DWORD_ALIGNED(pRequest->pBlockBuffer)) || (!IS_BUFFER_SIZE_A_DWORD_MULTPLE(pRequest->BlockSize)) || m_dwNumBytesToTransfer > MAXIMUM_DMA_TRANSFER_SIZE )
- {
- m_bUseDMAForTransfer = FALSE;
- SetupPollingXfer(pRequest);
- }else{
- m_bUseDMAForTransfer = TRUE;
- SetupDmaXfer(pRequest);
- }
-
- if(pRequest->TransferClass == SD_COMMAND)
- {
-
- status = SendCommand(pRequest->CommandCode, pRequest->CommandArgument, pRequest->CommandResponse.ResponseType, FALSE);
-
- if(!SD_API_SUCCESS(status))
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHCDBusRequestHandler() - Error sending command:0x%02x/r/n"), pRequest->CommandCode));
- goto BUS_REQUEST_COMPLETE;
- }
-
-
- if(m_bSendInitClocks)
- {
- m_bSendInitClocks = FALSE;
- Wait_80_SDI_Clock_Cycles();
- }
- }
- else
- {
-
- status = SendCommand(pRequest->CommandCode, pRequest->CommandArgument, pRequest->CommandResponse.ResponseType, TRUE);
-
- if(!SD_API_SUCCESS(status))
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHCDBusRequestHandler() - Error sending command:0x%02x/r/n"), pRequest->CommandCode));
- goto BUS_REQUEST_COMPLETE;
- }
- }
-
-
-
-
-
- SetEvent(m_hResponseReceivedEvent);
- m_CurrentState = CommandSent;
- status = SD_API_STATUS_PENDING;
-
- BUS_REQUEST_COMPLETE:
- DEBUGMSG (SDCARD_ZONE_FUNC,(TEXT("SDHCD:BusRequestHandler ends")));
- return status;
- }
9.TransferIstThread
TransferIstThread被SD_TransferIstThread调用,而SD_TransferIstThread在Initialize中被创建,对应于m_hDMAInterruptThread句柄.这个IST线程用来处理SDIO的DMA通道通信.
首先设置该线程的优先级(从注册表中获得,"DMA_IST_Priority"=dword:96),然后等待m_hResponseReceivedEvent事件的发生,该事件发生后继续运行,否则挂起.
m_hResponseReceivedEvent触发后,如果controller down则线程退出.调用SDHCDGetAndLockCurrentRequest(实现在sdhclib)来获取当前slot的请求,并锁住禁止取消.
然后处理一个特殊情况,SD_CMD_STOP_TRANSMISSION命令在SD_CMD_WRITE_MULTIPLE_BLOCK后发送,需要进行BUSY_CHECK.
如果BusyCheck为true,CommandCode为SD_CMD_ERASE或者CommandCode为SD_CMD_STOP_TRANSMISSION,m_dwLastTypeOfTransfer为SD_WRITE时,需要等待IO传输结束.检查SDIDSTA寄存器BusyFin位,如果为0(busy not finish),则进行等待,并判断超时,IsCardPresent,以及一些错误状态,如果任何一种情况发生,就设置BUSY_CHECKS_FINISH,跳转到TRANSFER_DONE通知BusRequest完成.
如果BUSY_CHECKS_FINISH成立,则准备DMA传输.如果ResponseType为NoResponse,跳转到TRANSFER_DONE.否则调用GetCommandResponse获取CommandResponse状态.如果是命令,直接TRANSFER_DONE.数据传输分两种情况是否使用DMA,m_bUseDMAForTransfer为false,启动IO传输,为true,并判断是SD_WRITE写操作时,复制数据到DMA memory,调用Enable_SDIO_DMA_Channel,启动DMA通道,然后等待DMA完成中断事件m_hDMAInterruptEvent,完成后调用InterruptDone和Stop_SDIO_DMA_Channel通知中断完成并停止DMA通道.然后等待读取SDIDSTA等待data transfer结束.如果是SD_READ,读取从DMA memory放到调用缓存区pBlockBuffer中.
最后停止SDI clock,通知总线请求结束(SDHCDIndicateBusRequestComplete).
- DWORD CSDIOControllerBase::TransferIstThread()
- {
- PSD_BUS_REQUEST pRequest = NULL;
- SD_API_STATUS status;
-
- if( m_DMAIstThreadPriority != 0xffffffff && !CeSetThreadPriority( GetCurrentThread(), m_DMAIstThreadPriority ) )
- {
- DEBUGMSG(SDCARD_ZONE_WARN,(TEXT("SDHCDriver:TransferIstThread(): warning, failed to set CEThreadPriority /n")));
- }
-
- for(;;)
- {
-
- status = SD_API_STATUS_PENDING;
- if(WaitForSingleObject(m_hResponseReceivedEvent, INFINITE) == WAIT_FAILED)
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCDriver:TransferIstThread(): Wait Failed!/n")));
- return FALSE;
- }
-
- if(m_bDriverShutdown)
- {
- DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCD:TransferIstThread(): Thread Exiting/n")));
- return FALSE;
- }
-
-
- if(pRequest == NULL)
- {
- if((pRequest = SDHCDGetAndLockCurrentRequest(m_pHCContext, 0)) == NULL)
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Unable to get/lock current request!/r/n")));
- status = SD_API_STATUS_INVALID_DEVICE_REQUEST;
- goto TRANSFER_DONE;
- }
- }
-
-
-
- if( ( m_fHandleBusyCheckOnCommand38 && pRequest->CommandCode == SD_CMD_ERASE ) ||
- ( ( pRequest->CommandCode == SD_CMD_STOP_TRANSMISSION ) && ( m_dwLastTypeOfTransfer == SD_WRITE ) ) )
- {
- DWORD dwWaitCount = 0;
-
- while(!(vm_pSDIReg->SDIDSTA & BUSY_CHECKS_FINISH))
- {
- dwWaitCount++;
- if( dwWaitCount > WAIT_TIME )
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - timeout waiting for BUSY_CHECKS to finish!/r/n")));
- status = SD_API_STATUS_DATA_TIMEOUT;
- goto TRANSFER_DONE;
- }
-
- if( !IsCardPresent() )
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Card ejected!/r/n")));
- status = SD_API_STATUS_DEVICE_REMOVED;
- goto TRANSFER_DONE;
- }
- if((vm_pSDIReg->SDIDSTA & FIFO_FAIL_ERROR))
- {
- vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | FIFO_FAIL_ERROR;
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - FIFO Error waiting for BUSY_CHECKS to finish!/r/n")));
- status = SD_API_STATUS_DATA_ERROR;
- goto TRANSFER_DONE;
- }
- if((vm_pSDIReg->SDIDSTA & DATA_TRANSMIT_CRC_ERROR))
- {
- vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_TRANSMIT_CRC_ERROR;
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Transmit CRC Error waiting for BUSY_CHECKS to finish!/r/n")));
- status = SD_API_STATUS_DATA_ERROR;
- goto TRANSFER_DONE;
- }
- if((vm_pSDIReg->SDIDSTA & DATA_RECEIVE_CRC_ERROR))
- {
- vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_RECEIVE_CRC_ERROR;
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Receive CRC Error waiting for BUSY_CHECKS to finish!/r/n")));
- status = SD_API_STATUS_DATA_ERROR;
- goto TRANSFER_DONE;
- }
- if((vm_pSDIReg->SDIDSTA & DATA_TIME_OUT))
- {
- vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_TIME_OUT;
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Data timeout waiting for BUSY_CHECKS to finish!/r/n")));
- status = SD_API_STATUS_DATA_TIMEOUT;
- goto TRANSFER_DONE;
- }
- }
- vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH;
- }
-
-
- if(pRequest->CommandResponse.ResponseType == NoResponse)
- {
- goto TRANSFER_DONE;
- }else{
- status = GetCommandResponse(pRequest);
-
- if(!SD_API_SUCCESS(status))
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHCDBusRequestHandler() - Error getting response for command:0x%02x/r/n"), pRequest->CommandCode));
- goto TRANSFER_DONE;
- }
- }
-
-
- if(pRequest->TransferClass == SD_COMMAND)
- {
- goto TRANSFER_DONE;
- }
-
-
-
-
- if(m_bUseDMAForTransfer == FALSE)
- {
-
-
- switch(pRequest->TransferClass)
- {
- case SD_READ:
- if(!PollingReceive(pRequest, m_dwNumBytesToTransfer))
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:BusRequestHandler() - PollingReceive() failed/r/n")));
- goto TRANSFER_DONE;
- }
- break;
-
- case SD_WRITE:
- if(!PollingTransmit(pRequest, m_dwNumBytesToTransfer))
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:BusRequestHandler() - PollingReceive() failed/r/n")));
- goto TRANSFER_DONE;
- }
- break;
- }
-
- status = SD_API_STATUS_SUCCESS;
- }else
- {
-
-
-
- if(pRequest->TransferClass == SD_WRITE)
- {
- BOOL fNoException;
- DEBUGCHK(m_dwNumBytesToTransfer <= MAXIMUM_DMA_TRANSFER_SIZE);
-
- SD_SET_PROC_PERMISSIONS_FROM_REQUEST( pRequest ) {
- fNoException = SDPerformSafeCopy( m_pDMABuffer, pRequest->pBlockBuffer, m_dwNumBytesToTransfer );
- } SD_RESTORE_PROC_PERMISSIONS();
-
- if (fNoException == FALSE) {
- status = SD_API_STATUS_ACCESS_VIOLATION;
- goto TRANSFER_DONE;
- }
- }
-
-
- Enable_SDIO_DMA_Channel();
-
-
-
- DWORD dwDelay = m_dwNumBytesToTransfer * m_dwDMATransferTimeoutFactor / ( m_dwClockRate / 2000 );
- if( Get_SDI_Bus_Width() != WIDE_BUS_ENABLE )
- {
- dwDelay *= 4;
- }
- dwDelay += m_dwDMATransferTimeoutConstant;
-
-
- if(WaitForSingleObject(m_hDMAInterruptEvent, dwDelay) != WAIT_OBJECT_0)
- {
- DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("TransferIstThread(): Wait Failed!/n")));
- Stop_SDIO_DMA_Channel();
- status = SD_API_STATUS_DATA_TIMEOUT;
- goto TRANSFER_DONE;
- }
-
- if(m_bDriverShutdown)
- {
- DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCD:TransferIstThread(): Thread Exiting/n")));
- return FALSE;
- }
-
-
- InterruptDone(m_dwDMASysIntr);
- Stop_SDIO_DMA_Channel();
-
- DWORD dwWaitCount = 0;
-
- while(!(vm_pSDIReg->SDIDSTA & DATA_TRANSMIT_FINISHED))
- {
- dwWaitCount++;
- if( dwWaitCount > WAIT_TIME )
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - timeout waiting for DMA transfer completion!/r/n")));
- status = SD_API_STATUS_DATA_TIMEOUT;
- goto TRANSFER_DONE;
- }
-
- if( !IsCardPresent() )
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Card ejected!/r/n")));
- status = SD_API_STATUS_DEVICE_REMOVED;
- goto TRANSFER_DONE;
- }
- if((vm_pSDIReg->SDIDSTA & FIFO_FAIL_ERROR))
- {
- vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | FIFO_FAIL_ERROR;
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - FIFO Error waiting for DMA transfer completion!/r/n")));
- status = SD_API_STATUS_DATA_ERROR;
- goto TRANSFER_DONE;
- }
- if((vm_pSDIReg->SDIDSTA & DATA_TRANSMIT_CRC_ERROR))
- {
- vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_TRANSMIT_CRC_ERROR;
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Transmit CRC Error waiting for DMA transfer completion!/r/n")));
- status = SD_API_STATUS_DATA_ERROR;
- goto TRANSFER_DONE;
- }
- if((vm_pSDIReg->SDIDSTA & DATA_RECEIVE_CRC_ERROR))
- {
- vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_RECEIVE_CRC_ERROR;
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Receive CRC Error waiting for DMA transfer completion!/r/n")));
- status = SD_API_STATUS_DATA_ERROR;
- goto TRANSFER_DONE;
- }
- if((vm_pSDIReg->SDIDSTA & DATA_TIME_OUT))
- {
- vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_TIME_OUT;
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Data timeout waiting for DMA transfer completion!/r/n")));
- status = SD_API_STATUS_DATA_TIMEOUT;
- goto TRANSFER_DONE;
- }
- }
-
- vm_pSDIReg->SDIDSTA = DATA_TRANSMIT_FINISHED;
-
-
- if(pRequest->TransferClass == SD_READ)
- {
- BOOL fNoException;
- DEBUGCHK(m_dwNumBytesToTransfer <= MAXIMUM_DMA_TRANSFER_SIZE);
-
- SD_SET_PROC_PERMISSIONS_FROM_REQUEST( pRequest ) {
- fNoException = SDPerformSafeCopy( pRequest->pBlockBuffer, m_pDMABuffer, m_dwNumBytesToTransfer );
- } SD_RESTORE_PROC_PERMISSIONS();
-
- if (fNoException == FALSE) {
- status = SD_API_STATUS_ACCESS_VIOLATION;
- goto TRANSFER_DONE;
- }
- }
-
-
- status = SD_API_STATUS_SUCCESS;
- }
-
- TRANSFER_DONE:
- if( !( Is_SDIO_Interrupt_Enabled() && ( Get_SDI_Bus_Width() == WIDE_BUS_ENABLE ) ) )
- {
- Stop_SDI_Clock();
- }
- m_CurrentState = CommandComplete;
- SDHCDIndicateBusRequestComplete(m_pHCContext, pRequest, status);
- pRequest = NULL;
- }
-
- return TRUE;
- }
10.IOInterruptIstThread
被SD_IOInterruptIstThread调用,对应于句柄m_hSDIOInterruptThread.同样首先设置线程优先级(从注册表中获取"SDIO_IST_Priority"=dword:97),然后等待m_hSDIOInterruptEvent事件发生,如果事件发生同时卡存在的话,调用SDHCDIndicateSlotStateChange通知总线驱动SD卡中断发生.
- DWORD CSDIOControllerBase::IOInterruptIstThread()
- {
-
- if( m_nSDIOIstThreadPriority != 0xffffffff && !CeSetThreadPriority( GetCurrentThread(), m_nSDIOIstThreadPriority ) )
- {
- DEBUGMSG(SDCARD_ZONE_WARN,(TEXT("SDHCDriver:SDIOInterruptIstThread(): warning, failed to set CEThreadPriority /n")));
- }
-
- for(;;)
- {
-
- if(WaitForSingleObject(m_hSDIOInterruptEvent, INFINITE) != WAIT_OBJECT_0)
- {
- DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCD:SDIOInterruptIstThread(): Wait Failed!/n")));
- return FALSE;
- }
-
- if(m_bDriverShutdown)
- {
- DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCD:SDIOInterruptIstThread(): Thread Exiting/n")));
- return FALSE;
- }
-
- if(m_bDevicePresent && IsCardPresent())
- {
-
- SDHCDIndicateSlotStateChange(m_pHCContext, 0, DeviceInterrupting);
- }
-
-
-
-
-
-
-
- }
- }
11.CardDetectThread
被SD_CardDetectThread调用.首先设置线程优先级(从注册表中获取"CardDetect_Thread_Priority"=dword:98"),然后等待m_hCardInsertInterruptEvent事件,调用IsCardPresent监测卡是否插入.如果卡拔出,调用SDHCDIndicateSlotStateChange通知DeviceEjected,否则卡插入,进行SDI寄存器初始化,设置clock rate(100KHz),启动SDI clock,调用SDHCDIndicateSlotStateChange通知DeviceInserted.
- DWORD CSDIOControllerBase::CardDetectThread()
- {
- BOOL bSlotStateChanged = FALSE;
- DWORD dwWaitResult = WAIT_TIMEOUT;
-
- if( m_nCardDetectIstThreadPriority != 0xffffffff && !CeSetThreadPriority( GetCurrentThread(), m_nCardDetectIstThreadPriority ) )
- {
- DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCDriver:CardDetectThread(): warning, failed to set CEThreadPriority /n")));
- }
-
- for(;;)
- {
-
- dwWaitResult = WaitForSingleObject(m_hCardInsertInterruptEvent, m_dwPollingTimeout);
-
- if(m_bDriverShutdown)
- {
- DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCardDetectIstThread: Thread Exiting/n")));
- return FALSE;
- }
-
-
- if( IsCardPresent() == m_bDevicePresent )
- {
- bSlotStateChanged = FALSE;
- }
- else
- {
- bSlotStateChanged = TRUE;
- }
-
- if( bSlotStateChanged || m_bReinsertTheCard )
- {
- m_bReinsertTheCard = FALSE;
-
-
- if(m_bDevicePresent == TRUE)
- {
- m_fCardInTheSlot = FALSE;
-
- SDHCDIndicateSlotStateChange(m_pHCContext, 0, DeviceEjected);
- m_bDevicePresent = FALSE;
-
- Stop_SDI_Clock();
- }
-
- if(IsCardPresent())
- {
- m_fCardInTheSlot = TRUE;
- m_bDevicePresent = TRUE;
-
-
- vm_pSDIReg->SDICON |= LITTLE_ENDIAN_BYTE_ORDER;
- vm_pSDIReg->SDICON |= RESET_FIFO;
- vm_pSDIReg->SDIBSIZE = BYTES_PER_SECTOR;
- vm_pSDIReg->SDIDTIMER = MAX_DATABUSY_TIMEOUT;
- SetClockRate(SD_DEFAULT_CARD_ID_CLOCK_RATE);
-
-
- Start_SDI_Clock();
- Wait_80_SDI_Clock_Cycles();
-
-
- m_bSendInitClocks = TRUE;
-
-
- SDHCDIndicateSlotStateChange(m_pHCContext, 0, DeviceInserted);
- }
- }
- }
-
- return TRUE;
- }
12.SendCommand
在BusRequestHandler中被调用,首先清除SDICSTA状态标志位,设置SDICARG命令参数寄存器.判断命令是否带数据设置SDICCON.根据不同的Response类型SDICCON进行不同设置.NoResponse时,写命令到SDICCON并发送命令,并确定发送完成.Short response时,SDICCON设置WAIT_FOR_RESPONSE.ResponseR2时,SDICCON设置LONG_RESPONSE | WAIT_FOR_RESPONSE.
- SD_API_STATUS CSDIOControllerBase::SendCommand(UINT16 Cmd, UINT32 Arg, UINT16 respType, BOOL bDataTransfer)
- {
- unsigned int uiNewCmdRegVal = 0;
- DWORD dwWaitCount = 0;
-
- DEBUGMSG (SDHC_SEND_ZONE,(TEXT("SendCommand (0x%08x, 0x%04x, 0x%08x, 0x%04x, 0x%x) starts"),
- this, Cmd, Arg, respType, bDataTransfer));
-
- vm_pSDIReg->SDICSTA = (CRC_CHECK_FAILED | COMMAND_SENT | COMMAND_TIMED_OUT | RESPONSE_RECEIVED);
-
-
- vm_pSDIReg->SDICARG = Arg;
-
-
- if(bDataTransfer == TRUE)
- {
- vm_pSDIReg->SDICCON |= SDIO_COMMAND_WITH_DATA;
- }else
- {
- vm_pSDIReg->SDICCON &= ~SDIO_COMMAND_WITH_DATA;
- }
-
-
- switch(respType)
- {
- case NoResponse:
- DEBUGMSG (SDHC_RESPONSE_ZONE,(TEXT("SendCommand no response required")));
- vm_pSDIReg->SDICCON = START_COMMAND | COMMAND_START_BIT | (Cmd & MAX_CMD_VALUE);
-
- while(!(vm_pSDIReg->SDICSTA & COMMAND_SENT))
- {
- dwWaitCount++;
- if( dwWaitCount > WAIT_TIME )
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SendCommand() - timeout waiting for command completion!/r/n")));
- return SD_API_STATUS_RESPONSE_TIMEOUT;
- }
-
- if( !IsCardPresent() )
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SendCommand() - Card ejected!/r/n")));
- return SD_API_STATUS_DEVICE_REMOVED;
- }
- if(vm_pSDIReg->SDICSTA & COMMAND_TIMED_OUT)
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SendCommand() - Command 0x%04x timed out!/r/n"), Cmd));
- vm_pSDIReg->SDICSTA = COMMAND_TIMED_OUT;
- return SD_API_STATUS_RESPONSE_TIMEOUT;
- }
- }
- vm_pSDIReg->SDICSTA = COMMAND_SENT;
- break;
-
- case ResponseR1:
- case ResponseR1b:
- case ResponseR3:
- case ResponseR4:
- case ResponseR5:
- case ResponseR6:
- DEBUGMSG (SDHC_RESPONSE_ZONE,(TEXT("sendSDICommand short response required")));
-
- vm_pSDIReg->SDICCON = WAIT_FOR_RESPONSE | START_COMMAND | COMMAND_START_BIT | (Cmd & MAX_CMD_VALUE);
- break;
-
- case ResponseR2:
- DEBUGMSG (SDHC_RESPONSE_ZONE,(TEXT("sendSDICommand long response required")));
-
- vm_pSDIReg->SDICCON = LONG_RESPONSE | WAIT_FOR_RESPONSE | START_COMMAND | COMMAND_START_BIT | (Cmd & MAX_CMD_VALUE);
- break;
-
- default:
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:sendSDICommand() - Invalid response type. Command not sent!/r/n")));
- return SD_API_STATUS_NOT_IMPLEMENTED;
- break;
- }
-
- return SD_API_STATUS_SUCCESS;
- }
13.GetCommandResponse
该函数用来获取命令应答,在TransferIstThread被调用.读取SDICSTA直到命令应答接收,如果有错误状态就返回错误.然后根据不同的应答类型分别读取SDIRSP0,SDIRSP1,SDIRSP2,SDIRSP3,具体格式参加代码注释.
- SD_API_STATUS CSDIOControllerBase::GetCommandResponse(PSD_BUS_REQUEST pRequest)
- {
- DEBUGMSG (SDHC_RESPONSE_ZONE,(TEXT("GetCommandResponse started")));
- PUCHAR respBuff;
- DWORD dwWaitCount = 0;
-
-
- while(!(vm_pSDIReg->SDICSTA & RESPONSE_RECEIVED))
- {
- dwWaitCount++;
- if( dwWaitCount > WAIT_TIME )
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:GetCommandResponse() - timeout waiting for command response!/r/n")));
- return SD_API_STATUS_RESPONSE_TIMEOUT;
- }
-
- if( !IsCardPresent() )
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:GetCommandResponse() - Card ejected!/r/n")));
- return SD_API_STATUS_DEVICE_REMOVED;
- }
- if(vm_pSDIReg->SDICSTA & COMMAND_TIMED_OUT)
- {
- vm_pSDIReg->SDICSTA = COMMAND_TIMED_OUT;
- DEBUGMSG (SDCARD_ZONE_ERROR,(TEXT("GetCommandResponse returned SD_API_STATUS_RESPONSE_TIMEOUT (COMMAND_TIMED_OUT)")));
- return SD_API_STATUS_RESPONSE_TIMEOUT;
- }
-
- if(vm_pSDIReg->SDIDSTA & CRC_CHECK_FAILED)
- {
- vm_pSDIReg->SDIDSTA = CRC_CHECK_FAILED;
- DEBUGMSG (SDCARD_ZONE_ERROR,(TEXT("GetCommandResponse returned SD_API_STATUS_CRC_ERROR (CRC_CHECK_FAILED)")));
- return SD_API_STATUS_CRC_ERROR;
- }
-
- if(vm_pSDIReg->SDIDSTA & DATA_TRANSMIT_CRC_ERROR)
- {
- vm_pSDIReg->SDIDSTA = DATA_TRANSMIT_CRC_ERROR;
- DEBUGMSG (SDCARD_ZONE_ERROR,(TEXT("getSDICommandResponse returned SD_API_STATUS_CRC_ERROR (DATA_TRANSMIT_CRC_ERROR)")));
- return SD_API_STATUS_CRC_ERROR;
- }
-
- if(vm_pSDIReg->SDIDSTA & DATA_RECEIVE_CRC_ERROR)
- {
- vm_pSDIReg->SDIDSTA = DATA_RECEIVE_CRC_ERROR;
- DEBUGMSG (SDCARD_ZONE_ERROR,(TEXT("GetCommandResponse returned SD_API_STATUS_CRC_ERROR (DATA_RECEIVE_CRC_ERROR)")));
- return SD_API_STATUS_CRC_ERROR;
- }
-
- if(vm_pSDIReg->SDIDSTA & DATA_TIME_OUT)
- {
- vm_pSDIReg->SDIDSTA = DATA_TIME_OUT;
- DEBUGMSG (SDCARD_ZONE_ERROR,(TEXT("GetCommandResponse returned SD_API_STATUS_DATA_TIMEOUT (DATA_TIME_OUT)")));
- return SD_API_STATUS_DATA_TIMEOUT;
- }
- }
- vm_pSDIReg->SDICSTA = RESPONSE_RECEIVED;
-
-
-
-
- respBuff = pRequest->CommandResponse.ResponseBuffer;
- switch(pRequest->CommandResponse.ResponseType)
- {
- case NoResponse:
- break;
-
- case ResponseR1:
- case ResponseR1b:
-
-
-
-
- *(respBuff ) = (BYTE)(START_BIT | TRANSMISSION_BIT | pRequest->CommandCode);
- *(respBuff + 1) = (BYTE)(vm_pSDIReg->SDIRSP0 );
- *(respBuff + 2) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 8 );
- *(respBuff + 3) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 16);
- *(respBuff + 4) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 24);
- *(respBuff + 5) = (BYTE)(END_RESERVED | END_BIT);
- break;
-
- case ResponseR3:
- case ResponseR4:
-
-
-
- *(respBuff ) = (BYTE)(START_BIT | TRANSMISSION_BIT | START_RESERVED);
- *(respBuff + 1) = (BYTE)(vm_pSDIReg->SDIRSP0 );
- *(respBuff + 2) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 8 );
- *(respBuff + 3) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 16);
- *(respBuff + 4) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 24);
- *(respBuff + 5) = (BYTE)(END_RESERVED | END_BIT);
- break;
-
- case ResponseR5:
- case ResponseR6:
-
-
-
- *(respBuff ) = (BYTE)(START_BIT | TRANSMISSION_BIT | pRequest->CommandCode);
- *(respBuff + 1) = (BYTE)(vm_pSDIReg->SDIRSP0 );
- *(respBuff + 2) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 8 );
- *(respBuff + 3) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 16);
- *(respBuff + 4) = (BYTE)(vm_pSDIReg->SDIRSP0 >> 24);
- *(respBuff + 5) = (BYTE)(vm_pSDIReg->SDIRSP1 >> 24);
- break;
-
- case ResponseR2:
-
-
-
-
-
-
-
-
-
- *(respBuff + 0) = (BYTE)(vm_pSDIReg->SDIRSP3 );
- *(respBuff + 1) = (BYTE)(vm_pSDIReg->SDIRSP3 >> 8 );
- *(respBuff + 2) = (BYTE)(vm_pSDIReg->SDIRSP3 >> 16);
- *(respBuff + 3) = (BYTE)(vm_pSDIReg->SDIRSP3 >> 24);
-
- *(respBuff + 4) = (BYTE)(vm_pSDIReg->SDIRSP2 );
- *(respBuff + 5) = (BYTE)(vm_pSDIReg->SDIRSP2 >> 8 );
- *(respBuff + 6) = (BYTE)(vm_pSDIReg->SDIRSP2 >> 16);
- *(respBuff + 7) = (BYTE)(vm_pSDIReg->SDIRSP2 >> 24);
-
- *(respBuff + 8) = (BYTE)(vm_pSDIReg->SDIRSP1 );
- *(respBuff + 9) = (BYTE)(vm_pSDIReg->SDIRSP1 >> 8 );
- *(respBuff + 10)= (BYTE)(vm_pSDIReg->SDIRSP1 >> 16);
- *(respBuff + 11)= (BYTE)(vm_pSDIReg->SDIRSP1 >> 24);
-
- *(respBuff + 12)= (BYTE)(vm_pSDIReg->SDIRSP0 );
- *(respBuff + 13)= (BYTE)(vm_pSDIReg->SDIRSP0 >> 8 );
- *(respBuff + 14)= (BYTE)(vm_pSDIReg->SDIRSP0 >> 16);
- *(respBuff + 15)= (BYTE)(vm_pSDIReg->SDIRSP0 >> 24);
- break;
-
- default:
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:GetCmdResponse(): Unrecognized response type!/r/n")));
- break;
- }
-
- DEBUGMSG (SDHC_RESPONSE_ZONE,(TEXT("GetCommandResponse returned SD_API_STATUS_SUCCESS")));
- return SD_API_STATUS_SUCCESS;
- }
14.SetupDmaXfer
DMA传输,分两种情况SD_READ和SD_WRITE,首先设置request类型(SD_READ或SD_WRITE),reset fifo,设置BlockSize(SDIBSIZE寄存器),根据m_dwDMAChannel(0-3)设置DMA寄存器,设置源/目的地址,源地址periperal bus, fixed addr,目的地址system bus, increment addr,设置DMA通道传输特性handshake, sync PCLK, interrupt, single RX, single service,, MMC request, no auto-reload, word (32 bits), RX count,SD_READ和SD_WRITE的源和目的地址正好相反.
当SD_CMD_STOP_TRANSMISSION命令时,设置BUSY_AFTER_COMMAND
15.IsCardBusy
检查Card是否处在Busy状态.检查SDICSTA和SDIDSTA状态寄存器,COMMAND_IN_PROGRESS,DATA_TRANSMIT_IN_PROGRESS,DATA_RECIEVE_IN_PROGRESS,READ_WAIT_REQUEST_OCCURE状态发生时,Card处于Busy状态.
- BOOL CSDIOControllerBase::IsCardBusy(UINT16 inData)
- {
-
- if(vm_pSDIReg->SDICSTA & COMMAND_IN_PROGRESS)
- return TRUE;
-
-
- if((vm_pSDIReg->SDIDSTA & DATA_TRANSMIT_IN_PROGRESS) ||
- (vm_pSDIReg->SDIDSTA & DATA_RECIEVE_IN_PROGRESS))
- return TRUE;
-
-
- if(vm_pSDIReg->SDIDSTA & READ_WAIT_REQUEST_OCCURED)
- return TRUE;
-
- return FALSE;
- }
16.SetClockRate
设置SDI clock时钟频率.首先检查参数正确性,频率最大为25MHz.如果输入MMC全速频率20MHz,由于2410在20MHz会有问题,所以设置成20MHz,然后计算分频值prescale = ((PCLK / (2*baud_rate)) - 1,然后确保SDI时钟处于停止状态,最后设置SDIPRE寄存器设置分配值,并启动SDI时钟.
- DWORD CSDIOControllerBase::SetClockRate(DWORD dwClockRate)
- {
- if((dwClockRate < 0) || (dwClockRate > SD_FULL_SPEED_RATE))
- {
- DEBUGMSG(ZONE_ENABLE_ERROR, (TEXT("SDHCDriver:SetClockRate() - invalid clock rate %d !/r/n"), dwClockRate));
- goto DONE;
- }
-
-
-
-
-
-
- if(dwClockRate == MMC_FULL_SPEED_RATE)
- {
- dwClockRate = 10000000;
- }
-
-
-
-
-
-
-
-
- DWORD dwPrescale = dwClockRate ? ( (PCLK / (2*dwClockRate)) - 1 ) : 0xff;
- DWORD dwActualRate = PCLK / 2 / ( dwPrescale + 1 );
-
-
- if( dwActualRate > dwClockRate )
- {
- dwPrescale++;
-
-
- dwActualRate = PCLK / 2 / ( dwPrescale + 1 );
- }
-
-
- if( dwPrescale > 0xff )
- {
- dwPrescale = 0xff;
-
-
- dwActualRate = PCLK / 2 / ( dwPrescale + 1 );
- }
-
- BOOL fClockIsRunning = Is_SDI_Clock_Running();
-
-
- if( fClockIsRunning )
- {
- Stop_SDI_Clock();
- }
-
-
- vm_pSDIReg->SDIPRE = dwPrescale;
-
- DEBUGMSG(SDHC_CLOCK_ZONE, (TEXT("SDHCD:SetClockRate() - Clock rate set to %d Hz/n"), dwActualRate));
-
- if( fClockIsRunning )
- {
- Start_SDI_Clock();
- }
-
-
- m_dwClockRate = dwActualRate;
-
- DONE:
- return m_dwClockRate;
- }
17.PollingTransmit
用来轮询发送数据.首先判断一些错误状态是否发生,如卡不再插槽,FIFO Fail,CRC error等就返回false.状态正常则读取SDIFSTA看FIFO能否接收更多数据.可以就向SDIDAT写数据.直至FIFO满为止.然后监测数据是否写完,并设置DATA_TRANSMIT_FINISHED.
- BOOL CSDIOControllerBase::PollingTransmit(PSD_BUS_REQUEST pRequest, DWORD dwLen)
- {
- BOOL fRetVal = TRUE;
- PBYTE pBuff = pRequest->pBlockBuffer;
-
- SD_SET_PROC_PERMISSIONS_FROM_REQUEST( pRequest ) {
- __try {
-
- while(dwLen > 0)
- {
- if( !m_fCardInTheSlot )
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:PollingTransmit() - Card ejected!/r/n")));
- fRetVal = FALSE;
- break;
- }
- if((vm_pSDIReg->SDIDSTA & FIFO_FAIL_ERROR))
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:PollingTransmit() - FIFO Error!/r/n")));
- fRetVal = FALSE;
- break;
- }
- if((vm_pSDIReg->SDIDSTA & DATA_TRANSMIT_CRC_ERROR))
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:PollingTransmit() - Transmit CRC Error!/r/n")));
- fRetVal = FALSE;
- break;
- }
- if((vm_pSDIReg->SDIDSTA & DATA_TIME_OUT))
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:PollingTransmit() - Data timeout!/r/n")));
- fRetVal = FALSE;
- break;
- }
-
- if((vm_pSDIReg->SDIFSTA & FIFO_AVAIL_FOR_TX))
- {
- *(PBYTE)&(vm_pSDIReg->SDIDAT) = *pBuff++;
- dwLen--;
- }
- }
- } __except (SDProcessException(GetExceptionInformation())) {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("--- SDHC Driver: Exception caught in PollingTransmit/n")));
- fRetVal = FALSE;
- }
- } SD_RESTORE_PROC_PERMISSIONS();
-
- if( fRetVal )
- {
- DWORD dwWaitCount = 0;
-
- while(!(vm_pSDIReg->SDIDSTA & DATA_TRANSMIT_FINISHED))
- {
- dwWaitCount++;
- if( dwWaitCount > WAIT_TIME )
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:PollingTransmit() - timeout waiting for DATA_TRANSMIT_FINISHED!/r/n")));
- return SD_API_STATUS_RESPONSE_TIMEOUT;
- }
-
- if( !IsCardPresent() )
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:PollingTransmit() - Card ejected!/r/n")));
- fRetVal = FALSE;
- break;
- }
- if((vm_pSDIReg->SDIDSTA & FIFO_FAIL_ERROR))
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:PollingTransmit() - FIFO Error waiting for DATA_TRANSMIT_FINISHED!/r/n")));
- fRetVal = FALSE;
- break;
- }
- if((vm_pSDIReg->SDIDSTA & DATA_TRANSMIT_CRC_ERROR))
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:PollingTransmit() - Transmit CRC Error waiting for DATA_TRANSMIT_FINISHED!/r/n")));
- fRetVal = FALSE;
- break;
- }
- if((vm_pSDIReg->SDIDSTA & DATA_TIME_OUT))
- {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:PollingTransmit() - Data timeout waiting for DATA_TRANSMIT_FINISHED!/r/n")));
- fRetVal = FALSE;
- break;
- }
- }
- vm_pSDIReg->SDIDSTA = DATA_TRANSMIT_FINISHED;
- }
-
- return fRetVal;
- }
18.PollingReceive
轮询接收数据.首先判断一些错误状态是否发生,没有的话读SDIFSTA寄存器看是否有数据,有的话读取数据到缓冲区中.