CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

SDHC Initialization Sequence

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

View user's profile Send private message Send e-mail MSN Messenger

SDHC Initialization Sequence
PostPosted: Wed Nov 26, 2008 10:38 am     Reply with quote

Hi, Im trying to use a SDHC in a datalogger project, but it is a little hard to find informations about its initialization sequence.

if someone has this answer, I´ll apreciate if you share with us.



regards.
_________________
Andre
crystal_lattice



Joined: 13 Jun 2006
Posts: 164

View user's profile Send private message

PostPosted: Thu Nov 27, 2008 12:14 am     Reply with quote

Do a search on google and you will find: http://svenpeter.blogspot.com/2008/11/sdhc-support-for-wii.html

It is not for microcontrollers, but still applies, I haven't played around with these cards so I can't give you experienced help, but here is an extract from the link I gave you:
Quote:
After sending the "GO_IDLE_STATE" command you need to send another command to indicate that you know about SDHC and are going to use it. The next two commands are then very similar to the SDv1 initialization with one more bit set to tell the card (again) that you know about high-capacity cards. If you don't send the special "I know about sdhc kthx" (aka CMD8) command the card will just return an error when you send the next command because it thinks that it can't be used with this host.


Here is another link providing some useful code:
http://www.cygnal.org/ubb/Forum5/HTML/001181.html
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Thu Nov 27, 2008 7:37 am     Reply with quote

Thank you man, I'm gonna check it... when I get some results I'll post.

ps: The second link that you gave me, I've already seen, and didn't work, but I'll look deeper.


regards.
_________________
Andre
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Nov 27, 2008 4:05 pm     Reply with quote

I never used SDHC cards but I think Crystal Lattice summed it up nicely.
You can download the SD / SDHC specifications v2.00 from: http://www.sdcard.org/developers/tech/sdcard/
Check out Figure 4-2 for the command sequence flow.
crystal_lattice



Joined: 13 Jun 2006
Posts: 164

View user's profile Send private message

PostPosted: Fri Nov 28, 2008 12:16 am     Reply with quote

I have also tried the link from that site, but seems you have to go to the site directly (elm chan one) and download the file, i use free download manager but this does not seem to work, i have to allow my browser (mozilla firefox) to download it else i get directed else where. That is, if you are refering to the link not working and not the actual file/driver...

I don't think you will easily find SDHC support/pre written driver for the pic as this falls in the catagory of memory>4GB which is a lot of storage memory for a pic. I doubt that the average hobbiest requires more memory than that... But like Ckielstra said, refer to the manual for answers.
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Fri Nov 28, 2008 9:56 am     Reply with quote

crystall_latice

Im trying to follow the steps in reference manual of sd association, but the 4gb sd kingston that I have doesnt pass from CMD8. CMD0 works fine, but CMD8 doesnt work....

Ill try to find a way to make it works...

thanks for the help.
_________________
Andre
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sun Nov 30, 2008 9:20 am     Reply with quote

Hi,
_________________
Andre


Last edited by andreluizeng on Sun Nov 30, 2008 3:47 pm; edited 1 time in total
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Sun Nov 30, 2008 9:24 am     Reply with quote

Hi,

I've been working on a 4GB SD Kingston, using those information that you gave me, but I can't even pass through CMD8. I received Illegal command all the time.

So, using the block diagram of the initialization sequence in that paper (SD organization), it says that if CMD8 doesn't work, ACMD has to be sent.
so.. I did, and the answer is CRC Error.

This is my initialization sequence just for tests:
Code:


