File: C:\M91449\Perso\RTWdsPIC\Developpements\Forum\resodad_john\myFolder\SDtroubleshooting\..\Microchip\MDD File System\SD-SPI.c

    1   /******************************************************************************
    2    *
    3    *               Microchip Memory Disk Drive File System
    4    *
    5    ******************************************************************************
    6    * FileName:        SD-SPI.c
    7    * Dependencies:    SD-SPI.h
    8    *                  string.h
    9    *                  FSIO.h
   10    *                  FSDefs.h
   11    * Processor:       PIC18/PIC24/dsPIC30/dsPIC33/PIC32
   12    * Compiler:        C18/C30/C32
   13    * Company:         Microchip Technology, Inc.
   14    *
   15    * Software License Agreement
   16    *
   17    * The software supplied herewith by Microchip Technology Incorporated
   18    * (the "Company") for its PICmicro® Microcontroller is intended and
   19    * supplied to you, the Company’s customer, for use solely and
   20    * exclusively on Microchip PICmicro Microcontroller products. The
   21    * software is owned by the Company and/or its supplier, and is
   22    * protected under applicable copyright laws. All rights are reserved.
   23    * Any use in violation of the foregoing restrictions may subject the
   24    * user to criminal sanctions under applicable laws, as well as to
   25    * civil liability for the breach of the terms and conditions of this
   26    * license.
   27    *
   28    * THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
   29    * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
   30    * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   31    * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
   32    * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
   33    * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
   34    *
   35   *****************************************************************************
   36    File Description:
   37   
   38    Change History:
   39     Rev     Description
   40     -----   -----------
   41     1.2.5   Fixed bug in the calculation of the capacity for v1.0 devices
   42     1.3.0   Improved media initialization sequence, for better card compatibility
   43             (especially with SDHC cards).
   44             Implemented SPI optimizations for data transfer rate improvement.
   45             Added new MDD_SDSPI_AsyncReadTasks() and MDD_SDSPI_AsyncWriteTasks() 
   46             API functions.  These are non-blocking, state machine based read/write
   47             handlers capable of considerably improved data throughput, particularly
   48             for multi-block reads and multi-block writes.
   49     1.3.2   Modified MDD_SDSPI_AsyncWriteTasks() so pre-erase command only gets
   50             used for multi-block write scenarios.   
   51     1.3.4   1) Added support for dsPIC33E & PIC24E controllers.
   52             2) #include "HardwareProfile.h" is moved up in the order.
   53             3) "SPI_INTERRUPT_FLAG_ASM" macro has to be defined in "HardwareProfile.h" file
   54                for PIC18 microcontrollers.Or else an error is generated while building
   55                the code.
   56                          "#define SPI_INTERRUPT_FLAG_ASM  PIR1, 3" is removed from SD-SPI.c
   57             4) Replaced "__C30" usage with "__C30__" .
   58   
   59   ********************************************************************/
   60   
   61   #include "Compiler.h"
   62   #include "GenericTypeDefs.h"
   63   #include "HardwareProfile.h"
   64   #include "MDD File System/FSIO.h"
   65   #include "MDD File System/FSDefs.h"
   66   #include "MDD File System/SD-SPI.h"
   67   #include "string.h"
   68   #include "FSConfig.h"
   69   
   70   /******************************************************************************
   71    * Global Variables
   72    *****************************************************************************/
   73   
   74   // Description:  Used for the mass-storage library to determine capacity
   75   DWORD MDD_SDSPI_finalLBA;
   76   WORD gMediaSectorSize;
   77   BYTE gSDMode;
   78   static MEDIA_INFORMATION mediaInformation;
   79   static ASYNC_IO ioInfo; //Declared global context, for fast/code efficient access
   80   
   81   
   82   #ifdef __18CXX
   83       // Summary: Table of SD card commands and parameters
   84       // Description: The sdmmc_cmdtable contains an array of SD card commands, the corresponding CRC code, the
   85       //              response type that the card will return, and a parameter indicating whether to expect
   86       //              additional data from the card.
   87       const rom typMMC_CMD sdmmc_cmdtable[] =
   88   #else
   89       const typMMC_CMD sdmmc_cmdtable[] =
   90   #endif
   91   {
   92       // cmd                      crc     response
   93       {cmdGO_IDLE_STATE,          0x95,   R1,     NODATA},
   94       {cmdSEND_OP_COND,           0xF9,   R1,     NODATA},
   95       {cmdSEND_IF_COND,      		0x87,   R7,     NODATA},
   96       {cmdSEND_CSD,               0xAF,   R1,     MOREDATA},
   97       {cmdSEND_CID,               0x1B,   R1,     MOREDATA},
   98       {cmdSTOP_TRANSMISSION,      0xC3,   R1b,    NODATA},
   99       {cmdSEND_STATUS,            0xAF,   R2,     NODATA},
  100       {cmdSET_BLOCKLEN,           0xFF,   R1,     NODATA},
  101       {cmdREAD_SINGLE_BLOCK,      0xFF,   R1,     MOREDATA},
  102       {cmdREAD_MULTI_BLOCK,       0xFF,   R1,     MOREDATA},
  103       {cmdWRITE_SINGLE_BLOCK,     0xFF,   R1,     MOREDATA},
  104       {cmdWRITE_MULTI_BLOCK,      0xFF,   R1,     MOREDATA}, 
  105       {cmdTAG_SECTOR_START,       0xFF,   R1,     NODATA},
  106       {cmdTAG_SECTOR_END,         0xFF,   R1,     NODATA},
  107       {cmdERASE,                  0xDF,   R1b,    NODATA},
  108       {cmdAPP_CMD,                0x73,   R1,     NODATA},
  109       {cmdREAD_OCR,               0x25,   R7,     NODATA},
  110       {cmdCRC_ON_OFF,             0x25,   R1,     NODATA},
  111       {cmdSD_SEND_OP_COND,        0xFF,   R7,     NODATA}, //Actual response is R3, but has same number of bytes as R7.
  112       {cmdSET_WR_BLK_ERASE_COUNT, 0xFF,   R1,     NODATA}
  113   };
  114   
  115   
  116   
  117   
  118   /******************************************************************************
  119    * Prototypes
  120    *****************************************************************************/
  121   extern void Delayms(BYTE milliseconds);
  122   BYTE MDD_SDSPI_ReadMedia(void);
  123   MEDIA_INFORMATION * MDD_SDSPI_MediaInitialize(void);
  124   MMC_RESPONSE SendMMCCmd(BYTE cmd, DWORD address);
  125   
  126   #if defined __C30__ || defined __C32__
  127       void OpenSPIM ( unsigned int sync_mode);
  128       void CloseSPIM( void );
  129       unsigned char WriteSPIM( unsigned char data_out );
  130   #elif defined __18CXX
  131       void OpenSPIM ( unsigned char sync_mode);
  132       void CloseSPIM( void );
  133       unsigned char WriteSPIM( unsigned char data_out );
  134   
  135       unsigned char WriteSPIManual(unsigned char data_out);
  136       BYTE ReadMediaManual (void);
  137       MMC_RESPONSE SendMMCCmdManual(BYTE cmd, DWORD address);
  138   #endif
  139   void InitSPISlowMode(void);
  140   
  141   #if defined __18CXX
  142   //Private function prototypes
  143   static void PIC18_Optimized_SPI_Write_Packet(void);
  144   static void PIC18_Optimized_SPI_Read_Packet(void);
  145   #endif
  146   
  147   //-------------Function name redirects------------------------------------------
  148   //During the media initialization sequence, it is
  149   //necessary to clock the media at no more than 400kHz SPI speeds, since some
  150   //media types power up in open drain output mode and cannot run fast initially.
  151   //On PIC18 devices, when the CPU is run at full frequency, the standard SPI 
  152   //prescalars cannot reach a low enough SPI frequency.  Therefore, we initialize
  153   //the card at low speed using bit-banged SPI on PIC18 devices.  On 
  154   //PIC32/PIC24/dsPIC devices, the SPI module is flexible enough to reach <400kHz
  155   //speeds regardless of CPU frequency, and therefore bit-banged code is not 
  156   //necessary.  Therefore, we use function redirects where necessary, to point to
  157   //the proper SPI related code, given the processor type.
  158   
  159   #if defined __18CXX
  160       #define SendMediaSlowCmd    SendMMCCmdManual
  161       #define WriteSPISlow        WriteSPIManual
  162   #else
  163       #define SendMediaSlowCmd    SendMMCCmd
  164       #define WriteSPISlow        WriteSPIM
  165   #endif
  166   //------------------------------------------------------------------------------
  167   
  168   
  169   #ifdef __PIC32MX__
  170   /*********************************************************
  171     Function:
  172       static inline __attribute__((always_inline)) unsigned char SPICacutateBRG (unsigned int pb_clk, unsigned int spi_clk)
  173     Summary:
  174       Calculate the PIC32 SPI BRG value
  175     Conditions:
  176       None
  177     Input:
  178       pb_clk -  The value of the PIC32 peripheral clock
  179       spi_clk - The desired baud rate
  180     Return:
  181       The corresponding BRG register value.
  182     Side Effects:
  183       None.
  184     Description:
  185       The SPICalutateBRG function is used to determine an appropriate BRG register value for the PIC32 SPI module.
  186     Remarks:
  187       None                                                  
  188     *********************************************************/
  189   
  190   static inline __attribute__((always_inline)) unsigned char SPICalutateBRG(unsigned int pb_clk, unsigned int spi_clk)
  191   {
  192       unsigned int brg;
  193   
  194       brg = pb_clk / (2 * spi_clk);
  195   
  196       if(pb_clk % (2 * spi_clk))
  197           brg++;
  198   
  199       if(brg > 0x100)
  200           brg = 0x100;
  201   
  202       if(brg)
  203           brg--;
  204   
  205       return (unsigned char) brg;
  206   }
  207   #endif
  208   
  209   
  210   /*********************************************************
  211     Function:
  212       BYTE MDD_SDSPI_MediaDetect
  213     Summary:
  214       Determines whether an SD card is present
  215     Conditions:
  216       The MDD_MediaDetect function pointer must be configured
  217       to point to this function in FSconfig.h
  218     Input:
  219       None
  220     Return Values:
  221       TRUE -  Card detected
  222       FALSE - No card detected
  223     Side Effects:
  224       None.
  225     Description:
  226       The MDD_SDSPI_MediaDetect function determine if an SD card is connected to 
  227       the microcontroller.
  228       If the MEDIA_SOFT_DETECT is not defined, the detection is done by polling
  229       the SD card detect pin.
  230       The MicroSD connector does not have a card detect pin, and therefore a
  231       software mechanism must be used. To do this, the SEND_STATUS command is sent 
  232       to the card. If the card is not answering with 0x00, the card is either not 
  233       present, not configured, or in an error state. If this is the case, we try
  234       to reconfigure the card. If the configuration fails, we consider the card not 
  235       present (it still may be present, but malfunctioning). In order to use the 
  236       software card detect mechanism, the MEDIA_SOFT_DETECT macro must be defined.
  237       
  238     Remarks:
  239       None                                                  
  240     *********************************************************/
  241   
  242   BYTE MDD_SDSPI_MediaDetect (void)
  243   {
  244   #ifndef MEDIA_SOFT_DETECT
  245       return(!SD_CD);
  246   #else
  247   	MMC_RESPONSE    response;
  248   
  249       //First check if SPI module is enabled or not.
  250   	if (SPIENABLE == 0)
  251   	{
  252   		//If the SPI module is not enabled, then the media has evidently not
  253   		//been initialized.  Try to send CMD0 and CMD13 to reset the device and
  254   		//get it into SPI mode (if present), and then request the status of
  255   		//the media.  If this times out, then the card is presumably not physically
  256   		//present.
  257   		
  258   		InitSPISlowMode();
  259   		
  260           //Send CMD0 to reset the media
  261   	    //If the card is physically present, then we should get a valid response.
  262   	    response = SendMediaSlowCmd(GO_IDLE_STATE,0x0);
  263   	    //Check if response was invalid (R1 response byte should be = 0x01 after GO_IDLE_STATE)
  264   	    if(response.r1._byte != 0x01)
  265   	    {
  266   	        CloseSPIM();
  267   	        return FALSE;
  268   	    }    
  269   	    else
  270   	    {
  271       	    //Card is presumably present.  The SDI pin should have a pull up resistor on
  272       	    //it, so the odds of SDI "floating" to 0x01 after sending CMD0 is very
  273       	    //remote, unless the media is genuinely present.  Therefore, we should
  274       	    //try to perform a full card initialization sequence now.
  275       		MDD_SDSPI_MediaInitialize();    //Can block and take a long time to execute.
  276       		if(mediaInformation.errorCode == MEDIA_NO_ERROR)
  277       		{
  278       			/* if the card was initialized correctly, it means it is present */
  279       			return TRUE;
  280       		}
  281       		else 
  282       		{
  283           		CloseSPIM();
  284       			return FALSE;
  285       		}		
  286   
  287       	}    
  288   	}//if (SPIENABLE == 0)
  289   	else
  290   	{
  291       	//The SPI module was already enabled.  This most likely means the media is
  292       	//present and has already been initialized.  However, it is possible that
  293       	//the user could have unplugged the media, in which case it is no longer
  294       	//present.  We should send it a command, to check the status.
  295       	response = SendMMCCmd(SEND_STATUS,0x0);
  296       	if((response.r2._word & 0xEC0C) != 0x0000)
  297   	    {
  298       	    //The card didn't respond with the expected result.  This probably
  299       	    //means it is no longer present.  We can try to re-initialized it,
  300       	    //just to be doubly sure.
  301       		CloseSPIM();
  302       		MDD_SDSPI_MediaInitialize();    //Can block and take a long time to execute.
  303       		if(mediaInformation.errorCode == MEDIA_NO_ERROR)
  304       		{
  305       			/* if the card was initialized correctly, it means it is present */
  306       			return TRUE;
  307       		}
  308       		else 
  309       		{
  310           		CloseSPIM();
  311       			return FALSE;
  312       		}
  313       	}
  314       	else
  315       	{
  316           	//The CMD13 response to SEND_STATUS was valid.  This presumably
  317           	//means the card is present and working normally.
  318           	return TRUE;
  319           }   	    
  320   
  321   	}
  322   
  323       //Should theoretically never execute to here.  All pathways should have 
  324       //already returned with the status.
  325       return TRUE;
  326   
  327   #endif
  328   
  329   }//end MediaDetect
  330   
  331   
  332   
  333   /*********************************************************
  334     Function:
  335       WORD MDD_SDSPI_ReadSectorSize (void)
  336     Summary:
  337       Determines the current sector size on the SD card
  338     Conditions:
  339       MDD_MediaInitialize() is complete
  340     Input:
  341       None
  342     Return:
  343       The size of the sectors for the physical media
  344     Side Effects:
  345       None.
  346     Description:
  347       The MDD_SDSPI_ReadSectorSize function is used by the
  348       USB mass storage class to return the card's sector
  349       size to the PC on request.
  350     Remarks:
  351       None
  352     *********************************************************/
  353   
  354   WORD MDD_SDSPI_ReadSectorSize(void)
  355   {
  356       return gMediaSectorSize;
  357   }
  358   
  359   
  360   /*********************************************************
  361     Function:
  362       DWORD MDD_SDSPI_ReadCapacity (void)
  363     Summary:
  364       Determines the current capacity of the SD card
  365     Conditions:
  366       MDD_MediaInitialize() is complete
  367     Input:
  368       None
  369     Return:
  370       The capacity of the device
  371     Side Effects:
  372       None.
  373     Description:
  374       The MDD_SDSPI_ReadCapacity function is used by the
  375       USB mass storage class to return the total number
  376       of sectors on the card.
  377     Remarks:
  378       None
  379     *********************************************************/
  380   DWORD MDD_SDSPI_ReadCapacity(void)
  381   {
  382       return (MDD_SDSPI_finalLBA);
  383   }
  384   
  385   
  386   /*********************************************************
  387     Function:
  388       WORD MDD_SDSPI_InitIO (void)
  389     Summary:
  390       Initializes the I/O lines connected to the card
  391     Conditions:
  392       MDD_MediaInitialize() is complete.  The MDD_InitIO
  393       function pointer is pointing to this function.
  394     Input:
  395       None
  396     Return:
  397       None
  398     Side Effects:
  399       None.
  400     Description:
  401       The MDD_SDSPI_InitIO function initializes the I/O
  402       pins connected to the SD card.
  403     Remarks:
  404       None
  405     *********************************************************/
  406   
  407   void MDD_SDSPI_InitIO (void)
  408   {
  409       // Turn off the card
  410       SD_CD_TRIS = INPUT;            //Card Detect - input
  411       SD_CS = 1;                     //Initialize Chip Select line
  412       SD_CS_TRIS = OUTPUT;           //Card Select - output
  413       SD_WE_TRIS = INPUT;            //Write Protect - input
  414   
  415   #if defined	(__dsPIC33E__) || defined (__PIC24E__)
  416       SD_CS_ANSEL = 0;
  417       SD_SCK_ANSEL = 0;
  418       SD_SDI_ANSEL = 0;
  419       SD_SDO_ANSEL = 0;
  420   #endif    
  421   }
  422   
  423   
  424   
  425   /*********************************************************
  426     Function:
  427       BYTE MDD_SDSPI_ShutdownMedia (void)
  428     Summary:
  429       Disables the SD card
  430     Conditions:
  431       The MDD_ShutdownMedia function pointer is pointing 
  432       towards this function.
  433     Input:
  434       None
  435     Return:
  436       None
  437     Side Effects:
  438       None.
  439     Description:
  440       This function will disable the SPI port and deselect
  441       the SD card.
  442     Remarks:
  443       None
  444     *********************************************************/
  445   
  446   BYTE MDD_SDSPI_ShutdownMedia(void)
  447   {
  448       // close the spi bus
  449       CloseSPIM();
  450       
  451       // deselect the device
  452       SD_CS = 1;
  453   
  454       return 0;
  455   }
  456   
  457   
  458   /*****************************************************************************
  459     Function:
  460       MMC_RESPONSE SendMMCCmd (BYTE cmd, DWORD address)
  461     Summary:
  462       Sends a command packet to the SD card.
  463     Conditions:
  464       None.
  465     Input:
  466       None.
  467     Return Values:
  468       MMC_RESPONSE    - The response from the card
  469                       - Bit 0 - Idle state
  470                       - Bit 1 - Erase Reset
  471                       - Bit 2 - Illegal Command
  472                       - Bit 3 - Command CRC Error
  473                       - Bit 4 - Erase Sequence Error
  474                       - Bit 5 - Address Error
  475                       - Bit 6 - Parameter Error
  476                       - Bit 7 - Unused. Always 0.
  477     Side Effects:
  478       None.
  479     Description:
  480       SendMMCCmd prepares a command packet and sends it out over the SPI interface.
  481       Response data of type 'R1' (as indicated by the SD/MMC product manual is returned.
  482     Remarks:
  483       None.
  484     *****************************************************************************/
  485   
  486   MMC_RESPONSE SendMMCCmd(BYTE cmd, DWORD address)
  487   {
  488       MMC_RESPONSE    response;
  489       CMD_PACKET  CmdPacket;
  490       WORD timeout;
  491       DWORD longTimeout;
  492       
  493       SD_CS = 0;                           //Select card
  494       
  495       // Copy over data
  496       CmdPacket.cmd        = sdmmc_cmdtable[cmd].CmdCode;
  497       CmdPacket.address    = address;
  498       CmdPacket.crc        = sdmmc_cmdtable[cmd].CRC;       // Calc CRC here
  499       
  500       CmdPacket.TRANSMIT_BIT = 1;             //Set Tranmission bit
  501       
  502       WriteSPIM(CmdPacket.cmd);                //Send Command
  503       WriteSPIM(CmdPacket.addr3);              //Most Significant Byte
  504       WriteSPIM(CmdPacket.addr2);
  505       WriteSPIM(CmdPacket.addr1);
  506       WriteSPIM(CmdPacket.addr0);              //Least Significant Byte
  507       WriteSPIM(CmdPacket.crc);                //Send CRC
  508   
  509       //Special handling for CMD12 (STOP_TRANSMISSION).  The very first byte after
  510       //sending the command packet may contain bogus non-0xFF data.  This 
  511       //"residual data" byte should not be interpreted as the R1 response byte.
  512       if(cmd == STOP_TRANSMISSION)
  513       {
  514           MDD_SDSPI_ReadMedia(); //Perform dummy read to fetch the residual non R1 byte
  515       } 
  516   
  517       //Loop until we get a response from the media.  Delay (NCR) could be up 
  518       //to 8 SPI byte times.  First byte of response is always the equivalent of 
  519       //the R1 byte, even for R1b, R2, R3, R7 responses.
  520       timeout = NCR_TIMEOUT;
  521       do
  522       {
  523           response.r1._byte = MDD_SDSPI_ReadMedia();
  524           timeout--;
  525       }while((response.r1._byte == MMC_FLOATING_BUS) && (timeout != 0));
  526       
  527       //Check if we should read more bytes, depending upon the response type expected.  
  528       if(sdmmc_cmdtable[cmd].responsetype == R2)
  529       {
  530           response.r2._byte1 = response.r1._byte; //We already received the first byte, just make sure it is in the correct location in the struct.
  531           response.r2._byte0 = MDD_SDSPI_ReadMedia(); //Fetch the second byte of the response.
  532       }
  533       else if(sdmmc_cmdtable[cmd].responsetype == R1b)
  534       {
  535           //Keep trying to read from the media, until it signals it is no longer
  536           //busy.  It will continuously send 0x00 bytes until it is not busy.
  537           //A non-zero value means it is ready for the next command.
  538           //The R1b response is received after a CMD12 STOP_TRANSMISSION
  539           //command, where the media card may be busy writing its internal buffer
  540           //to the flash memory.  This can typically take a few milliseconds, 
  541           //with a recommended maximum timeout of 250ms or longer for SD cards.
  542           longTimeout = WRITE_TIMEOUT;
  543           do
  544           {
  545               response.r1._byte = MDD_SDSPI_ReadMedia();
  546               longTimeout--;
  547           }while((response.r1._byte == 0x00) && (longTimeout != 0));
  548   
  549           response.r1._byte = 0x00;
  550       }
  551       else if (sdmmc_cmdtable[cmd].responsetype == R7) //also used for response R3 type
  552       {
  553           //Fetch the other four bytes of the R3 or R7 response.
  554           //Note: The SD card argument response field is 32-bit, big endian format.
  555           //However, the C compiler stores 32-bit values in little endian in RAM.
  556           //When writing to the _returnVal/argument bytes, make sure the order it 
  557           //gets stored in is correct.      
  558           response.r7.bytewise.argument._byte3 = MDD_SDSPI_ReadMedia();
  559           response.r7.bytewise.argument._byte2 = MDD_SDSPI_ReadMedia();
  560           response.r7.bytewise.argument._byte1 = MDD_SDSPI_ReadMedia();
  561           response.r7.bytewise.argument._byte0 = MDD_SDSPI_ReadMedia();
  562       }
  563   
  564       WriteSPIM(0xFF);    //Device requires at least 8 clock pulses after 
  565                                //the response has been sent, before if can process
  566                                //the next command.  CS may be high or low.
  567   
  568       // see if we are expecting more data or not
  569       if(!(sdmmc_cmdtable[cmd].moredataexpected))
  570           SD_CS = 1;
  571   
  572       return(response);
  573   }
  574   
  575   #ifdef __18CXX
  576   /*****************************************************************************
  577     Function:
  578       MMC_RESPONSE SendMMCCmdManual (BYTE cmd, DWORD address)
  579     Summary:
  580       Sends a command packet to the SD card with bit-bang SPI.
  581     Conditions:
  582       None.
  583     Input:
  584       Need input cmd index into a rom table of implemented commands.
  585       Also needs 4 bytes of data as address for some commands (also used for
  586       other purposes in other commands).
  587     Return Values:
  588       Assuming an "R1" type of response, each bit will be set depending upon status:
  589       MMC_RESPONSE    - The response from the card
  590                       - Bit 0 - Idle state
  591                       - Bit 1 - Erase Reset
  592                       - Bit 2 - Illegal Command
  593                       - Bit 3 - Command CRC Error
  594                       - Bit 4 - Erase Sequence Error
  595                       - Bit 5 - Address Error
  596                       - Bit 6 - Parameter Error
  597                       - Bit 7 - Unused. Always 0.
  598       Other response types (ex: R3/R7) have up to 5 bytes of response.  The first
  599       byte is always the same as the R1 response.  The contents of the other bytes 
  600       depends on the command.
  601     Side Effects:
  602       None.
  603     Description:
  604       SendMMCCmd prepares a command packet and sends it out over the SPI interface.
  605       Response data of type 'R1' (as indicated by the SD/MMC product manual is returned.
  606       This function is intended to be used when the clock speed of a PIC18 device is
  607       so high that the maximum SPI divider can't reduce the clock below the maximum
  608       SD card initialization sequence speed.
  609     Remarks:
  610       None.
  611     ***************************************************************************************/
  612   MMC_RESPONSE SendMMCCmdManual(BYTE cmd, DWORD address)
  613   {
  614       BYTE index;
  615       MMC_RESPONSE    response;
  616       CMD_PACKET  CmdPacket;
  617       WORD timeout;
  618       
  619       SD_CS = 0;                           //Select card
  620       
  621       // Copy over data
  622       CmdPacket.cmd        = sdmmc_cmdtable[cmd].CmdCode;
  623       CmdPacket.address    = address;
  624       CmdPacket.crc        = sdmmc_cmdtable[cmd].CRC;       // Calc CRC here
  625       
  626       CmdPacket.TRANSMIT_BIT = 1;             //Set Tranmission bit
  627       
  628       WriteSPIManual(CmdPacket.cmd);                //Send Command
  629       WriteSPIManual(CmdPacket.addr3);              //Most Significant Byte
  630       WriteSPIManual(CmdPacket.addr2);
  631       WriteSPIManual(CmdPacket.addr1);
  632       WriteSPIManual(CmdPacket.addr0);              //Least Significant Byte
  633       WriteSPIManual(CmdPacket.crc);                //Send CRC
  634   
  635       //Special handling for CMD12 (STOP_TRANSMISSION).  The very first byte after
  636       //sending the command packet may contain bogus non-0xFF data.  This 
  637       //"residual data" byte should not be interpreted as the R1 response byte.
  638       if(cmd == STOP_TRANSMISSION)
  639       {
  640           ReadMediaManual(); //Perform dummy read to fetch the residual non R1 byte
  641       } 
  642   
  643       //Loop until we get a response from the media.  Delay (NCR) could be up 
  644       //to 8 SPI byte times.  First byte of response is always the equivalent of 
  645       //the R1 byte, even for R1b, R2, R3, R7 responses.
  646       timeout = NCR_TIMEOUT;
  647       do
  648       {
  649           response.r1._byte = ReadMediaManual();
  650           timeout--;
  651       }while((response.r1._byte == MMC_FLOATING_BUS) && (timeout != 0));
  652       
  653       
  654       //Check if we should read more bytes, depending upon the response type expected.  
  655       if(sdmmc_cmdtable[cmd].responsetype == R2)
  656       {
  657           response.r2._byte1 = response.r1._byte; //We already received the first byte, just make sure it is in the correct location in the struct.
  658           response.r2._byte0 = ReadMediaManual(); //Fetch the second byte of the response.
  659       }
  660       else if(sdmmc_cmdtable[cmd].responsetype == R1b)
  661       {
  662           //Keep trying to read from the media, until it signals it is no longer
  663           //busy.  It will continuously send 0x00 bytes until it is not busy.
  664           //A non-zero value means it is ready for the next command.
  665           timeout = 0xFFFF;
  666           do
  667           {
  668               response.r1._byte = ReadMediaManual();
  669               timeout--;
  670           }while((response.r1._byte == 0x00) && (timeout != 0));
  671   
  672           response.r1._byte = 0x00;
  673       }
  674       else if (sdmmc_cmdtable[cmd].responsetype == R7) //also used for response R3 type
  675       {
  676           //Fetch the other four bytes of the R3 or R7 response.
  677           //Note: The SD card argument response field is 32-bit, big endian format.
  678           //However, the C compiler stores 32-bit values in little endian in RAM.
  679           //When writing to the _returnVal/argument bytes, make sure the order it 
  680           //gets stored in is correct.      
  681           response.r7.bytewise.argument._byte3 = ReadMediaManual();
  682           response.r7.bytewise.argument._byte2 = ReadMediaManual();
  683           response.r7.bytewise.argument._byte1 = ReadMediaManual();
  684           response.r7.bytewise.argument._byte0 = ReadMediaManual();
  685       }
  686   
  687       WriteSPIManual(0xFF);    //Device requires at least 8 clock pulses after 
  688                                //the response has been sent, before if can process
  689                                //the next command.  CS may be high or low.
  690   
  691       // see if we are expecting more data or not
  692       if(!(sdmmc_cmdtable[cmd].moredataexpected))
  693           SD_CS = 1;
  694   
  695       return(response);
  696   }
  697   #endif
  698   
  699   
  700   
  701   /*****************************************************************************
  702     Function:
  703       BYTE MDD_SDSPI_SectorRead (DWORD sector_addr, BYTE * buffer)
  704     Summary:
  705       Reads a sector of data from an SD card.
  706     Conditions:
  707       The MDD_SectorRead function pointer must be pointing towards this function.
  708     Input:
  709       sector_addr - The address of the sector on the card.
  710       buffer -      The buffer where the retrieved data will be stored.  If
  711                     buffer is NULL, do not store the data anywhere.
  712     Return Values:
  713       TRUE -  The sector was read successfully
  714       FALSE - The sector could not be read
  715     Side Effects:
  716       None
  717     Description:
  718       The MDD_SDSPI_SectorRead function reads a sector of data bytes (512 bytes) 
  719       of data from the SD card starting at the sector address and stores them in 
  720       the location pointed to by 'buffer.'
  721     Remarks:
  722       The card expects the address field in the command packet to be a byte address.
  723       The sector_addr value is converted to a byte address by shifting it left nine
  724       times (multiplying by 512).
  725       
  726       This function performs a synchronous read operation.  In other words, this
  727       function is a blocking function, and will not return until either the data
  728       has fully been read, or, a timeout or other error occurred.
  729     ***************************************************************************************/
  730   BYTE MDD_SDSPI_SectorRead(DWORD sector_addr, BYTE* buffer)
  731   {
  732       ASYNC_IO info;
  733       BYTE status;
  734       
  735       //Initialize info structure for using the MDD_SDSPI_AsyncReadTasks() function.
  736       info.wNumBytes = 512;
  737       info.dwBytesRemaining = 512;
  738       info.pBuffer = buffer;
  739       info.dwAddress = sector_addr;
  740       info.bStateVariable = ASYNC_READ_QUEUED;
  741       
  742       //Blocking loop, until the state machine finishes reading the sector,
  743       //or a timeout or other error occurs.  MDD_SDSPI_AsyncReadTasks() will always
  744       //return either ASYNC_READ_COMPLETE or ASYNC_READ_FAILED eventually 
  745       //(could take awhile in the case of timeout), so this won't be a totally
  746       //infinite blocking loop.
  747       while(1)
  748       {
  749           status = MDD_SDSPI_AsyncReadTasks(&info);
  750           if(status == ASYNC_READ_COMPLETE)
  751           {
  752               return TRUE;
  753           }
  754           else if(status == ASYNC_READ_ERROR)
  755           {
  756               return FALSE;
  757           } 
  758       }       
  759   
  760       //Impossible to get here, but we will return a value anyay to avoid possible 
  761       //compiler warnings.
  762       return FALSE;
  763   }    
  764   
  765    
  766   
  767   
  768   
  769   
  770   /*****************************************************************************
  771     Function:
  772       BYTE MDD_SDSPI_AsyncReadTasks(ASYNC_IO* info)
  773     Summary:
  774       Speed optimized, non-blocking, state machine based read function that reads 
  775       data packets from the media, and copies them to a user specified RAM buffer.
  776     Pre-Conditions:
  777       The ASYNC_IO structure must be initialized correctly, prior to calling
  778       this function for the first time.  Certain parameters, such as the user
  779       data buffer pointer (pBuffer) in the ASYNC_IO struct are allowed to be changed
  780       by the application firmware, in between each call to MDD_SDSPI_AsyncReadTasks().
  781       Additionally, the media and microcontroller SPI module should have already 
  782       been initalized before using this function.  This function is mutually
  783       exclusive with the MDD_SDSPI_AsyncWriteTasks() function.  Only one operation
  784       (either one read or one write) is allowed to be in progress at a time, as
  785       both functions share statically allocated resources and monopolize the SPI bus.
  786     Input:
  787       ASYNC_IO* info -        A pointer to a ASYNC_IO structure.  The 
  788                               structure contains information about how to complete
  789                               the read operation (ex: number of total bytes to read,
  790                               where to copy them once read, maximum number of bytes
  791                               to return for each call to MDD_SDSPI_AsyncReadTasks(), etc.).
  792     Return Values:
  793       BYTE - Returns a status byte indicating the current state of the read 
  794               operation. The possible return values are:
  795               
  796               ASYNC_READ_BUSY - Returned when the state machine is busy waiting for
  797                                a data start token from the media.  The media has a
  798                                random access time, which can often be quite long
  799                                (<= ~3ms typ, with maximum of 100ms).  No data
  800                                has been copied yet in this case, and the application
  801                                should keep calling MDD_SDSPI_AsyncReadTasks() until either
  802                                an error/timeout occurs, or ASYNC_READ_NEW_PACKET_READY
  803                                is returned.
  804               ASYNC_READ_NEW_PACKET_READY -   Returned after a single packet, of
  805                                               the specified size (in info->numBytes),
  806                                               is ready to be read from the 
  807                                               media and copied to the user 
  808                                               specified data buffer.  Often, after
  809                                               receiving this return value, the 
  810                                               application firmware would want to
  811                                               update the info->pReceiveBuffer pointer
  812                                               before calling MDD_SDSPI_AsyncReadTasks()
  813                                               again.  This way, the application can
  814                                               begin fetching the next packet worth
  815                                               of data, while still using/consuming
  816                                               the previous packet of data.
  817               ASYNC_READ_COMPLETE - Returned when all data bytes in the read 
  818                                    operation have been read and returned successfully,
  819                                    and the media is now ready for the next operation.
  820               ASYNC_READ_ERROR - Returned when some failure occurs.  This could be
  821                                  either due to a media timeout, or due to some other
  822                                  unknown type of error.  In this case, the 
  823                                  MDD_SDSPI_AsyncReadTasks() handler will terminate
  824                                  the read attempt and will try to put the media 
  825                                  back in a default state, ready for a new command.  
  826                                  The application firmware may then retry the read
  827                                  attempt (if desired) by re-initializing the 
  828                                  ASYNC_IO structure and setting the 
  829                                  bStateVariable = ASYNC_READ_QUEUED.
  830   
  831               
  832     Side Effects:
  833       Uses the SPI bus and the media.  The media and SPI bus should not be
  834       used by any other function until the read operation has either completed
  835       successfully, or returned with the ASYNC_READ_ERROR condition.
  836     Description:
  837       Speed optimized, non-blocking, state machine based read function that reads 
  838       data packets from the media, and copies them to a user specified RAM buffer.
  839       This function uses the multi-block read command (and stop transmission command) 
  840       to perform fast reads of data.  The total amount of data that will be returned 
  841       on any given call to MDD_SDSPI_AsyncReadTasks() will be the info->numBytes parameter.
  842       However, if the function is called repeatedly, with info->bytesRemaining set
  843       to a large number, this function can successfully fetch data sizes >> than
  844       the block size (theoretically anything up to ~4GB, since bytesRemaining is 
  845       a 32-bit DWORD).  The application firmware should continue calling 
  846       MDD_SDSPI_AsyncReadTasks(), until the ASYNC_READ_COMPLETE value is returned 
  847       (or ASYNC_READ_ERROR), even if it has already received all of the data expected.
  848       This is necessary, so the state machine can issue the CMD12 (STOP_TRANMISSION) 
  849       to terminate the multi-block read operation, once the total expected number 
  850       of bytes have been read.  This puts the media back into the default state 
  851       ready for a new command.
  852       
  853       During normal/successful operations, calls to MDD_SDSPI_AsyncReadTasks() 
  854       would typically return:
  855       1. ASYNC_READ_BUSY - repeatedly up to several milliseconds, then 
  856       2. ASYNC_READ_NEW_PACKET_READY - repeatedly, until 512 bytes [media read 
  857           block size] is received, then 
  858       3. Back to ASYNC_READ_BUSY (for awhile, may be short), then
  859       4. Back to ASYNC_READ_NEW_PACKET_READY (repeatedly, until the next 512 byte
  860          boundary, then back to #3, etc.
  861       5. After all data is received successfully, then the function will return 
  862          ASYNC_READ_COMPLETE, for all subsequent calls (until a new read operation
  863          is started, by re-initializing the ASYNC_IO structure, and re-calling
  864          the function).
  865       
  866     Remarks:
  867       This function will monopolize the SPI module during the operation.  Do not
  868       use the SPI module for any other purpose, while a fetch operation is in
  869       progress.  Additionally, the ASYNC_IO structure must not be modified
  870       in a different context, while the MDD_SDSPI_AsyncReadTasks() function is executing.
  871       In between calls to MDD_SDSPI_AsyncReadTasks(), certain parameters, namely the
  872       info->numBytes and info->pReceiveBuffer are allowed to change however.
  873       
  874       The bytesRemaining value must always be an exact integer multiple of numBytes 
  875       for the function to operate correctly.  Additionally, it is recommended, although
  876       not essential, for the bytesRemaining to be an integer multiple of the media
  877       read block size.
  878       
  879       When starting a read operation, the info->stateVariable must be initalized to
  880       ASYNC_READ_QUEUED.  All other fields in the info structure should also be
  881       initialized correctly.
  882       
  883       The info->wNumBytes must always be less than or equal to the media block size,
  884       (which is 512 bytes).  Additionally, info->wNumBytes must always be an exact 
  885       integer factor of the media block size (unless info->dwBytesRemaining is less
  886       than the media block size).  Example values that are allowed for info->wNumBytes
  887       are: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512.
  888     *****************************************************************************/
  889   
  890   BYTE MDD_SDSPI_AsyncReadTasks(ASYNC_IO* info)
  891   {
  892       BYTE bData;
  893       MMC_RESPONSE response;
  894       static WORD blockCounter;
  895       static DWORD longTimeoutCounter;
  896       static BOOL SingleBlockRead;
  897       
  898       //Check what state we are in, to decide what to do.
  899       switch(info->bStateVariable)
  900       {
  901           case ASYNC_READ_COMPLETE:
  902               return ASYNC_READ_COMPLETE;
  903           case ASYNC_READ_QUEUED:
  904               //Start the read request.  
  905               
  906               //Initialize some variables we will use later.
  907               blockCounter = MEDIA_BLOCK_SIZE; //Counter will be used later for block boundary tracking
  908               ioInfo = *info; //Get local copy of structure, for quicker access with less code size
  909   
  910               //SDHC cards are addressed on a 512 byte block basis.  This is 1:1 equivalent
  911               //to LBA addressing.  For standard capacity media, the media is expecting
  912               //a complete byte address.  Therefore, to convert from the LBA address to the
  913               //byte address, we need to multiply by 512.
  914               if (gSDMode == SD_MODE_NORMAL)
  915               {
  916                   ioInfo.dwAddress <<= 9; //Equivalent to multiply by 512
  917               }  
  918               if(ioInfo.dwBytesRemaining <= MEDIA_BLOCK_SIZE)
  919               {
  920                   SingleBlockRead = TRUE;
  921                   response = SendMMCCmd(READ_SINGLE_BLOCK, ioInfo.dwAddress);
  922               }    
  923               else
  924               {
  925                   SingleBlockRead = FALSE;
  926                   response = SendMMCCmd(READ_MULTI_BLOCK, ioInfo.dwAddress);
  927               }    
  928               //Note: SendMMCmd() sends 8 SPI clock cycles after getting the
  929               //response.  This meets the NAC min timing paramemter, so we don't
  930               //need additional clocking here.
  931               
  932               // Make sure the command was accepted successfully
  933               if(response.r1._byte != 0x00)
  934               {
  935                   //Perhaps the card isn't initialized or present.
  936                   info->bStateVariable = ASYNC_READ_ABORT;
  937                   return ASYNC_READ_BUSY; 
  938               }
  939               
  940               //We successfully sent the READ_MULTI_BLOCK command to the media.
  941               //We now need to keep polling the media until it sends us the data
  942               //start token byte.
  943               longTimeoutCounter = NAC_TIMEOUT; //prepare timeout counter for next state
  944               info->bStateVariable = ASYNC_READ_WAIT_START_TOKEN;
  945               return ASYNC_READ_BUSY;
  946           case ASYNC_READ_WAIT_START_TOKEN:
  947               //In this case, we have already issued the READ_MULTI_BLOCK command
  948               //to the media, and we need to keep polling the media until it sends
  949               //us the data start token byte.  This could typically take a 
  950               //couple/few milliseconds, up to a maximum of 100ms.
  951               if(longTimeoutCounter != 0x00000000)
  952               {
  953                   longTimeoutCounter--;
  954                   bData = MDD_SDSPI_ReadMedia();
  955                   
  956                   if(bData != MMC_FLOATING_BUS)
  957                   {
  958                       if(bData == DATA_START_TOKEN)
  959                       {   
  960                           //We got the start token.  Ready to receive the data
  961                           //block now.
  962                           info->bStateVariable = ASYNC_READ_NEW_PACKET_READY;
  963                           return ASYNC_READ_NEW_PACKET_READY;
  964                       }
  965                       else
  966                       {
  967                           //We got an unexpected non-0xFF, non-start token byte back?
  968                           //Some kind of error must have occurred. 
  969                           info->bStateVariable = ASYNC_READ_ABORT; 
  970                           return ASYNC_READ_BUSY;
  971                       }        
  972                   }
  973                   else
  974                   {
  975                       //Media is still busy.  Start token not received yet.
  976                       return ASYNC_READ_BUSY;
  977                   }                    
  978               } 
  979               else
  980               {
  981                   //The media didn't respond with the start data token in the timeout
  982                   //interval allowed.  Operation failed.  Abort the operation.
  983                   info->bStateVariable = ASYNC_READ_ABORT; 
  984                   return ASYNC_READ_BUSY;                
  985               }       
  986               //Should never execute to here
  987               
  988           case ASYNC_READ_NEW_PACKET_READY:
  989               //We have sent the READ_MULTI_BLOCK command and have successfully
  990               //received the data start token byte.  Therefore, we are ready
  991               //to receive raw data bytes from the media.
  992               if(ioInfo.dwBytesRemaining != 0x00000000)
  993               {
  994                   //Re-update local copy of pointer and number of bytes to read in this
  995                   //call.  These parameters are allowed to change between packets.
  996                   ioInfo.wNumBytes = info->wNumBytes;
  997              	    ioInfo.pBuffer = info->pBuffer;
  998              	    
  999              	    //Update counters for state tracking and loop exit condition tracking.
 1000                   ioInfo.dwBytesRemaining -= ioInfo.wNumBytes;
 1001                   blockCounter -= ioInfo.wNumBytes;
 1002   
 1003                   //Now read a ioInfo.wNumBytes packet worth of SPI bytes, 
 1004                   //and place the received bytes in the user specified pBuffer.
 1005                   //This operation directly dictates data thoroughput in the 
 1006                   //application, therefore optimized code should be used for each 
 1007                   //processor type.
 1008               	#if defined __C30__ || defined __C32__
 1009                   {
 1010                       //PIC24/dsPIC/PIC32 architecture is efficient with pointers.
 1011                       //Therefore, this code can provide good SPI bus utilization, 
 1012                       //provided the compiler optimization level is 's' or '3'.
 1013                       BYTE* localPointer = ioInfo.pBuffer;
 1014                       WORD localCounter = ioInfo.wNumBytes;
 1015                       
 1016                       if(localCounter != 0x0000)
 1017                       {
 1018                           localPointer--;
 1019                           while(1)
 1020                           {
 1021                               SPIBUF = 0xFF;
 1022                               localPointer++;
 1023                               if((--localCounter) == 0x0000)
 1024                               {
 1025                                  break; 
 1026                               } 
 1027                               while(!SPISTAT_RBF);
 1028                               *localPointer = (BYTE)SPIBUF;
 1029                           }
 1030                           while(!SPISTAT_RBF);
 1031                           *localPointer = (BYTE)SPIBUF;  
 1032                       }  
 1033                   }    
 1034                   #elif defined __18CXX
 1035                       PIC18_Optimized_SPI_Read_Packet();
 1036               	#endif   
 1037   
 1038                   //Check if we have received a multiple of the media block 
 1039                   //size (ex: 512 bytes).  If so, the next two bytes are going to 
 1040                   //be CRC values, rather than data bytes.  
 1041                   if(blockCounter == 0)
 1042                   {
 1043                       //Read two bytes to receive the CRC-16 value on the data block.
 1044                       MDD_SDSPI_ReadMedia();
 1045                       MDD_SDSPI_ReadMedia();
 1046                       //Following sending of the CRC-16 value, the media may still
 1047                       //need more access time to internally fetch the next block.
 1048                       //Therefore, it will send back 0xFF idle value, until it is
 1049                       //ready.  Then it will send a new data start token, followed
 1050                       //by the next block of useful data.
 1051                       if(ioInfo.dwBytesRemaining != 0x00000000)
 1052                       {
 1053                           info->bStateVariable = ASYNC_READ_WAIT_START_TOKEN;
 1054                       }
 1055                       blockCounter = MEDIA_BLOCK_SIZE;
 1056                       return ASYNC_READ_BUSY;
 1057                   }
 1058                       
 1059                   return ASYNC_READ_NEW_PACKET_READY;
 1060               }//if(ioInfo.dwBytesRemaining != 0x00000000)
 1061               else
 1062               {
 1063                   //We completed the read operation successfully and have returned
 1064                   //all data bytes requested.
 1065                   //Send CMD12 to let the media know we are finished reading
 1066                   //blocks from it, if we sent a multi-block read request earlier.
 1067                   if(SingleBlockRead == FALSE)
 1068                   {
 1069                       SendMMCCmd(STOP_TRANSMISSION, 0x00000000);
 1070                   }    
 1071                   SD_CS = 1;  //De-select media
 1072                   mSend8ClkCycles();  
 1073                   info->bStateVariable = ASYNC_READ_COMPLETE;
 1074                   return ASYNC_READ_COMPLETE;
 1075               }
 1076           case ASYNC_READ_ABORT:
 1077               //If the application firmware wants to cancel a read request.
 1078               info->bStateVariable = ASYNC_READ_ERROR;
 1079               //Send CMD12 to terminate the multi-block read request.
 1080               response = SendMMCCmd(STOP_TRANSMISSION, 0x00000000);
 1081               //Fall through to ASYNC_READ_ERROR/default case.
 1082           case ASYNC_READ_ERROR:
 1083           default:
 1084               //Some error must have happened.
 1085               SD_CS = 1;  //De-select media
 1086               mSend8ClkCycles();  
 1087               return ASYNC_READ_ERROR; 
 1088       }//switch(info->stateVariable)    
 1089       
 1090       //Should never get to here.  All pathways should have already returned.
 1091       return ASYNC_READ_ERROR;
 1092   }    
 1093   
 1094   
 1095   
 1096   
 1097   #ifdef __18CXX
 1098   /*****************************************************************************
 1099     Function:
 1100       static void PIC18_Optimized_SPI_Read_Packet(void)
 1101     Summary:
 1102       A private function intended for use internal to the SD-SPI.c file.
 1103       This function reads a specified number of bytes from the SPI module,
 1104       at high speed for optimum thoroughput, and copies them into the user
 1105       specified RAM buffer.
 1106       This function is only implemented and used on PIC18 devices.
 1107     Pre-Conditions:
 1108       The ioInfo.wNumBytes must be pre-initialized prior to calling 
 1109       PIC18_Optimized_SPI_Read_Packet().
 1110       Additionally, the ioInfo.pBuffer must also be pre-initialized, prior
 1111       to calling PIC18_Optimized_SPI_Read_Packet().
 1112     Input:
 1113       ioInfo.wNumBytes global variable, initialized to the number of bytes to read.
 1114       ioInfo.pBuffer global variable, initialize to point to the RAM location that
 1115           the read data should be copied to.
 1116     Return Values:
 1117       None (although the ioInfo.pBuffer RAM specified will contain new contents)
 1118     Side Effects:
 1119       None
 1120     Description:
 1121       A private function intended for use internal to the SD-SPI.c file.
 1122       This function reads a specified number of bytes from the SPI module,
 1123       at high speed for optimum thoroughput, and copies them into the user
 1124       specified RAM buffer.
 1125       This function is only implemented and used on PIC18 devices.
 1126     Remarks:
 1127       This function is speed optimized, using inline assembly language code, and
 1128       makes use of C compiler managed resources.  It is currently written to work
 1129       with the Microchip MPLAB C18 compiler, and may need modification is built
 1130       with a different PIC18 compiler.
 1131     *****************************************************************************/
 1132   static void PIC18_Optimized_SPI_Read_Packet(void)
 1133   {
 1134       static WORD FSR0Save;
 1135       static WORD PRODSave;
 1136   
 1137       //Make sure the SPI_INTERRUPT_FLAG_ASM has been correctly defined, for the SPI
 1138       //module that is actually being used in the hardware.
 1139       #ifndef SPI_INTERRUPT_FLAG_ASM
 1140           #error "Please define SPI_INTERRUPT_FLAG_ASM.  Double click this message for more info."
 1141           //In the HardwareProfile - [platform name].h file for your project, please
 1142           //add a "#define SPI_INTERRUPT_FLAG_ASM  PIRx, y" definition, where
 1143           //PIRx is the PIR register holding the SSPxIF flag for the SPI module being used
 1144           //to interface with the SD/MMC card, and y is the bit number for the SSPxIF bit (ex: 0-7).
 1145       #endif
 1146   
 1147       //Make sure at least one byte needs to be read.
 1148       if(ioInfo.wNumBytes == 0)
 1149       {
 1150           return;
 1151       }
 1152   
 1153       //Context save C compiler managed registers that we will modify in this function.
 1154       FSR0Save = FSR0;    
 1155       PRODSave = PROD;    
 1156       
 1157       //Using PRODH and PRODL as convenient 16-bit access bank counter
 1158       PROD = ioInfo.wNumBytes;    //ioInfo.wNumBytes holds the total number of bytes
 1159                                   //this function will read from SPI.
 1160       //Going to use the FSR0 directly.  This is non-conventional, but delivers
 1161       //better performance than using a normal C managed software RAM pointer.
 1162       FSR0 = (WORD)ioInfo.pBuffer;
 1163   
 1164       //Initiate the first SPI operation
 1165       WREG = SPIBUF;
 1166       SPI_INTERRUPT_FLAG = 0;
 1167       SPIBUF = 0xFF;
 1168   
 1169       //Highly speed efficient SPI read loop, written in inline assembly
 1170       //language for best performance.  Total number of bytes that will be fetched
 1171       //is exactly == the value of ioInfo.wNumBytes prior to calling this function.
 1172       _asm
 1173           bra     ASMSPIReadLoopEntryPoint
 1174       
 1175   ASMSPIReadLoop:
 1176           //Wait until last hardware SPI transaction is complete
 1177           btfss   SPI_INTERRUPT_FLAG_ASM, 0
 1178           bra     -2
 1179           bcf     SPI_INTERRUPT_FLAG_ASM, 0
 1180   
 1181           //Save received byte and start the next transfer
 1182           movf    SPIBUF, 0, 0    //Copy SPIBUF byte into WREG
 1183           setf    SPIBUF, 0       //Write 0xFF to SPIBUF, to start a SPI transaction
 1184           movwf   POSTINC0, 0     //Write the last received byte to the user's RAM buffer
 1185       
 1186   ASMSPIReadLoopEntryPoint:
 1187           //Now decrement 16-bit counter for loop exit test condition
 1188           movlw   0x00
 1189           decf    PRODL, 1, 0     //Decrement LSB
 1190           subwfb  PRODH, 1, 0     //Decrement MSB, only if borrow from LSB decrement
 1191           //Check if anymore bytes remain to be sent
 1192           movf    PRODL, 0, 0     //copy PRODL to WREG
 1193           iorwf   PRODH, 0, 0     //Z bit will be set if both PRODL and PRODH == 0x00
 1194           bnz     ASMSPIReadLoop  //Go back and loop if our counter isn't = 0x0000.
 1195   
 1196           //Wait until the very last SPI transaction is complete and save the byte
 1197           btfss   SPI_INTERRUPT_FLAG_ASM, 0
 1198           bra     -2
 1199           movff   SPIBUF, POSTINC0
 1200       _endasm
 1201   
 1202       SPI_INTERRUPT_FLAG = 0;	 
 1203   
 1204       //Context restore C compiler managed registers
 1205       PROD = PRODSave;
 1206       FSR0 = FSR0Save;    
 1207   }    
 1208   #endif
 1209   
 1210   
 1211   
 1212   
 1213   
 1214   /*****************************************************************************
 1215     Function:
 1216       BYTE MDD_SDSPI_AsyncWriteTasks(ASYNC_IO* info)
 1217     Summary:
 1218       Speed optimized, non-blocking, state machine based write function that writes
 1219       data from the user specified buffer, onto the media, at the specified 
 1220       media block address.
 1221     Pre-Conditions:
 1222       The ASYNC_IO structure must be initialized correctly, prior to calling
 1223       this function for the first time.  Certain parameters, such as the user
 1224       data buffer pointer (pBuffer) in the ASYNC_IO struct are allowed to be changed
 1225       by the application firmware, in between each call to MDD_SDSPI_AsyncWriteTasks().
 1226       Additionally, the media and microcontroller SPI module should have already 
 1227       been initalized before using this function.  This function is mutually
 1228       exclusive with the MDD_SDSPI_AsyncReadTasks() function.  Only one operation
 1229       (either one read or one write) is allowed to be in progress at a time, as
 1230       both functions share statically allocated resources and monopolize the SPI bus.
 1231     Input:
 1232       ASYNC_IO* info -        A pointer to a ASYNC_IO structure.  The 
 1233                               structure contains information about how to complete
 1234                               the write operation (ex: number of total bytes to write,
 1235                               where to obtain the bytes from, number of bytes
 1236                               to write for each call to MDD_SDSPI_AsyncWriteTasks(), etc.).
 1237     Return Values:
 1238       BYTE - Returns a status byte indicating the current state of the write 
 1239               operation. The possible return values are:
 1240               
 1241               ASYNC_WRITE_BUSY - Returned when the state machine is busy waiting for
 1242                                the media to become ready to accept new data.  The 
 1243                                media has write time, which can often be quite long
 1244                                (a few ms typ, with maximum of 250ms).  The application
 1245                                should keep calling MDD_SDSPI_AsyncWriteTasks() until either
 1246                                an error/timeout occurs, ASYNC_WRITE_SEND_PACKET
 1247                                is returned, or ASYNC_WRITE_COMPLETE is returned.
 1248               ASYNC_WRITE_SEND_PACKET -   Returned when the MDD_SDSPI_AsyncWriteTasks()
 1249                                           handler is ready to consume data and send
 1250                                           it to the media.  After ASYNC_WRITE_SEND_PACKET
 1251                                           is returned, the application should make certain
 1252                                           that the info->wNumBytes and pBuffer parameters
 1253                                           are correct, prior to calling 
 1254                                           MDD_SDSPI_AsyncWriteTasks() again.  After
 1255                                           the function returns, the application is
 1256                                           then free to write new data into the pBuffer
 1257                                           RAM location. 
 1258               ASYNC_WRITE_COMPLETE - Returned when all data bytes in the write
 1259                                    operation have been written to the media successfully,
 1260                                    and the media is now ready for the next operation.
 1261               ASYNC_WRITE_ERROR - Returned when some failure occurs.  This could be
 1262                                  either due to a media timeout, or due to some other
 1263                                  unknown type of error.  In this case, the 
 1264                                  MDD_SDSPI_AsyncWriteTasks() handler will terminate
 1265                                  the write attempt and will try to put the media 
 1266                                  back in a default state, ready for a new command.  
 1267                                  The application firmware may then retry the write
 1268                                  attempt (if desired) by re-initializing the 
 1269                                  ASYNC_IO structure and setting the 
 1270                                  bStateVariable = ASYNC_WRITE_QUEUED.
 1271   
 1272               
 1273     Side Effects:
 1274       Uses the SPI bus and the media.  The media and SPI bus should not be
 1275       used by any other function until the read operation has either completed
 1276       successfully, or returned with the ASYNC_WRITE_ERROR condition.
 1277     Description:
 1278       Speed optimized, non-blocking, state machine based write function that writes 
 1279       data packets to the media, from a user specified RAM buffer.
 1280       This function uses either the single block or multi-block write command 
 1281       to perform fast writes of the data.  The total amount of data that will be 
 1282       written on any given call to MDD_SDSPI_AsyncWriteTasks() will be the 
 1283       info->numBytes parameter.
 1284       However, if the function is called repeatedly, with info->dwBytesRemaining
 1285       set to a large number, this function can successfully write data sizes >> than
 1286       the block size (theoretically anything up to ~4GB, since dwBytesRemaining is 
 1287       a 32-bit DWORD).  The application firmware should continue calling 
 1288       MDD_SDSPI_AsyncWriteTasks(), until the ASYNC_WRITE_COMPLETE value is returned 
 1289       (or ASYNC_WRITE_ERROR), even if it has already sent all of the data expected.
 1290       This is necessary, so the state machine can finish the write process and 
 1291       terminate the multi-block write operation, once the total expected number 
 1292       of bytes have been written.  This puts the media back into the default state 
 1293       ready for a new command.
 1294       
 1295       During normal/successful operations, calls to MDD_SDSPI_AsyncWriteTasks() 
 1296       would typically return:
 1297       1. ASYNC_WRITE_SEND_PACKET - repeatedly, until 512 bytes [media read 
 1298           block size] is received, then 
 1299       2. ASYNC_WRITE_BUSY (for awhile, could be a long time, many milliseconds), then
 1300       3. Back to ASYNC_WRITE_SEND_PACKET (repeatedly, until the next 512 byte
 1301          boundary, then back to #2, etc.
 1302       4. After all data is copied successfully, then the function will return 
 1303          ASYNC_WRITE_COMPLETE, for all subsequent calls (until a new write operation
 1304          is started, by re-initializing the ASYNC_IO structure, and re-calling
 1305          the function).
 1306       
 1307     Remarks:
 1308       When starting a read operation, the info->stateVariable must be initalized to
 1309       ASYNC_WRITE_QUEUED.  All other fields in the info structure should also be
 1310       initialized correctly.
 1311   
 1312       This function will monopolize the SPI module during the operation.  Do not
 1313       use the SPI module for any other purpose, while a write operation is in
 1314       progress.  Additionally, the ASYNC_IO structure must not be modified
 1315       in a different context, while the MDD_SDSPI_AsyncReadTasks() function is 
 1316       actively executing.
 1317       In between calls to MDD_SDSPI_AsyncWriteTasks(), certain parameters, namely the
 1318       info->wNumBytes and info->pBuffer are allowed to change however.
 1319       
 1320       The dwBytesRemaining value must always be an exact integer multiple of wNumBytes 
 1321       for the function to operate correctly.  Additionally, it is required that
 1322       the wNumBytes parameter, must always be less than or equal to the media block size,
 1323       (which is 512 bytes).  Additionally, info->wNumBytes must always be an exact 
 1324       integer factor of the media block size.  Example values that are allowed for
 1325       info->wNumBytes are: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512.
 1326     *****************************************************************************/
 1327   BYTE MDD_SDSPI_AsyncWriteTasks(ASYNC_IO* info)
 1328   {
 1329       static BYTE data_byte;
 1330       static WORD blockCounter;
 1331       static DWORD WriteTimeout;
 1332       static BYTE command;
 1333       DWORD preEraseBlockCount;
 1334       MMC_RESPONSE response;
 1335   
 1336       
 1337       //Check what state we are in, to decide what to do.
 1338       switch(info->bStateVariable)
 1339       {
 1340           case ASYNC_WRITE_COMPLETE:
 1341               return ASYNC_WRITE_COMPLETE;
 1342           case ASYNC_WRITE_QUEUED:
 1343               //Initiate the write sequence.
 1344               blockCounter = MEDIA_BLOCK_SIZE;    //Initialize counter.  Will be used later for block boundary tracking.
 1345   
 1346               //Copy input structure into a statically allocated global instance 
 1347               //of the structure, for faster local access of the parameters with 
 1348               //smaller code size.
 1349               ioInfo = *info;
 1350   
 1351               //Check if we are writing only a single block worth of data, or 
 1352               //multiple blocks worth of data.
 1353               if(ioInfo.dwBytesRemaining <= MEDIA_BLOCK_SIZE)
 1354               {
 1355                   command = WRITE_SINGLE_BLOCK;
 1356               }    
 1357               else
 1358               {
 1359                   command = WRITE_MULTI_BLOCK;
 1360                   
 1361                   //Compute the number of blocks that we are going to be writing in this multi-block write operation.
 1362                   preEraseBlockCount = (ioInfo.dwBytesRemaining >> 9); //Divide by 512 to get the number of blocks to write
 1363                   //Always need to erase at least one block.
 1364                   if(preEraseBlockCount == 0)
 1365                   {
 1366                       preEraseBlockCount++;   
 1367                   } 
 1368       
 1369                   //Should send CMD55/ACMD23 to let the media know how many blocks it should 
 1370                   //pre-erase.  This isn't essential, but it allows for faster multi-block 
 1371                   //writes, and probably also reduces flash wear on the media.
 1372                   response = SendMMCCmd(APP_CMD, 0x00000000);    //Send CMD55
 1373                   if(response.r1._byte == 0x00)   //Check if successful.
 1374                   {
 1375                       SendMMCCmd(SET_WR_BLK_ERASE_COUNT , preEraseBlockCount);    //Send ACMD23        
 1376                   }
 1377               }    
 1378   
 1379               //The info->dwAddress parameter is the block address.
 1380               //For standard capacity SD cards, the card expects a complete byte address.
 1381               //To convert the block address into a byte address, we multiply by the block size (512).
 1382               //For SDHC (high capacity) cards, the card expects a block address already, so no
 1383               //address cconversion is needed
 1384               if (gSDMode == SD_MODE_NORMAL)  
 1385               {
 1386                   ioInfo.dwAddress <<= 9;   //<< 9 multiplies by 512
 1387               }    
 1388   
 1389               //Send the write single or write multi command, with the LBA or byte 
 1390               //address (depeding upon SDHC or standard capacity card)
 1391               response = SendMMCCmd(command, ioInfo.dwAddress);    
 1392   
 1393               //See if it was accepted
 1394               if(response.r1._byte != 0x00)
 1395               {
 1396                   //Perhaps the card isn't initialized or present.
 1397                   info->bStateVariable = ASYNC_WRITE_ERROR;
 1398                   return ASYNC_WRITE_ERROR; 
 1399               }    
 1400               else
 1401               {
 1402                   //Card is ready to receive start token and data bytes.
 1403                   info->bStateVariable = ASYNC_WRITE_TRANSMIT_PACKET;
 1404               } 
 1405               return ASYNC_WRITE_SEND_PACKET;   
 1406   
 1407           case ASYNC_WRITE_TRANSMIT_PACKET:
 1408               //Check if we just finished programming a block, or we are starting
 1409               //for the first time.  In this case, we need to send the data start token.
 1410               if(blockCounter == MEDIA_BLOCK_SIZE)
 1411               {
 1412                   //Send the correct data start token, based on the type of write we are doing
 1413                   if(command == WRITE_MULTI_BLOCK)
 1414                   {
 1415                       WriteSPIM(DATA_START_MULTI_BLOCK_TOKEN);   
 1416                   }
 1417                   else
 1418                   {
 1419                       //Else must be a single block write
 1420                       WriteSPIM(DATA_START_TOKEN);   
 1421                   }        
 1422               } 
 1423                  
 1424               //Update local copy of pointer and byte count.  Application firmware
 1425               //is alllowed to change these between calls to this handler function.
 1426               ioInfo.wNumBytes = info->wNumBytes;
 1427               ioInfo.pBuffer = info->pBuffer;
 1428               
 1429               //Keep track of variables for loop/state exit conditions.
 1430               ioInfo.dwBytesRemaining -= ioInfo.wNumBytes;
 1431               blockCounter -= ioInfo.wNumBytes;
 1432               
 1433               //Now send a packet of raw data bytes to the media, over SPI.
 1434               //This code directly impacts data thoroughput in a significant way.  
 1435               //Special care should be used to make sure this code is speed optimized.
 1436           	#if defined __C30__ || defined __C32__
 1437               {
 1438                   //PIC24/dsPIC/PIC32 architecture is efficient with pointers and 
 1439                   //local variables due to the large number of WREGs available.
 1440                   //Therefore, this code gives good SPI bus utilization, provided
 1441                   //the compiler optimization level is 's' or '3'.
 1442                   BYTE* localPointer = ioInfo.pBuffer;    
 1443                   WORD localCounter = ioInfo.wNumBytes;
 1444                   do
 1445                   {
 1446                       SPIBUF = *localPointer++;
 1447                       localCounter--;
 1448                       while(!SPISTAT_RBF);
 1449                       data_byte = SPIBUF; //Dummy read to clear SPISTAT_RBF
 1450                   }while(localCounter);         
 1451               }                	    
 1452               #elif defined __18CXX   
 1453                   PIC18_Optimized_SPI_Write_Packet();
 1454               #endif
 1455    
 1456               //Check if we have finshed sending a 512 byte block.  If so,
 1457               //need to receive 16-bit CRC, and retrieve the data_response token
 1458               if(blockCounter == 0)
 1459               {
 1460                   blockCounter = MEDIA_BLOCK_SIZE;    //Re-initialize counter
 1461                   
 1462                   //Add code to compute CRC, if using CRC. By default, the media 
 1463                   //doesn't use CRC unless it is enabled manually during the card 
 1464                   //initialization sequence.
 1465                   mSendCRC();  //Send 16-bit CRC for the data block just sent
 1466                   
 1467                   //Read response token byte from media, mask out top three don't 
 1468                   //care bits, and check if there was an error
 1469                   if((MDD_SDSPI_ReadMedia() & WRITE_RESPONSE_TOKEN_MASK) != DATA_ACCEPTED)
 1470                   {
 1471                       //Something went wrong.  Try and terminate as gracefully as 
 1472                       //possible, so as allow possible recovery.
 1473                       info->bStateVariable = ASYNC_WRITE_ABORT; 
 1474                       return ASYNC_WRITE_BUSY;
 1475                   }
 1476                   
 1477                   //The media will now send busy token (0x00) bytes until
 1478                   //it is internally ready again (after the block is successfully
 1479                   //writen and the card is ready to accept a new block.
 1480                   info->bStateVariable = ASYNC_WRITE_MEDIA_BUSY;
 1481                   WriteTimeout = WRITE_TIMEOUT;       //Initialize timeout counter
 1482                   return ASYNC_WRITE_BUSY;
 1483               }//if(blockCounter == 0)
 1484               
 1485               //If we get to here, we haven't reached a block boundary yet.  Keep 
 1486               //on requesting packets of data from the application.
 1487               return ASYNC_WRITE_SEND_PACKET;   
 1488   
 1489           case ASYNC_WRITE_MEDIA_BUSY:
 1490               if(WriteTimeout != 0)
 1491               {
 1492                   WriteTimeout--;
 1493                   mSend8ClkCycles();  //Dummy read to gobble up a byte (ex: to ensure we meet NBR timing parameter)
 1494                   data_byte = MDD_SDSPI_ReadMedia();  //Poll the media.  Will return 0x00 if still busy.  Will return non-0x00 is ready for next data block.
 1495                   if(data_byte != 0x00)
 1496                   {
 1497                       //The media is done and is no longer busy.  Go ahead and
 1498                       //either send the next packet of data to the media, or the stop
 1499                       //token if we are finshed.
 1500                       if(ioInfo.dwBytesRemaining == 0)
 1501                       {
 1502                           WriteTimeout = WRITE_TIMEOUT;
 1503                           if(command == WRITE_MULTI_BLOCK)
 1504                           {
 1505                               //We finished sending all bytes of data.  Send the stop token byte.
 1506                               WriteSPIM(DATA_STOP_TRAN_TOKEN);
 1507                               //After sending the stop transmission token, we need to
 1508                               //gobble up one byte before checking for media busy (0x00).
 1509                               //This is to meet the NBR timing parameter.  During the NBR
 1510                               //interval the SD card may not respond with the busy signal, even
 1511                               //though it is internally busy.
 1512                               mSend8ClkCycles();
 1513                                                   
 1514                               //The media still needs to finish internally writing.
 1515                               info->bStateVariable = ASYNC_STOP_TOKEN_SENT_WAIT_BUSY;
 1516                               return ASYNC_WRITE_BUSY;
 1517                           }
 1518                           else
 1519                           {
 1520                               //In this case we were doing a single block write,
 1521                               //so no stop token is necessary.  In this case we are
 1522                               //now fully complete with the write operation.
 1523                               SD_CS = 1;          //De-select media
 1524                               mSend8ClkCycles();  
 1525                               info->bStateVariable = ASYNC_WRITE_COMPLETE;
 1526                               return ASYNC_WRITE_COMPLETE;                            
 1527                           }                            
 1528                           
 1529                       }
 1530                       //Else we have more data to write in the multi-block write.    
 1531                       info->bStateVariable = ASYNC_WRITE_TRANSMIT_PACKET;  
 1532                       return ASYNC_WRITE_SEND_PACKET;                    
 1533                   }    
 1534                   else
 1535                   {
 1536                       //The media is still busy.
 1537                       return ASYNC_WRITE_BUSY;
 1538                   }    
 1539               }
 1540               else
 1541               {
 1542                   //Timeout occurred.  Something went wrong.  The media should not 
 1543                   //have taken this long to finish the write.
 1544                   info->bStateVariable = ASYNC_WRITE_ABORT;
 1545                   return ASYNC_WRITE_BUSY;
 1546               }        
 1547           
 1548           case ASYNC_STOP_TOKEN_SENT_WAIT_BUSY:
 1549               //We already sent the stop transmit token for the multi-block write 
 1550               //operation.  Now all we need to do, is keep waiting until the card
 1551               //signals it is no longer busy.  Card will keep sending 0x00 bytes
 1552               //until it is no longer busy.
 1553               if(WriteTimeout != 0)
 1554               {
 1555                   WriteTimeout--;
 1556                   data_byte = MDD_SDSPI_ReadMedia();
 1557                   //Check if card is no longer busy.  
 1558                   if(data_byte != 0x00)
 1559                   {
 1560                       //If we get to here, multi-block write operation is fully
 1561                       //complete now.  
 1562   
 1563                       //Should send CMD13 (SEND_STATUS) after a programming sequence, 
 1564                       //to confirm if it was successful or not inside the media.
 1565                                   
 1566                       //Prepare to receive the next command.
 1567                       SD_CS = 1;          //De-select media
 1568                       mSend8ClkCycles();  //NEC timing parameter clocking
 1569                       info->bStateVariable = ASYNC_WRITE_COMPLETE;
 1570                       return ASYNC_WRITE_COMPLETE;
 1571                   }
 1572                   //If we get to here, the media is still busy with the write.
 1573                   return ASYNC_WRITE_BUSY;    
 1574               }    
 1575               //Timeout occurred.  Something went wrong.  Fall through to ASYNC_WRITE_ABORT.
 1576           case ASYNC_WRITE_ABORT:
 1577               //An error occurred, and we need to stop the write sequence so as to try and allow
 1578               //for recovery/re-attempt later.
 1579               SendMMCCmd(STOP_TRANSMISSION, 0x00000000);
 1580               SD_CS = 1;  //deselect media
 1581               mSend8ClkCycles();  //After raising CS pin, media may not tri-state data out for 1 bit time.
 1582               info->bStateVariable = ASYNC_WRITE_ERROR; 
 1583               //Fall through to default case.
 1584           default:
 1585               //Used for ASYNC_WRITE_ERROR case.
 1586               return ASYNC_WRITE_ERROR; 
 1587       }//switch(info->stateVariable)    
 1588       
 1589   
 1590       //Should never execute to here.  All pathways should have a hit a return already.
 1591       info->bStateVariable = ASYNC_WRITE_ABORT;
 1592       return ASYNC_WRITE_BUSY;
 1593   } 
 1594   
 1595   
 1596   #ifdef __18CXX   
 1597   /*****************************************************************************
 1598     Function:
 1599       static void PIC18_Optimized_SPI_Write_Packet(void)
 1600     Summary:
 1601       A private function intended for use internal to the SD-SPI.c file.
 1602       This function writes a specified number of bytes to the SPI module,
 1603       at high speed for optimum throughput, copied from the user specified RAM
 1604       buffer.
 1605       This function is only implemented and used on PIC18 devices.
 1606     Pre-Conditions:
 1607       The ioInfo.wNumBytes must be pre-initialized prior to calling 
 1608       PIC18_Optimized_SPI_Write_Packet().
 1609       Additionally, the ioInfo.pBuffer must also be pre-initialized, prior
 1610       to calling PIC18_Optimized_SPI_Write_Packet().
 1611     Input:
 1612       ioInfo.wNumBytes global variable, initialized to the number of bytes to send
 1613       ioInfo.pBuffer global variable, initialized to point to the RAM location that
 1614           contains the data to send out the SPI port
 1615     Return Values:
 1616       None
 1617     Side Effects:
 1618       None
 1619     Description:
 1620       A private function intended for use internal to the SD-SPI.c file.
 1621       This function writes a specified number of bytes to the SPI module,
 1622       at high speed for optimum throughput, copied from the user specified RAM
 1623       buffer.
 1624       This function is only implemented and used on PIC18 devices.
 1625     Remarks:
 1626       This function is speed optimized, using inline assembly language code, and
 1627       makes use of C compiler managed resources.  It is currently written to work
 1628       with the Microchip MPLAB C18 compiler, and may need modification if built
 1629       with a different PIC18 compiler.
 1630     *****************************************************************************/
 1631   static void PIC18_Optimized_SPI_Write_Packet(void)
 1632   {
 1633       static BYTE bData;
 1634       static WORD FSR0Save;
 1635       static WORD PRODSave;
 1636   
 1637       //Make sure the SPI_INTERRUPT_FLAG_ASM has been correctly defined, for the SPI
 1638       //module that is actually being used in the hardware.
 1639       #ifndef SPI_INTERRUPT_FLAG_ASM
 1640           #error Please add "#define SPI_INTERRUPT_FLAG_ASM  PIRx, Y" to your hardware profile.  Replace x and Y with appropriate numbers for your SPI module interrupt flag.
 1641       #endif
 1642       
 1643       //Make sure at least one byte needs copying.
 1644       if(ioInfo.wNumBytes == 0)
 1645       {
 1646           return;
 1647       }    
 1648   
 1649       //Context save C compiler managed registers.
 1650       FSR0Save = FSR0; 
 1651       PRODSave = PROD;
 1652       
 1653       //Using PRODH and PRODL as 16 bit loop counter.  These are convenient since
 1654       //they are always in the access bank.
 1655       PROD = ioInfo.wNumBytes;
 1656       //Using FSR0 directly, for optimal SPI loop speed.
 1657       FSR0 = (WORD)ioInfo.pBuffer; 
 1658                                 
 1659       _asm
 1660           movf    POSTINC0, 0, 0  //Fetch next byte to send and store in WREG
 1661           bra     ASMSPIXmitLoopEntryPoint
 1662   ASMSPIXmitLoop:    
 1663           movf    POSTINC0, 0, 0  //Pre-Fetch next byte to send and temporarily store in WREG
 1664           //Wait until last hardware SPI transaction is complete
 1665           btfss   SPI_INTERRUPT_FLAG_ASM, 0
 1666           bra     -2
 1667           
 1668   ASMSPIXmitLoopEntryPoint:
 1669           //Start the next SPI transaction
 1670           bcf     SPI_INTERRUPT_FLAG_ASM, 0   //Clear interrupt flag
 1671           movwf   SPIBUF, 0       //Write next byte to transmit to SSPBUF
 1672           
 1673           //Now decrement byte counter for loop exit condition
 1674           movlw   0x00
 1675           decf    PRODL, 1, 0     //Decrement LSB
 1676           subwfb  PRODH, 1, 0     //Decrement MSB, only if borrow from LSB decrement
 1677           //Check if anymore bytes remain to be sent
 1678           movf    PRODL, 0, 0     //copy PRODL to WREG
 1679           iorwf   PRODH, 0, 0     //Z bit will be set if both PRODL and PRODH == 0x00
 1680           bnz     ASMSPIXmitLoop  //Go back and loop if our counter isn't = 0x0000.
 1681       _endasm
 1682   
 1683       //Wait until the last SPI transaction is really complete.  
 1684       //Above loop jumps out after the last byte is started, but not finished yet.
 1685       while(!SPI_INTERRUPT_FLAG);
 1686   
 1687       //Leave SPI module in a "clean" state, ready for next transaction.
 1688       bData = SPIBUF;         //Dummy read to clear BF flag.
 1689       SPI_INTERRUPT_FLAG = 0; //Clear interrupt flag.
 1690       //Restore C compiler managed registers that we modified
 1691       PROD = PRODSave;
 1692       FSR0 = FSR0Save;
 1693   }    
 1694   #endif    
 1695   
 1696   
 1697   
 1698   
 1699   
 1700   /*****************************************************************************
 1701     Function:
 1702       BYTE MDD_SDSPI_SectorWrite (DWORD sector_addr, BYTE * buffer, BYTE allowWriteToZero)
 1703     Summary:
 1704       Writes a sector of data to an SD card.
 1705     Conditions:
 1706       The MDD_SectorWrite function pointer must be pointing to this function.
 1707     Input:
 1708       sector_addr -      The address of the sector on the card.
 1709       buffer -           The buffer with the data to write.
 1710       allowWriteToZero -
 1711                        - TRUE -  Writes to the 0 sector (MBR) are allowed
 1712                        - FALSE - Any write to the 0 sector will fail.
 1713     Return Values:
 1714       TRUE -  The sector was written successfully.
 1715       FALSE - The sector could not be written.
 1716     Side Effects:
 1717       None.
 1718     Description:
 1719       The MDD_SDSPI_SectorWrite function writes one sector of data (512 bytes) 
 1720       of data from the location pointed to by 'buffer' to the specified sector of 
 1721       the SD card.
 1722     Remarks:
 1723       The card expects the address field in the command packet to be a byte address.
 1724       The sector_addr value is ocnverted to a byte address by shifting it left nine
 1725       times (multiplying by 512).
 1726     ***************************************************************************************/
 1727   BYTE MDD_SDSPI_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero)
 1728   {
 1729       static ASYNC_IO info;
 1730       BYTE status;
 1731       
 1732       if(allowWriteToZero == FALSE)
 1733       {
 1734           if(sector_addr == 0x00000000)
 1735           {
 1736               return FALSE;
 1737           }    
 1738       }    
 1739       
 1740       //Initialize structure so we write a single sector worth of data.
 1741       info.wNumBytes = 512;
 1742       info.dwBytesRemaining = 512;
 1743       info.pBuffer = buffer;
 1744       info.dwAddress = sector_addr;
 1745       info.bStateVariable = ASYNC_WRITE_QUEUED;
 1746       
 1747       //Repeatedly call the write handler until the operation is complete (or a
 1748       //failure/timeout occurred).
 1749       while(1)
 1750       {
 1751           status = MDD_SDSPI_AsyncWriteTasks(&info);
 1752           if(status == ASYNC_WRITE_COMPLETE)
 1753           {
 1754               return TRUE;
 1755           }    
 1756           else if(status == ASYNC_WRITE_ERROR)
 1757           {
 1758               return FALSE;
 1759           }
 1760       }    
 1761       return TRUE;
 1762   }    
 1763   
 1764   
 1765   
 1766   
 1767   /*******************************************************************************
 1768     Function:
 1769       BYTE MDD_SDSPI_WriteProtectState
 1770     Summary:
 1771       Indicates whether the card is write-protected.
 1772     Conditions:
 1773       The MDD_WriteProtectState function pointer must be pointing to this function.
 1774     Input:
 1775       None.
 1776     Return Values:
 1777       TRUE -  The card is write-protected
 1778       FALSE - The card is not write-protected
 1779     Side Effects:
 1780       None.
 1781     Description:
 1782       The MDD_SDSPI_WriteProtectState function will determine if the SD card is
 1783       write protected by checking the electrical signal that corresponds to the
 1784       physical write-protect switch.
 1785     Remarks:
 1786       None
 1787   *******************************************************************************/
 1788   
 1789   BYTE MDD_SDSPI_WriteProtectState(void)
 1790   {
 1791       return(SD_WE);
 1792   }
 1793   
 1794   
 1795   /*******************************************************************************
 1796     Function:
 1797       void Delayms (BYTE milliseconds)
 1798     Summary:
 1799       Delay.
 1800     Conditions:
 1801       None.
 1802     Input:
 1803       BYTE milliseconds - Number of ms to delay
 1804     Return:
 1805       None.
 1806     Side Effects:
 1807       None.
 1808     Description:
 1809       The Delayms function will delay a specified number of milliseconds.  Used for SPI
 1810       timing.
 1811     Remarks:
 1812       Depending on compiler revisions, this function may not delay for the exact 
 1813       time specified.  This shouldn't create a significant problem.
 1814   *******************************************************************************/
 1815   
 1816   void Delayms(BYTE milliseconds)
 1817   {
 1818       BYTE    ms;
 1819       DWORD   count;
 1820       
 1821       ms = milliseconds;
 1822       while (ms--)
 1823       {
 1824           count = MILLISECDELAY;
 1825           while (count--);
 1826       }
 1827       Nop();
 1828       return;
 1829   }
 1830   
 1831   
 1832   /*******************************************************************************
 1833     Function:
 1834       void CloseSPIM (void)
 1835     Summary:
 1836       Disables the SPI module.
 1837     Conditions:
 1838       None.
 1839     Input:
 1840       None.
 1841     Return:
 1842       None.
 1843     Side Effects:
 1844       None.
 1845     Description:
 1846       Disables the SPI module.
 1847     Remarks:
 1848       None.
 1849   *******************************************************************************/
 1850   
 1851   void CloseSPIM (void)
 1852   {
 1853   #if defined __C30__ || defined __C32__
 1854   
 1855       SPISTAT &= 0x7FFF;
 1856   
 1857   #elif defined __18CXX
 1858   
 1859       SPICON1 &= 0xDF;
 1860   
 1861   #endif
 1862   }
 1863   
 1864   
 1865   
 1866   /*****************************************************************************
 1867     Function:
 1868       unsigned char WriteSPIM (unsigned char data_out)
 1869     Summary:
 1870       Writes data to the SD card.
 1871     Conditions:
 1872       None.
 1873     Input:
 1874       data_out - The data to write.
 1875     Return:
 1876       0.
 1877     Side Effects:
 1878       None.
 1879     Description:
 1880       The WriteSPIM function will write a byte of data from the microcontroller to the
 1881       SD card.
 1882     Remarks:
 1883       None.
 1884     ***************************************************************************************/
 1885   
 1886   unsigned char WriteSPIM( unsigned char data_out )
 1887   {
 1888   #ifdef __PIC32MX__
 1889       BYTE   clear;
 1890       putcSPI((BYTE)data_out);
 1891       clear = getcSPI();
 1892       return ( 0 );                // return non-negative#
 1893   #elif defined __18CXX
 1894       BYTE clear;
 1895       clear = SPIBUF;
 1896       SPI_INTERRUPT_FLAG = 0;
 1897       SPIBUF = data_out;
 1898       if (SPICON1 & 0x80)
 1899           return -1;
 1900       else
 1901           while (!SPI_INTERRUPT_FLAG);
 1902       return 0;
 1903   #else
 1904       BYTE   clear;
 1905       SPIBUF = data_out;          // write byte to SSP1BUF register
 1906       while( !SPISTAT_RBF ); // wait until bus cycle complete
 1907       clear = SPIBUF;
 1908       return ( 0 );                // return non-negative#
 1909   #endif
 1910   }
 1911   
 1912   
 1913   
 1914   /*****************************************************************************
 1915     Function:
 1916       BYTE MDD_SDSPI_ReadMedia (void)
 1917     Summary:
 1918       Reads a byte of data from the SD card.
 1919     Conditions:
 1920       None.
 1921     Input:
 1922       None.
 1923     Return:
 1924       The byte read.
 1925     Side Effects:
 1926       None.
 1927     Description:
 1928       The MDD_SDSPI_ReadMedia function will read one byte from the SPI port.
 1929     Remarks:
 1930       This function replaces ReadSPI, since some implementations of that function
 1931       will initialize SSPBUF/SPIBUF to 0x00 when reading.  The card expects 0xFF.
 1932     ***************************************************************************************/
 1933   BYTE MDD_SDSPI_ReadMedia(void)
 1934   {
 1935   
 1936   #ifdef __C32__
 1937   
 1938       putcSPI((BYTE)0xFF);
 1939       return (BYTE)getcSPI();
 1940   
 1941   #elif defined __18CXX
 1942   
 1943       BYTE clear;
 1944       clear = SPIBUF;
 1945       SPI_INTERRUPT_FLAG = 0;
 1946       SPIBUF = 0xFF;
 1947       while (!SPI_INTERRUPT_FLAG);
 1948       return SPIBUF;
 1949   
 1950   #else
 1951       SPIBUF = 0xFF;                              //Data Out - Logic ones
 1952       while(!SPISTAT_RBF);                     //Wait until cycle complete
 1953       return(SPIBUF);                             //Return with byte read
 1954   #endif
 1955   }
 1956   
 1957   /*****************************************************************************
 1958     Function:
 1959       void OpenSPIM (unsigned int sync_mode)
 1960     Summary:
 1961       Initializes the SPI module
 1962     Conditions:
 1963       None.
 1964     Input:
 1965       sync_mode - Input parameter that sets the SPI mode/speed.
 1966     Return:
 1967       None.
 1968     Side Effects:
 1969       None.
 1970     Description:
 1971       The OpenSPIM function will enable and configure the SPI module.
 1972     Remarks:
 1973       None.
 1974     ***************************************************************************************/
 1975   
 1976   #ifdef __18CXX
 1977   void OpenSPIM (unsigned char sync_mode)
 1978   #else
 1979   void OpenSPIM( unsigned int sync_mode)
 1980   #endif
 1981   {
 1982       SPISTAT = 0x0000;               // power on state 
 1983   
 1984       //SPI module initilization depends on processor type
 1985       #ifdef __PIC32MX__
 1986           #if (GetSystemClock() <= 20000000)
 1987               SPIBRG = SPICalutateBRG(GetPeripheralClock(), 10000);
 1988           #else
 1989               SPIBRG = SPICalutateBRG(GetPeripheralClock(), SPI_FREQUENCY);
 1990           #endif
 1991           SPICON1bits.CKP = 1;
 1992           SPICON1bits.CKE = 0;
 1993       #elif defined __C30__ //must be PIC24 or dsPIC device
 1994           SPICON1 = 0x0000;              // power on state
 1995           SPICON1 |= sync_mode;          // select serial mode 
 1996           SPICON1bits.CKP = 1;
 1997           SPICON1bits.CKE = 0;
 1998       #else   //must be __18CXX (PIC18 processor)
 1999           SPICON1 = 0x00;         
 2000           SPICON1 |= sync_mode;   
 2001           SPISTATbits.CKE = 1;
 2002       #endif
 2003   
 2004       SPICLOCK = 0;
 2005       SPIOUT = 0;                  // define SDO1 as output (master or slave)
 2006       SPIIN = 1;                  // define SDI1 as input (master or slave)
 2007       SPIENABLE = 1;             // enable synchronous serial port
 2008   }
 2009   
 2010   
 2011   #ifdef __18CXX
 2012   // Description: Delay value for the manual SPI clock
 2013   #define MANUAL_SPI_CLOCK_VALUE             1
 2014   /*****************************************************************************
 2015     Function:
 2016       unsigned char WriteSPIManual (unsigned char data_out)
 2017     Summary:
 2018       Write a character to the SD card with bit-bang SPI.
 2019     Conditions:
 2020       Make sure the SDI pin is pre-configured as a digital pin, if it is 
 2021       multiplexed with analog functionality.
 2022     Input:
 2023       data_out - Data to send.
 2024     Return:
 2025       0.
 2026     Side Effects:
 2027       None.
 2028     Description:
 2029       Writes a character to the SD card.
 2030     Remarks:
 2031       The WriteSPIManual function is for use on a PIC18 when the clock speed is so
 2032       high that the maximum SPI clock divider cannot reduce the SPI clock speed below
 2033       the maximum SD card initialization speed.
 2034     ***************************************************************************************/
 2035   unsigned char WriteSPIManual(unsigned char data_out)
 2036   {
 2037       unsigned char i;
 2038       unsigned char clock;
 2039   
 2040       SPICLOCKLAT = 0;
 2041       SPIOUTLAT = 1;
 2042       SPICLOCK = OUTPUT;
 2043       SPIOUT = OUTPUT;
 2044   
 2045   	//Loop to send out 8 bits of SDO data and associated SCK clock.
 2046   	for(i = 0; i < 8; i++)
 2047   	{
 2048   		SPICLOCKLAT = 0;
 2049   		if(data_out & 0x80)
 2050   			SPIOUTLAT = 1;
 2051   		else
 2052   			SPIOUTLAT = 0;
 2053   		data_out = data_out << 1;				//Bit shift, so next bit to send is in MSb position
 2054       	clock = MANUAL_SPI_CLOCK_VALUE;
 2055       	while (clock--);
 2056       	SPICLOCKLAT = 1;
 2057       	clock = MANUAL_SPI_CLOCK_VALUE;
 2058       	while (clock--);    			
 2059   	}	
 2060       SPICLOCKLAT = 0;
 2061   
 2062       return 0; 
 2063   }
 2064   
 2065   
 2066   /*****************************************************************************
 2067     Function:
 2068       BYTE ReadMediaManual (void)
 2069     Summary:
 2070       Reads a byte of data from the SD card.
 2071     Conditions:
 2072       None.
 2073     Input:
 2074       None.
 2075     Return:
 2076       The byte read.
 2077     Side Effects:
 2078       None.
 2079     Description:
 2080       The MDD_SDSPI_ReadMedia function will read one byte from the SPI port.
 2081     Remarks:
 2082       This function replaces ReadSPI, since some implementations of that function
 2083       will initialize SSPBUF/SPIBUF to 0x00 when reading.  The card expects 0xFF.
 2084       This function is for use on a PIC18 when the clock speed is so high that the
 2085       maximum SPI clock prescaler cannot reduce the SPI clock below the maximum SD card
 2086       initialization speed.
 2087     ***************************************************************************************/
 2088   BYTE ReadMediaManual (void)
 2089   {
 2090       unsigned char i;
 2091       unsigned char clock;
 2092       unsigned char result = 0x00;
 2093   
 2094       SPIOUTLAT = 1;
 2095       SPIOUT = OUTPUT;
 2096       SPIIN = INPUT;
 2097       SPICLOCKLAT = 0;
 2098       SPICLOCK = OUTPUT;
 2099    
 2100    	//Loop to send 8 clock pulses and read in the returned bits of data. Data "sent" will be = 0xFF
 2101   	for(i = 0; i < 8u; i++)
 2102   	{
 2103   		SPICLOCKLAT = 0;
 2104       	clock = MANUAL_SPI_CLOCK_VALUE;
 2105       	while (clock--);
 2106       	SPICLOCKLAT = 1;
 2107       	clock = MANUAL_SPI_CLOCK_VALUE;
 2108       	while (clock--);
 2109   		result = result << 1;	//Bit shift the previous result.  We receive the byte MSb first. This operation makes LSb = 0.  
 2110       	if(SPIINPORT)
 2111       		result++;			//Set the LSb if we detected a '1' on the SPIINPORT pin, otherwise leave as 0.
 2112   	}	
 2113       SPICLOCKLAT = 0;
 2114   
 2115       return result;
 2116   }//end ReadMedia
 2117   #endif      // End __18CXX
 2118   
 2119   /*****************************************************************************
 2120     Function:
 2121       void InitSPISlowMode(void)
 2122     Summary:
 2123       Initializes the SPI module to operate at low SPI frequency <= 400kHz.
 2124     Conditions:
 2125       Processor type and GetSystemClock() macro have to be defined correctly
 2126       to get the correct SPI frequency.
 2127     Input:
 2128       Uses GetSystemClock() macro value.  Should be #define in the hardwareprofile.
 2129     Return Values:
 2130       None.  Initializes the hardware SPI module (except on PIC18).  On PIC18,
 2131       The SPI is bit banged to achieve low frequencies, but this function still
 2132       initializes the I/O pins. 
 2133     Side Effects:
 2134       None.
 2135     Description:
 2136       This function initalizes and enables the SPI module, configured for low 
 2137       SPI frequency, so as to be compatible with media cards which require <400kHz
 2138       SPI frequency during initialization.
 2139     Remarks:
 2140       None.
 2141     ***************************************************************************************/
 2142   void InitSPISlowMode(void)
 2143   {
 2144       #if defined __C30__ || defined __C32__
 2145       	WORD spiconvalue = 0x0003;
 2146       	#ifdef __PIC32MX__
 2147       		OpenSPI(SPI_START_CFG_1, SPI_START_CFG_2);
 2148       	    SPIBRG = SPICalutateBRG(GetPeripheralClock(), 400000);
 2149       	#else //else C30 = PIC24/dsPIC devices
 2150               WORD timeout;
 2151       	    // Calculate the prescaler needed for the clock
 2152       	    timeout = GetSystemClock() / 400000;
 2153       	    // if timeout is less than 400k and greater than 100k use a 1:1 prescaler
 2154       	    if (timeout == 0)
 2155       	    {
 2156       	        OpenSPIM (MASTER_ENABLE_ON | PRI_PRESCAL_1_1 | SEC_PRESCAL_1_1);
 2157       	    }
 2158       	    else
 2159       	    {
 2160       	        while (timeout != 0)
 2161       	        {
 2162       	            if (timeout > 8)
 2163       	            {
 2164       	                spiconvalue--;
 2165       	                // round up
 2166       	                if ((timeout % 4) != 0)
 2167       	                    timeout += 4;
 2168       	                timeout /= 4;
 2169       	            }
 2170       	            else
 2171       	            {
 2172       	                break;
 2173       	            }
 2174       	        }
 2175       	        
 2176       	        timeout--;
 2177       	    
 2178       	        OpenSPIM (MASTER_ENABLE_ON | spiconvalue | ((~(timeout << 2)) & 0x1C));
 2179       	    }
 2180       	#endif   //#ifdef __PIC32MX__ (and corresponding #else)    
 2181       #else //must be PIC18 device
 2182           //Make sure the SPI module doesn't control the bus, will use 
 2183           //bit-banged SPI instead, for slow mode initialization operation
 2184           SPICON1 = 0x00;
 2185           SPICLOCKLAT = 0;
 2186           SPIOUTLAT = 1;
 2187           SPICLOCK = OUTPUT;
 2188           SPIOUT = OUTPUT;
 2189       #endif //#if defined __C30__ || defined __C32__
 2190   }    
 2191   
 2192   
 2193   
 2194   /*****************************************************************************
 2195     Function:
 2196       MEDIA_INFORMATION *  MDD_SDSPI_MediaInitialize (void)
 2197     Summary:
 2198       Initializes the SD card.
 2199     Conditions:
 2200       The MDD_MediaInitialize function pointer must be pointing to this function.
 2201     Input:
 2202       None.
 2203     Return Values:
 2204       The function returns a pointer to the MEDIA_INFORMATION structure.  The
 2205       errorCode member may contain the following values:
 2206           * MEDIA_NO_ERROR - The media initialized successfully
 2207           * MEDIA_CANNOT_INITIALIZE - Cannot initialize the media.  
 2208     Side Effects:
 2209       None.
 2210     Description:
 2211       This function will send initialization commands to and SD card.
 2212     Remarks:
 2213       Psuedo code flow for the media initialization process is as follows:
 2214   
 2215   -------------------------------------------------------------------------------------------
 2216   SD Card SPI Initialization Sequence (for physical layer v1.x or v2.0 device) is as follows:
 2217   -------------------------------------------------------------------------------------------
 2218   0.  Power up tasks
 2219       a.  Initialize microcontroller SPI module to no more than 400kbps rate so as to support MMC devices.
 2220       b.  Add delay for SD card power up, prior to sending it any commands.  It wants the 
 2221           longer of: 1ms, the Vdd ramp time (time from 2.7V to Vdd stable), and 74+ clock pulses.
 2222   1.  Send CMD0 (GO_IDLE_STATE) with CS = 0.  This puts the media in SPI mode and software resets the SD/MMC card.
 2223   2.  Send CMD8 (SEND_IF_COND).  This requests what voltage the card wants to run at. 
 2224       Note: Some cards will not support this command.
 2225       a.  If illegal command response is received, this implies either a v1.x physical spec device, or not an SD card (ex: MMC).
 2226       b.  If normal response is received, then it must be a v2.0 or later SD memory card.
 2227   
 2228   If v1.x device:
 2229   -----------------
 2230   3.  Send CMD1 repeatedly, until initialization complete (indicated by R1 response byte/idle bit == 0)
 2231   4.  Basic initialization is complete.  May now switch to higher SPI frequencies.
 2232   5.  Send CMD9 to read the CSD structure.  This will tell us the total flash size and other info which will be useful later.
 2233   6.  Parse CSD structure bits (based on v1.x structure format) and extract useful information about the media.
 2234   7.  The card is now ready to perform application data transfers.
 2235   
 2236   If v2.0+ device:
 2237   -----------------
 2238   3.  Verify the voltage range is feasible.  If not, unusable card, should notify user that the card is incompatible with this host.
 2239   4.  Send CMD58 (Read OCR).
 2240   5.  Send CMD55, then ACMD41 (SD_SEND_OP_COND, with HCS = 1).
 2241       a.  Loop CMD55/ACMD41 until R1 response byte == 0x00 (indicating the card is no longer busy/no longer in idle state).  
 2242   6.  Send CMD58 (Get CCS).
 2243       a.  If CCS = 1 --> SDHC card.
 2244       b.  If CCS = 0 --> Standard capacity SD card (which is v2.0+).
 2245   7.  Basic initialization is complete.  May now switch to higher SPI frequencies.
 2246   8.  Send CMD9 to read the CSD structure.  This will tell us the total flash size and other info which will be useful later.
 2247   9.  Parse CSD structure bits (based on v2.0 structure format) and extract useful information about the media.
 2248   10. The card is now ready to perform application data transfers.
 2249   --------------------------------------------------------------------------------
 2250   ********************************************************************************/
 2251   
 2252   MEDIA_INFORMATION *  MDD_SDSPI_MediaInitialize(void)
 2253   {
 2254       WORD timeout;
 2255       MMC_RESPONSE response;
 2256   	BYTE CSDResponse[20];
 2257   	BYTE count, index;
 2258   	DWORD c_size;
 2259   	BYTE c_size_mult;
 2260   	BYTE block_len;
 2261   	
 2262   	#ifdef __DEBUG_UART
 2263   	InitUART();
 2264   	#endif
 2265    
 2266       //Initialize global variables.  Will get updated later with valid data once
 2267       //the data is known.
 2268       mediaInformation.errorCode = MEDIA_NO_ERROR;
 2269       mediaInformation.validityFlags.value = 0;
 2270       MDD_SDSPI_finalLBA = 0x00000000;	//Will compute a valid size later, from the CSD register values we get from the card
 2271       gSDMode = SD_MODE_NORMAL;           //Will get updated later with real value, once we know based on initialization flow.
 2272   
 2273       SD_CS = 1;               //Initialize Chip Select line (1 = card not selected)
 2274   
 2275       //MMC media powers up in the open-drain mode and cannot handle a clock faster
 2276       //than 400kHz. Initialize SPI port to <= 400kHz
 2277       InitSPISlowMode();    
 2278       
 2279       #ifdef __DEBUG_UART  
 2280       PrintROMASCIIStringUART("\r\n\r\nInitializing Media\r\n"); 
 2281       #endif
 2282   
 2283       //Media wants the longer of: Vdd ramp time, 1 ms fixed delay, or 74+ clock pulses.
 2284       //According to spec, CS should be high during the 74+ clock pulses.
 2285       //In practice it is preferrable to wait much longer than 1ms, in case of
 2286       //contact bounce, or incomplete mechanical insertion (by the time we start
 2287       //accessing the media). 
 2288       Delayms(30);
 2289       SD_CS = 1;
 2290       //Generate 80 clock pulses.
 2291       for(timeout=0; timeout<10u; timeout++)
 2292           WriteSPISlow(0xFF);
 2293   
 2294   
 2295       // Send CMD0 (with CS = 0) to reset the media and put SD cards into SPI mode.
 2296       timeout = 100;
 2297       do
 2298       {
 2299           //Toggle chip select, to make media abandon whatever it may have been doing
 2300           //before.  This ensures the CMD0 is sent freshly after CS is asserted low,
 2301           //minimizing risk of SPI clock pulse master/slave syncronization problems, 
 2302           //due to possible application noise on the SCK line.
 2303           SD_CS = 1;
 2304           WriteSPISlow(0xFF);   //Send some "extraneous" clock pulses.  If a previous
 2305                                 //command was terminated before it completed normally,
 2306                                 //the card might not have received the required clocking
 2307                                 //following the transfer.
 2308           SD_CS = 0;
 2309           timeout--;
 2310   
 2311           //Send CMD0 to software reset the device
 2312           response = SendMediaSlowCmd(GO_IDLE_STATE, 0x0);
 2313       }while((response.r1._byte != 0x01) && (timeout != 0));
 2314       //Check if all attempts failed and we timed out.  Normally, this won't happen,
 2315       //unless maybe the SD card was busy, because it was previously performing a
 2316       //read or write operation, when it was interrupted by the microcontroller getting
 2317       //reset or power cycled, without also resetting or power cycling the SD card.
 2318       //In this case, the SD card may still be busy (ex: trying to respond with the 
 2319       //read request data), and may not be ready to process CMD0.  In this case,
 2320       //we can try to recover by issuing CMD12 (STOP_TRANSMISSION).
 2321       if(timeout == 0)
 2322       {
 2323           #ifdef __DEBUG_UART  
 2324           PrintROMASCIIStringUART("Media failed CMD0 too many times. R1 response byte = ");
 2325           PrintRAMBytesUART(((unsigned char*)&response + 1), 1);
 2326           UARTSendLineFeedCarriageReturn();
 2327           PrintROMASCIIStringUART("Trying CMD12 to recover.\r\n");
 2328           #endif
 2329   
 2330           SD_CS = 1;
 2331           WriteSPISlow(0xFF);       //Send some "extraneous" clock pulses.  If a previous
 2332                                     //command was terminated before it completed normally,
 2333                                     //the card might not have received the required clocking
 2334                                     //following the transfer.
 2335           SD_CS = 0;
 2336   
 2337           //Send CMD12, to stop any read/write transaction that may have been in progress
 2338           response = SendMediaSlowCmd(STOP_TRANSMISSION, 0x0);    //Blocks until SD card signals non-busy
 2339           //Now retry to send send CMD0 to perform software reset on the media
 2340           response = SendMediaSlowCmd(GO_IDLE_STATE, 0x0);        
 2341           if(response.r1._byte != 0x01) //Check if card in idle state now.
 2342           {
 2343               //Card failed to process CMD0 yet again.  At this point, the proper thing
 2344               //to do would be to power cycle the card and retry, if the host 
 2345               //circuitry supports disconnecting the SD card power.  Since the
 2346               //SD/MMC PICtail+ doesn't support software controlled power removal
 2347               //of the SD card, there is nothing that can be done with this hardware.
 2348               //Therefore, we just give up now.  The user needs to physically 
 2349               //power cycle the media and/or the whole board.
 2350               #ifdef __DEBUG_UART  
 2351               PrintROMASCIIStringUART("Media still failed CMD0. Cannot initialize card, returning.\r\n");
 2352               #endif   
 2353               mediaInformation.errorCode = MEDIA_CANNOT_INITIALIZE;
 2354               return &mediaInformation;
 2355           }            
 2356           else
 2357           {
 2358               //Card successfully processed CMD0 and is now in the idle state.
 2359               #ifdef __DEBUG_UART  
 2360               PrintROMASCIIStringUART("Media successfully processed CMD0 after CMD12.\r\n");
 2361               #endif        
 2362           }    
 2363       }//if(timeout == 0) [for the CMD0 transmit loop]
 2364       else
 2365       {
 2366           #ifdef __DEBUG_UART  
 2367           PrintROMASCIIStringUART("Media successfully processed CMD0.\r\n");
 2368           #endif        
 2369       }       
 2370       
 2371   
 2372       //Send CMD8 (SEND_IF_COND) to specify/request the SD card interface condition (ex: indicate what voltage the host runs at).
 2373       //0x000001AA --> VHS = 0001b = 2.7V to 3.6V.  The 0xAA LSB is the check pattern, and is arbitrary, but 0xAA is recommended (good blend of 0's and '1's).
 2374       //The SD card has to echo back the check pattern correctly however, in the R7 response.
 2375       //If the SD card doesn't support the operating voltage range of the host, then it may not respond.
 2376       //If it does support the range, it will respond with a type R7 reponse packet (6 bytes/48 bits).	        
 2377       //Additionally, if the SD card is MMC or SD card v1.x spec device, then it may respond with
 2378       //invalid command.  If it is a v2.0 spec SD card, then it is mandatory that the card respond
 2379       //to CMD8.
 2380       response = SendMediaSlowCmd(SEND_IF_COND, 0x1AA);   //Note: If changing "0x1AA", CRC value in table must also change.
 2381       if(((response.r7.bytewise.argument._returnVal & 0xFFF) == 0x1AA) && (!response.r7.bitwise.bits.ILLEGAL_CMD))
 2382      	{
 2383           //If we get to here, the device supported the CMD8 command and didn't complain about our host
 2384           //voltage range.
 2385           //Most likely this means it is either a v2.0 spec standard or high capacity SD card (SDHC)
 2386           #ifdef __DEBUG_UART  
 2387           PrintROMASCIIStringUART("Media successfully processed CMD8. Response = ");
 2388           PrintRAMBytesUART(((unsigned char*)&response + 1), 4);
 2389           UARTSendLineFeedCarriageReturn();
 2390           #endif
 2391   
 2392   		//Send CMD58 (Read OCR [operating conditions register]).  Reponse type is R3, which has 5 bytes.
 2393   		//Byte 4 = normal R1 response byte, Bytes 3-0 are = OCR register value.
 2394           #ifdef __DEBUG_UART  
 2395           PrintROMASCIIStringUART("Sending CMD58.\r\n");
 2396           #endif
 2397           response = SendMediaSlowCmd(READ_OCR, 0x0);
 2398           //Now that we have the OCR register value in the reponse packet, we could parse
 2399           //the register contents and learn what voltage the SD card wants to run at.
 2400           //If our host circuitry has variable power supply capability, it could 
 2401           //theoretically adjust the SD card Vdd to the minimum of the OCR to save power.
 2402   		
 2403   		//Now send CMD55/ACMD41 in a loop, until the card is finished with its internal initialization.
 2404   		//Note: SD card specs recommend >= 1 second timeout while waiting for ACMD41 to signal non-busy.
 2405   		for(timeout = 0; timeout < 0xFFFF; timeout++)
 2406   		{				
 2407   			//Send CMD55 (lets SD card know that the next command is application specific (going to be ACMD41)).
 2408   			SendMediaSlowCmd(APP_CMD, 0x00000000);
 2409   			
 2410   			//Send ACMD41.  This is to check if the SD card is finished booting up/ready for full frequency and all
 2411   			//further commands.  Response is R3 type (6 bytes/48 bits, middle four bytes contain potentially useful data).
 2412               //Note: When sending ACMD41, the HCS bit is bit 30, and must be = 1 to tell SD card the host supports SDHC
 2413   			response = SendMediaSlowCmd(SD_SEND_OP_COND,0x40000000); //bit 30 set
 2414   			
 2415   			//The R1 response should be = 0x00, meaning the card is now in the "standby" state, instead of
 2416   			//the "idle" state (which is the default initialization state after CMD0 reset is issued).  Once
 2417   			//in the "standby" state, the SD card is finished with basic intitialization and is ready 
 2418   			//for read/write and other commands.
 2419   			if(response.r1._byte == 0)
 2420   			{
 2421       		    #ifdef __DEBUG_UART  
 2422                   PrintROMASCIIStringUART("Media successfully processed CMD55/ACMD41 and is no longer busy.\r\n");
 2423   				#endif
 2424   				break;  //Break out of for() loop.  Card is finished initializing.
 2425               }				
 2426   		}		
 2427   		if(timeout >= 0xFFFF)
 2428   		{
 2429               #ifdef __DEBUG_UART  
 2430               PrintROMASCIIStringUART("Media Timeout on CMD55/ACMD41.\r\n");
 2431               #endif
 2432       		mediaInformation.errorCode = MEDIA_CANNOT_INITIALIZE;
 2433           }				
 2434   		
 2435   		
 2436           //Now send CMD58 (Read OCR register).  The OCR register contains important
 2437           //info we will want to know about the card (ex: standard capacity vs. SDHC).
 2438           response = SendMediaSlowCmd(READ_OCR, 0x0); 
 2439   
 2440   		//Now check the CCS bit (OCR bit 30) in the OCR register, which is in our response packet.
 2441   		//This will tell us if it is a SD high capacity (SDHC) or standard capacity device.
 2442   		if(response.r7.bytewise.argument._returnVal & 0x40000000)    //Note the HCS bit is only valid when the busy bit is also set (indicating device ready).
 2443   		{
 2444   			gSDMode = SD_MODE_HC;
 2445   			
 2446   		    #ifdef __DEBUG_UART  
 2447               PrintROMASCIIStringUART("Media successfully processed CMD58: SD card is SDHC v2.0 (or later) physical spec type.\r\n");
 2448               #endif
 2449           }				
 2450           else
 2451           {
 2452               gSDMode = SD_MODE_NORMAL;
 2453   
 2454               #ifdef __DEBUG_UART  
 2455               PrintROMASCIIStringUART("Media successfully processed CMD58: SD card is standard capacity v2.0 (or later) spec.\r\n");
 2456               #endif
 2457           } 
 2458           //SD Card should now be finished with initialization sequence.  Device should be ready
 2459           //for read/write commands.
 2460   
 2461   	}//if(((response.r7.bytewise._returnVal & 0xFFF) == 0x1AA) && (!response.r7.bitwise.bits.ILLEGAL_CMD))
 2462       else
 2463   	{
 2464           //The CMD8 wasn't supported.  This means the card is not a v2.0 card.
 2465           //Presumably the card is v1.x device, standard capacity (not SDHC).
 2466   
 2467           #ifdef __DEBUG_UART  
 2468           PrintROMASCIIStringUART("CMD8 Unsupported: Media is most likely MMC or SD 1.x device.\r\n");
 2469           #endif
 2470   
 2471   
 2472           SD_CS = 1;                              // deselect the devices
 2473           Delayms(1);
 2474           SD_CS = 0;                              // select the device
 2475   
 2476           //The CMD8 wasn't supported.  This means the card is definitely not a v2.0 SDHC card.
 2477           gSDMode = SD_MODE_NORMAL;
 2478       	// According to the spec CMD1 must be repeated until the card is fully initialized
 2479       	timeout = 0x1FFF;
 2480           do
 2481           {
 2482               //Send CMD1 to initialize the media.
 2483               response = SendMediaSlowCmd(SEND_OP_COND, 0x00000000);    //When argument is 0x00000000, this queries MMC cards for operating voltage range
 2484               timeout--;
 2485           }while((response.r1._byte != 0x00) && (timeout != 0));
 2486           // see if it failed
 2487           if(timeout == 0)
 2488           {
 2489               #ifdef __DEBUG_UART  
 2490               PrintROMASCIIStringUART("CMD1 failed.\r\n");
 2491               #endif
 2492   
 2493               mediaInformation.errorCode = MEDIA_CANNOT_INITIALIZE;
 2494               SD_CS = 1;                              // deselect the devices
 2495           }
 2496           else
 2497           {
 2498               #ifdef __DEBUG_UART  
 2499               PrintROMASCIIStringUART("CMD1 Successfully processed, media is no longer busy.\r\n");
 2500               #endif
 2501               
 2502               //Set read/write block length to 512 bytes.  Note: commented out since
 2503               //this theoretically isn't necessary, since all cards v1 and v2 are 
 2504               //required to support 512 byte block size, and this is supposed to be
 2505               //the default size selected on cards that support other sizes as well.
 2506               //response = SendMediaSlowCmd(SET_BLOCKLEN, 0x00000200);    //Set read/write block length to 512 bytes
 2507           }
 2508          
 2509   	}
 2510   
 2511   
 2512       //Temporarily deselect device
 2513       SD_CS = 1;
 2514       
 2515       //Basic initialization of media is now complete.  The card will now use push/pull
 2516       //outputs with fast drivers.  Therefore, we can now increase SPI speed to 
 2517       //either the maximum of the microcontroller or maximum of media, whichever 
 2518       //is slower.  MMC media is typically good for at least 20Mbps SPI speeds.  
 2519       //SD cards would typically operate at up to 25Mbps or higher SPI speeds.
 2520       OpenSPIM(SYNC_MODE_FAST);
 2521   
 2522   	SD_CS = 0;
 2523   
 2524   	/* Send the CMD9 to read the CSD register */
 2525       timeout = NCR_TIMEOUT;
 2526       do
 2527       {
 2528           //Send CMD9: Read CSD data structure.
 2529   		response = SendMMCCmd(SEND_CSD, 0x00);
 2530           timeout--;
 2531       }while((response.r1._byte != 0x00) && (timeout != 0));
 2532       if(timeout != 0x00)
 2533       {
 2534           #ifdef __DEBUG_UART  
 2535           PrintROMASCIIStringUART("CMD9 Successfully processed: Read CSD register.\r\n");
 2536           PrintROMASCIIStringUART("CMD9 response R1 byte = ");
 2537           PrintRAMBytesUART((unsigned char*)&response, 1); 
 2538           UARTSendLineFeedCarriageReturn();
 2539           #endif
 2540       }    
 2541       else
 2542       {
 2543           //Media failed to respond to the read CSD register operation.
 2544           #ifdef __DEBUG_UART  
 2545           PrintROMASCIIStringUART("Timeout occurred while processing CMD9 to read CSD register.\r\n");
 2546           #endif
 2547           
 2548           mediaInformation.errorCode = MEDIA_CANNOT_INITIALIZE;
 2549           SD_CS = 1;
 2550           return &mediaInformation;
 2551       }    
 2552   
 2553   	/* According to the simplified spec, section 7.2.6, the card will respond
 2554   	with a standard response token, followed by a data block of 16 bytes
 2555   	suffixed with a 16-bit CRC.*/
 2556   	index = 0;
 2557   	for (count = 0; count < 20u; count ++)
 2558   	{
 2559   		CSDResponse[index] = MDD_SDSPI_ReadMedia();
 2560   		index++;			
 2561   		/* Hopefully the first byte is the datatoken, however, some cards do
 2562   		not send the response token before the CSD register.*/
 2563   		if((count == 0) && (CSDResponse[0] == DATA_START_TOKEN))
 2564   		{
 2565   			/* As the first byte was the datatoken, we can drop it. */
 2566   			index = 0;
 2567   		}
 2568   	}
 2569   
 2570       #ifdef __DEBUG_UART  
 2571       PrintROMASCIIStringUART("CSD data structure contains: ");
 2572       PrintRAMBytesUART((unsigned char*)&CSDResponse, 20); 
 2573       UARTSendLineFeedCarriageReturn();
 2574       #endif
 2575       
 2576   
 2577   
 2578   	//Extract some fields from the response for computing the card capacity.
 2579   	//Note: The structure format depends on if it is a CSD V1 or V2 device.
 2580   	//Therefore, need to first determine version of the specs that the card 
 2581   	//is designed for, before interpreting the individual fields.
 2582   
 2583   	//-------------------------------------------------------------
 2584   	//READ_BL_LEN: CSD Structure v1 cards always support 512 byte
 2585   	//read and write block lengths.  Some v1 cards may optionally report
 2586   	//READ_BL_LEN = 1024 or 2048 bytes (and therefore WRITE_BL_LEN also 
 2587   	//1024 or 2048).  However, even on these cards, 512 byte partial reads
 2588   	//and 512 byte write are required to be supported.
 2589   	//On CSD structure v2 cards, it is always required that READ_BL_LEN 
 2590   	//(and therefore WRITE_BL_LEN) be 512 bytes, and partial reads and
 2591   	//writes are not allowed.
 2592   	//Therefore, all cards support 512 byte reads/writes, but only a subset
 2593   	//of cards support other sizes.  For best compatibility with all cards,
 2594   	//and the simplest firmware design, it is therefore preferrable to 
 2595   	//simply ignore the READ_BL_LEN and WRITE_BL_LEN values altogether,
 2596   	//and simply hardcode the read/write block size as 512 bytes.
 2597   	//-------------------------------------------------------------
 2598   	gMediaSectorSize = 512u;
 2599   	//mediaInformation.sectorSize = gMediaSectorSize;
 2600   	mediaInformation.sectorSize = 512u;
 2601   	mediaInformation.validityFlags.bits.sectorSize = TRUE;
 2602   	//-------------------------------------------------------------
 2603   
 2604   	//Calculate the MDD_SDSPI_finalLBA (see SD card physical layer simplified spec 2.0, section 5.3.2).
 2605   	//In USB mass storage applications, we will need this information to 
 2606   	//correctly respond to SCSI get capacity requests.  Note: method of computing 
 2607   	//MDD_SDSPI_finalLBA depends on CSD structure spec version (either v1 or v2).
 2608   	if(CSDResponse[0] & 0xC0)	//Check CSD_STRUCTURE field for v2+ struct device
 2609   	{
 2610   		//Must be a v2 device (or a reserved higher version, that doesn't currently exist)
 2611   
 2612   		//Extract the C_SIZE field from the response.  It is a 22-bit number in bit position 69:48.  This is different from v1.  
 2613   		//It spans bytes 7, 8, and 9 of the response.
 2614   		c_size = (((DWORD)CSDResponse[7] & 0x3F) << 16) | ((WORD)CSDResponse[8] << 8) | CSDResponse[9];
 2615   		
 2616   		MDD_SDSPI_finalLBA = ((DWORD)(c_size + 1) * (WORD)(1024u)) - 1; //-1 on end is correction factor, since LBA = 0 is valid.
 2617   	}
 2618   	else //if(CSDResponse[0] & 0xC0)	//Check CSD_STRUCTURE field for v1 struct device
 2619   	{
 2620   		//Must be a v1 device.
 2621   		//Extract the C_SIZE field from the response.  It is a 12-bit number in bit position 73:62.  
 2622   		//Although it is only a 12-bit number, it spans bytes 6, 7, and 8, since it isn't byte aligned.
 2623   		c_size = ((DWORD)CSDResponse[6] << 16) | ((WORD)CSDResponse[7] << 8) | CSDResponse[8];	//Get the bytes in the correct positions
 2624   		c_size &= 0x0003FFC0;	//Clear all bits that aren't part of the C_SIZE
 2625   		c_size = c_size >> 6;	//Shift value down, so the 12-bit C_SIZE is properly right justified in the DWORD.
 2626   		
 2627   		//Extract the C_SIZE_MULT field from the response.  It is a 3-bit number in bit position 49:47.
 2628   		c_size_mult = ((WORD)((CSDResponse[9] & 0x03) << 1)) | ((WORD)((CSDResponse[10] & 0x80) >> 7));
 2629   
 2630           //Extract the BLOCK_LEN field from the response. It is a 4-bit number in bit position 83:80.
 2631           block_len = CSDResponse[5] & 0x0F;
 2632   
 2633           block_len = 1 << (block_len - 9); //-9 because we report the size in sectors of 512 bytes each
 2634   		
 2635   		//Calculate the MDD_SDSPI_finalLBA (see SD card physical layer simplified spec 2.0, section 5.3.2).
 2636   		//In USB mass storage applications, we will need this information to 
 2637   		//correctly respond to SCSI get capacity requests (which will cause MDD_SDSPI_ReadCapacity() to get called).
 2638   		MDD_SDSPI_finalLBA = ((DWORD)(c_size + 1) * (WORD)((WORD)1 << (c_size_mult + 2)) * block_len) - 1;	//-1 on end is correction factor, since LBA = 0 is valid.		
 2639   	}	
 2640   
 2641       //Turn off CRC7 if we can, might be an invalid cmd on some cards (CMD59)
 2642       //Note: POR default for the media is normally with CRC checking off in SPI 
 2643       //mode anyway, so this is typically redundant.
 2644       SendMMCCmd(CRC_ON_OFF,0x0);
 2645   
 2646       //Now set the block length to media sector size. It should be already set to this.
 2647       SendMMCCmd(SET_BLOCKLEN,gMediaSectorSize);
 2648   
 2649       //Deselect media while not actively accessing the card.
 2650       SD_CS = 1;
 2651   
 2652       #ifdef __DEBUG_UART  
 2653       PrintROMASCIIStringUART("Returning from MediaInitialize() function.\r\n");
 2654       #endif
 2655   
 2656   
 2657       return &mediaInformation;
 2658   }//end MediaInitialize
 2659   
 2660