diff -r 4816d766a08a -r f345bda72bc4 Symbian3/PDK/Source/GUID-2344B900-5EC5-4467-BEAD-AB55C88CE63E.dita
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/PDK/Source/GUID-2344B900-5EC5-4467-BEAD-AB55C88CE63E.dita Tue Mar 30 11:56:28 2010 +0100
@@ -0,0 +1,134 @@
+
+
+
+
+
+Stack
+Implementation GuideHow to implement the platform-specific class for an SDIO stack
+of an SDIO-based hardware component.
+The stack is provided by the DSDIOStack class. The developers
+porting the SDIO Controller must derive the DSDIOStack class
+and implement three platform-specific functions: IssueMMCCommandSM(), EnableSDIOInterrupt() and MaxBlockSize().
+The following sections describe how to implement these functions in the DMySdioStack class
+derived from DSIOStack.
+Hardware registersThe DMySdioStack class
+needs to have access to the values and offsets of the SDIO configuration registers.
+Refer to the platform documentation and declare appropriate constants in the
+header file of the stack class.
+IssueMMCCommandSM()If
+you have not declared it already, declare the following function in the definition
+of DMySdioStack:TMMCErr IssueMMCCommandSM();
DSDIOStack::IssueMMCCommandSM() handles the commands to the bus and must be extended to support the SDIO
+protocol. See also DSDStack::IssueMMCCommandsSM().
Rely on the platform documentation to perform the operations and
+update appropriate hardware registers when you intercept the following commands:
+IO_OP_COND (CMD5)
+IO_RW_DIRECT (CMD52)
+IO_RW_EXTENDED (CMD53)
+
You should also handle the additional IO_SEND_OP_COND (R4)
+and IO_RW_DIRECT (R5) responses.
In the following example,
+the hypothetical hardware platform has two requirements, which are implemented
+by the IssueMMCCommandSM() function. The function disables
+the CRC7 check when receiving an R4 response to an CMD5 command, and disables
+the SDIO interrupt before issuing a CMD52 command.void DMySdioStack::IssueMMCCommandSM()
+ {
+ TMMCCommandDesc& cmd = Command();
+ ...
+ // CMD5
+ // Disable the CRC7 check for R4 responses
+ if (cmd.iCommand == ECmd5)
+ {
+ // Clear the MMC_CRC7_R4_ENABLE bit
+ // MMC_SDIO_REG_SLOT0 is a 32-bit hardware register for SDIO in slot 0
+ AsspRegister::Modify32(MMC_SDIO_REG_SLOT0, MMC_CRC7_R4_ENABLE, 0);
+ }
+ else
+ {
+ // Set the MMC_CRC7_R4_ENABLE bit
+ AsspRegister::Modify32(MMC_SDIO_REG_SLOT0, 0, MMC_CRC7_R4_ENABLE);
+ }
+
+ // CMD52
+ // Disable SDIO interrupts for CMD 52
+ if (cmd.iCommand == ECmd52)
+ {
+ EnableSDIOInterrupt(EFalse);
+ }
+ ...
+ }
+
As the SDIO Controller is instantiated at run-time, the
+memory used to support the SDIO transfer mechanisms must be allocated dynamically.
+Therefore, you can use two different types of memory and of data transfer:
The KMMCCmdFlagDMARamValid flag of the TMMCCommandDesc object
+indicates which kind of memory transfer to use.
If you use the Programmatic I/O method, you need to queue pending data transfers
+while you handle hardware interrupts. Your platform's documentation specifies
+which interrupts may be received during transfers.
+EnableSDIOInterrupt()Declare
+the following function in the definition of DMySdioStack:virtual void EnableSDIOInterrupt(TBool aEnable);
DSDIOStack::EnableSDIOInterrupt() enables or disables
+the SDIO interrupt.
The following example is a typical implementation
+of EnableSDIOInterrupt():void DMySdioStack::EnableSDIOInterrupt(TBool aEnable)
+ {
+ if (aEnable)
+ {
+ // Set the Interrupt Enable Master Bit
+ // MMC_SDIO_REG_SLOT0 is a 32-bit hardware register for SDIO in slot 0
+ AsspRegister:: Modify32(MMC_SDIO_REG_SLOT0, SDIO_IENM, 0);
+ }
+ else
+ {
+ // Set the Interrupt Enable Master Bit
+ AsspRegister:: Modify32(MMC_SDIO_REG_SLOT0, 0, SDIO_IENM);
+ }
+ }
+
You must also ensure that your interrupt handler checks
+the SDIO interrupt register and the card slot before forwarding the interrupt
+to the stack. If checking the card slot is likely to take too long,
+use a DFC (Delayed Function Call) for the interrupt handler to preserve real-time
+performance.
The following example illustrates how to implement
+this aspect of the interrupt handler:void DMySdioInterrupt::Service(TAny* aSelf)
+ {
+ ...
+ // Get access to the stack
+ DPlatMMCStack* stack = (reinterpret_cast<DMySdioInterrupt*>(aSelf))->Stack();
+
+ // MMC_SDIO_REG_SLOT0 is a 32-bit hardware register for SDIO in slot 0
+ TInt32 sdioReg = AsspRegister::Read32(MMC_SDIO_REG_SLOT0);
+ // Test for the SDIO interrupt
+ if (sdioReg & KMMC_SDIO_IntPending)
+ {
+ // Trigger the PIL’s interrupt handler for slot 0
+ stack->HandleSDIOInterrupt(0);
+ return;
+ }
+
+ // MMC_SDIO_REG_SLOT1 is a 32-bit hardware register for SDIO in slot 1
+ sdioReg = AsspRegister::Read32(MMC_SDIO_REG_SLOT1);
+ // Test for the SDIO interrupt
+ if (sdioReg & KMMC_SDIO_IntPending)
+ {
+ // Trigger the PIL’s interrupt handler for slot 1
+ stack->HandleSDIOInterrupt(1);
+ return;
+ }
+
+ ...
+ }
+
+MaxBlockSize() Declare
+the following function in the definition of DMySdioStack:virtual TUint32 MaxBlockSize() const;
DSDIOStack::MaxBlockSize() returns the maximum block size in bytes
+that can be transferred on the SDIO bus. Extended read/write commands require
+this information.
In the SD protocol, the block size must be a power
+of two. SDIO does not have the same constraint and the block size can be anything
+between 1 and 2048.
The following example is a typical implementation
+of MaxBlockSize():TUint32 DMySdioStack::MaxBlockSize() const
+ {
+ return(512);
+ }
+
+
\ No newline at end of file