char InitCard (void)
{
   char Requ;
   char i;
   char Cmd;
   long TimeOut;
   

   // dummy clocks
   for (i = 0; i < 20; i++)   MMC8Clock ();   

   // Reset
   printf ("\r\nCMD0");
   Requ = SendCmd (CMD0, 0x00, 0x95);  (arguments are: cmd, data, crc)
   MMCDebug (Requ);
   

   if (Requ == IN_IDLE_STATE)
   {
      printf ("\r\nCMD8");
      // CMD8 - SEND_IF_COND
      Requ = SendCmd (CMD8, 0x1AA, 0x87);      
      MMCDebug (Requ);
      
   // SD Card V2.0 or later
   if (Requ == IN_IDLE_STATE)
   {
      printf ("\r\nSDHC");         
   }
      
   // SD Card V2.0 with wrong voltage
   // or SD Card V1.0 / MMC
   else
   {
      // ACMD41 - SD_SEND_OP_COND
      printf ("\r\nACMD41");
      Requ = SendCmd (ACMD41, 0x00, 0x01);   
      MMCDebug (Requ);
      // SD Card
      if (Requ <= IN_IDLE_STATE)
      {
              Cmd = ACMD41;
            
         printf ("\r\nSD");
      }   
         
      // MMC
      else
      {
         Cmd = CMD1;
         printf ("\r\MMC");
      }   
                  
      TimeOut = 5000;
      Requ = TRUE;
                  
                while (Requ && TimeOut)
                {
            Requ = SendCmd (Comando, 0x00, 0x01);
                   TimeOut--;
                 }

                if (! TimeOut)
                 {
                   printf ("\r\nInitialization sequence failed");
               return FALSE;
                }   
         
      // set block size to 512 bytes
      else
      {
         Requ = SendCmd (CMD16, 0x0200, 0x01);
           
              if (Requ)
                   {
                         printf("\r\nError");
                  return FALSE;
                   }
            
           }   

        }
            
        return TRUE;
   }   

   return FALSE;
}   




and my answers are:

Quote:


CMD0
Request: 0x01
IN IDLE STATE

CMD8
Request: 0x05
IN IDLE STATE
ILLEGAL COMMAND

ACMD41
Request: 0x09
IN IDLE STATE
COMMAND CRC ERROR


Initialization sequence failed


so.... any clues?

Im keeping trying... if any progress Ill post.

thanks.
_________________
Andre
eternauta3k
Guest







PostPosted: Tue Feb 10, 2009 7:33 pm     Reply with quote

I'm having the same problem. When I do a SEND_IF_COND, I get illegal command + in idle state.

The spec says the command is legal in idle state, maybe what it means is that I can only run it while it's still returning a 1 in the idle state bit. I'm gonna try that, see how it works.
spatial



Joined: 07 Jul 2010
Posts: 1

View user's profile Send private message

PostPosted: Wed Jul 07, 2010 9:43 am     Reply with quote

Sorry to open this thread again but I also have been having the same problems with an Kingston 4GB SD Card. I sent them an email and got the following response:

Quote:
Please note that Kingston Technology does not manufacture and subsequently test its range of flash card products to be used for the purpose of being addressed under the SPI mode.

Our products are made for the purpose of being used as removable storage media in popular electronic equipment such as digital cameras, mp3 players, satellite navigation devices, PDAs and mobile phones.

Although it is possible that our cards can be addressed in the way which you intend, we can not guarantee that this will always be possible.

Indeed the results may vary from one card or batch to the next, depending on the type of components used during the manufacturing process.

If you are able to use the cards in standard data transfer mode, then the product is working according to Kingston Technology design specification.

If the card can't be addressed using SPI then it probably isn't too much of a worry and is more of a poor reflection on Kingston.
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Jul 07, 2010 9:57 am     Reply with quote

The simplified physical layer spec specifies:-

"The CMD8 CRC verification is always enabled. The Host shall set correct CRC in the argument of
CMD8. If CRC error is detected, card returns CRC error in R1 response regardless of command index."

You must set the CRC for CMD8 always.
It also says:-

"If the card indicates an illegal command, the card is legacy and does not support CMD8. If the card
supports CMD8 and can operate on the supplied voltage, the response echoes back the supply voltage
and the check pattern that were set in the command argument.
If VCA in the response is set to 0, the card cannot operate on the supplied voltage. If check pattern is
not matched, CMD8 communication is not valid. In this case, it is recommended to retry CMD8
sequence."

retry CMD8 if it fails first time.

Please also note that the SD interface, SPI included is covered by a license for use. It costs around $3000 per year to make a product which can use SD cards.
icebell



Joined: 22 Jun 2012
Posts: 1

View user's profile Send private message

second time
PostPosted: Fri Jun 22, 2012 3:57 am     Reply with quote

That is true, with the kingston 4GB sdHC card, the sescond time I send the CMD8 comand, the response is 0xFF, 0x01, 0x00, 0x00, 0x01, 0xAA.
hadipic



Joined: 02 Dec 2012
Posts: 2

View user's profile Send private message Yahoo Messenger

PostPosted: Tue Feb 17, 2015 4:42 am     Reply with quote

Code:

/*-----------------------------------------------------------------------*/
/* PFF - Low level disk control module for ATtiny85     (C)ChaN, 2009    */
// conver ccs compile  for use pic18f452 by bashniji
// 2015-1-26
//hadi bashniji
// emai hadi.bashniji@gmail .com
//  hcmmc init test ok
// initing low level routin
/*-----------------------------------------------------------------------*/

                 
                                                             
#define _WRITE_FUNC   1                                   

#define   debug_monitor   0
#define   debug_monitor_r   0

/* Definitions for MMC/SDC command */
#define CMD0   (0x40+0)   /* GO_IDLE_STATE */
#define CMD1   (0x40+1)   /* SEND_OP_COND (MMC) */
#define   ACMD41 (0xe9) //(0x80 + 0x40 )   /* SEND_OP_COND (SDC) */
#define CMD8   (0x40+8)   /* SEND_IF_COND */
#define CMD12   (0x40+12)   /* STOP_TRANSMISSION */
#define CMD16   (0x40+16)   /* SET_BLOCKLEN */
#define CMD17   (0x40+17)   /* READ_SINGLE_BLOCK */
#define CMD24   (0x40+24)   /* WRITE_BLOCK */
#define CMD55   (0x40+55)   /* APP_CMD */
#define CMD58   (0x40+58)   /* READ_OCR */

/*--------------------------------------------------------------------------

   Module Private Functions

---------------------------------------------------------------------------*/

#include "stdint.h"
#include <string.h>
 
 #define bud1  18000000 //9216000 // F_CPU / 2
       
                             
#ifndef MMCSD_PIN_SCL
 #define MMCSD_PIN_SCL     PIN_C3 //o
 #define MMCSD_PIN_SDI     PIN_C4 //i
 #define MMCSD_PIN_SDO     PIN_C5 //o
 #define MMCSD_PIN_SELECT  PIN_C2 //o                                                             
#endif

   
         

#define USE_SW_ONLY 0
                       
#if USE_SW_ONLY
/* For software spi */
#use spi(MASTER,BAUD=bud1,CLK=MMCSD_PIN_SCL, DO=MMCSD_PIN_SDO, DI=MMCSD_PIN_SDI, BITS=8, MODE=3, MSB_FIRST, stream=mmcsd_spi, FORCE_SW)
#else                 
/* For hardware spi */
#use spi(MASTER,BAUD=bud1,CLK=MMCSD_PIN_SCL, DO=MMCSD_PIN_SDO, DI=MMCSD_PIN_SDI, BITS=8, MODE=3, stream=mmcsd_spi, FORCE_HW)
#endif

                                                                               

#define dword int32                                                                               
#define word int16                                                                 

/* Status of Disk Functions */
typedef BYTE   DSTATUS;


/* Results of Disk Functions */
typedef enum {
   RES_OK = 0,      /* 0: Function succeeded */
   RES_ERROR,      /* 1: Disk error */
   RES_NOTRDY,      /* 2: Not ready */
   RES_PARERR      /* 3: Invalid parameter */
} DRESULT;


/*---------------------------------------*/
/* Prototypes for disk control functions */

//DSTATUS disk_initialize (void);
//DRESULT disk_readp (BYTE*, DWORD, WORD, WORD);
//DRESULT disk_writep (const BYTE*, DWORD);

#define STA_NOINIT      0x01   /* Drive not initialized */
#define STA_NODISK      0x02   /* No medium in the drive */

/* Card type flags (CardType) */
#define CT_MMC            0x01   /* MMC ver 3 */
#define CT_SD1            0x02   /* SD ver 1 */
#define CT_SD2            0x04   /* SD ver 2 */
#define CT_SDC            (CT_SD1|CT_SD2)   /* SD */
#define CT_BLOCK         0x08   /* Block addressing */



#byte SSPCON1= 0x0FC6


#bit  SSPM1    =  SSPCON1.1
#bit  SSPM0    =  SSPCON1.0



BYTE CardType;



void init_spi(void){                         



   output_drive(MMCSD_PIN_SCL);
   output_drive(MMCSD_PIN_SDO);             
   output_drive(MMCSD_PIN_SELECT);
   output_float(MMCSD_PIN_SDI);
                                 
}


unsigned char xmit_spi(unsigned char dat)
{

spi_xfer(mmcsd_spi,dat);

}


/*-----------------------------------------------------------------------*/
/* Receive a byte from MMC via SPI  (Platform dependent)                 */

/*-----------------------------------------------------------------------*/

unsigned char rcv_spi(void)
{
    return spi_xfer(mmcsd_spi, 0xFF);
}




/*-----------------------------------------------------------------------*/
/* Deselect the card and release SPI bus                                 */
/*-----------------------------------------------------------------------*/

static
void deselect (void)
    {
   
    output_high(MMCSD_PIN_SELECT);
  //  spi_xfer(mmcsd_spi,0xff);    /* Dummy clock (force DO hi-z for multiple slave SPI) */
    }



/*-----------------------------------------------------------------------*/
/* Select the card and wait for ready                                    */
/*-----------------------------------------------------------------------*/

static
int select (void)    /* 1:Successful, 0:Timeout */
    {
   
    output_low(MMCSD_PIN_SELECT);
  //  spi_xfer(mmcsd_spi,0xff);   /* Dummy clock (force DO enabled) */

   // if (wait_ready()) return 1;    /* OK */
   // deselect();
   //
   //return 0;    /* Timeout */
    }



/*-----------------------------------------------------------------------*/
/* Deselect the card and release SPI bus                                 */
/*-----------------------------------------------------------------------*/

static
void release_spi (void)
{
   DESELECT();
   rcv_spi();
}

/*-----------------------------------------------------------------------*/
/* Wait for card ready                                                   */
/*-----------------------------------------------------------------------*/

static
BYTE wait_ready (void)
{
   BYTE res;
   WORD timeout = 0x1FFF;
   
   do
      res = rcv_spi();
   while ((res != 0xFF) && (--timeout));
   
   return res;
}

/*-----------------------------------------------------------------------*/
/* Send a command packet to MMC                                          */
/*-----------------------------------------------------------------------*/

static
BYTE send_cmd (
   BYTE cmd,      /* Command byte */
   DWORD arg      /* Argument */
)
{
   BYTE n, res;

   /* Select the card and wait for ready */
   DESELECT();
   SELECT();

   if (wait_ready() != 0xFF) {
      return 0xFF;
   }

 
//res = send_cmd(CMD55, 0);      // PICC18 Compiler error! (recursive function)

   if (cmd & 0x80) {   /* ACMD<n> is the command sequence of CMD55-CMD<n> */
     
      cmd= cmd & 0x7F;
       
     
      //res = send_cmd(CMD55, 0);      // PICC18 Compiler error! (recursive function)
      /* Send command packet */
       xmit_spi(CMD55);                  /* Start + Command index */
       xmit_spi( make8(0, 3));      /* Argument[31..24] */
       xmit_spi( make8(0, 2));      /* Argument[23..16] */
       xmit_spi( make8(0, 1));         /* Argument[15..8] */
       xmit_spi( make8(0, 0));            /* Argument[7..0] */
      n = 0x01;                     /* Dummy CRC + Stop */
     
       if (cmd == CMD0) n = 0x95;         /* Valid CRC for CMD0(0) */
      if (cmd == CMD8) n = 0x87;         /* Valid CRC for CMD8(0x1AA) */
       xmit_spi(n);
       
      /* Receive command response */
      if (cmd == CMD12) rcv_spi();      /* Skip a stuff byte when stop reading */
   
      n = 10;                        /* Wait for a valid response in timeout of 10 attempts */
      do
         res = rcv_spi();
      while ((res & 0x80) && --n);
      if (res > 1) return res;
   }
   
   
 
   

   /* Send command packet */
   xmit_spi(cmd);                  /* Start + Command index */
   xmit_spi( make8(arg, 3));      /* Argument[31..24] */
   xmit_spi( make8(arg, 2));      /* Argument[23..16] */
   xmit_spi( make8(arg, 1));         /* Argument[15..8] */
   xmit_spi( make8(arg, 0));            /* Argument[7..0] */
   n = 0x01;                     /* Dummy CRC + Stop */
   if (cmd == CMD0) n = 0x95;         /* Valid CRC for CMD0(0) */
   if (cmd == CMD8) n = 0x87;         /* Valid CRC for CMD8(0x1AA) */
   xmit_spi(n);
   
   /* Receive command response */
   if (cmd == CMD12) rcv_spi();      /* Skip a stuff byte when stop reading */
     
   n = 10;                        /* Wait for a valid response in timeout of 10 attempts */
   do
      res = rcv_spi();
   while ((res & 0x80) && --n);
       #if debug_monitor_r
     printf (" %d ->  %x \n\r",cmd-0x40,res);
     #endif
   return res;         /* Return with the response value */
}
                                           


/*--------------------------------------------------------------------------

   Public Functions

---------------------------------------------------------------------------*/


/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive                                                 */
/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (void)
{
   BYTE n, cmd, ty, ocr[4];
   int16 tmr,timer1;
         
                                                                                                 
   init_spi();
   
    // sspm0 , sspm1  >  00       foc/4     01 foc/16      10    foc /64
   // foc/64 low sped
    SSPM0 = 1 ;   
    SSPM1 = 0 ; 
                               
#if _WRITE_FUNC
//   if (MMC_SEL) disk_writep(0, 0);      /* Finalize write process if it is in progress */
#endif
   for (n = 100; n; n--) rcv_spi();   /* Dummy clocks */
                   

   ty = 0;
   if (send_cmd(CMD0, 0) == 1)
   {         /* Enter Idle state */
     
     
     if (send_cmd(CMD8, 0x1AA) == 1)
      {   /* SDv2 */                   
         
         for (n = 0; n < 4; n++) ocr[n] = rcv_spi();      /* Get trailing return value of R7 resp */
         if (ocr[2] == 0x01 && ocr[3] == 0xAA) {            /* The card can work at vdd range of 2.7-3.6V */
          #if debug_monitor 
         printf ("cmd8= %x %x  \n\r",ocr[2],ocr[3]);
          #endif                             
        // while (get_timer1() && send_cmd(ACMD41,(DWORD)1 << 30));
         for (tmr = 12000; tmr && send_cmd(ACMD41,(int32)1<<30 ); tmr--) ;delay_us(1) ;   /* Wait for leaving idle state (ACMD41 with HCS bit) */ // 1<<30=0x40000000
       //     if (get_timer1()&& send_cmd(CMD58, 0) == 0)         /* Check CCS bit in the OCR */
                                           
            if (tmr && send_cmd(CMD58, 0) == 0)   
            {      /* Check CCS bit in the OCR */               
               for (n = 0; n < 4; n++) ocr[n] = rcv_spi();         
                #if debug_monitor                 
                printf ("ocr= %x %x %x %x  \n\r",ocr[0],ocr[1]ocr[2],ocr[3]);
               #endif                                                                           
               ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;   /* SDv2 (HC or SC) */
             
            }
         }                                               
      }
      else {                     /* SDv1 or MMCv3 */
         
        //  for (tmr = 25000; tmr && send_cmd(cmd1, 0); tmr--);
         
         if (send_cmd(ACMD41, 0) <= 1)   
         {
            ty = CT_SD1; cmd = ACMD41;   /* SDv1 */
         }
         else                 
         {   /* Proteus 7.x MMC sim model */
            ty = CT_MMC; cmd = CMD1;   /* MMCv3 */
         }
           #if debug_monitor
          printf ("card type %x  \n\r",ty);
          #endif
        for (tmr = 25000; tmr && send_cmd(cmd, 0); tmr--) ;
           
          #if debug_monitor             
         printf ("cmd41 \n\r",);   /* Wait for leaving idle state */
          #endif
         if (!tmr || send_cmd(CMD16, 512) != 0)         /* Set R/W block length to 512 */
            ty = 0;
      }
   }
   
                                               
   CardType = ty;
   release_spi();
    #if debug_monitor
   printf ("card type %x  \n\r",CardType);
    #endif                                                         
           SSPM0 = 0 ;   
           SSPM1 = 0 ;   
 
   return ty ? 0 : STA_NOINIT;
}



/*-----------------------------------------------------------------------*/
/* Read partial sector                                                   */
/*-----------------------------------------------------------------------*/

DRESULT disk_readp (
   BYTE *buff,      /* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */
   DWORD lba,      /* Sector number (LBA) */
   WORD ofs,      /* Byte offset to read from (0..511) */
   WORD cnt      /* Number of bytes to read (ofs + cnt mus be <= 512) */
)
{
   DRESULT res;
   BYTE rc;
   WORD bc;


   if (!(CardType & CT_BLOCK)) lba *= 512;      /* Convert to byte address if needed */

   res = RES_ERROR;
   if (send_cmd(CMD17, lba) == 0) {      /* READ_SINGLE_BLOCK */

      bc = 30000;
      do {                     /* Wait for data packet in timeout of 100ms */
         rc = rcv_spi();
      } while (rc == 0xFF && --bc);

      if (rc == 0xFE) {            /* A data packet arrived */
         bc = 514 - ofs - cnt;

         /* Skip leading bytes */
         if (ofs) {
            do rcv_spi(); while (--ofs);
         }

         /* Receive a part of the sector */
         if (buff) {   /* Store data to the memory */
            do
               *buff++ = rcv_spi();
            while (--cnt);
         } else {   /* Forward data to the outgoing stream (depends on the project) */
            //do
               //xmit(rcv_spi());   /* (Console output) */
            //while (--cnt);
         }

         /* Skip trailing bytes and CRC */
         do rcv_spi(); while (--bc);

         res = RES_OK;
      }
   }

   release_spi();

   return res;
}

/*-----------------------------------------------------------------------*/
/* Write partial sector                                                  */
/*-----------------------------------------------------------------------*/
#if _WRITE_FUNC

DRESULT disk_writep (
    BYTE *buff,   /* Pointer to the bytes to be written (NULL:Initiate/Finalize sector write) */
   DWORD sa         /* Number of bytes to send, Sector number (LBA) or zero */
)
{
   DRESULT res;
   WORD bc;
   static WORD wc;


   res = RES_ERROR;

   if (buff) {      /* Send data bytes */
      bc = (WORD)sa;
      while (bc && wc) {      /* Send data bytes to the card */
         xmit_spi(*buff++);
         wc--; bc--;
      }
      res = RES_OK;
   } else {
      if (sa) {   /* Initiate sector write process */
         if (!(CardType & CT_BLOCK)) sa *= 512;   /* Convert to byte address if needed */
         if (send_cmd(CMD24, sa) == 0) {         /* WRITE_SINGLE_BLOCK */
            xmit_spi(0xFF); xmit_spi(0xFE);      /* Data block header */
            wc = 512;                     /* Set byte counter */
            res = RES_OK;
         }
      } else {   /* Finalize sector write process */
         bc = wc + 2;
         while (bc--) xmit_spi(0);   /* Fill left bytes and CRC with zeros */
         if ((rcv_spi() & 0x1F) == 0x05) {   /* Receive data resp and wait for end of write process in timeout of 300ms */
            for (bc = 65000; rcv_spi() != 0xFF && bc; bc--) ;   /* Wait ready */
            if (bc) res = RES_OK;
         }
         release_spi();
      }
   }

   return res;
}
#endif

Code:


Last edited by hadipic on Tue Feb 17, 2015 4:47 am; edited 2 times in total
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group