RX

Dependencies:   mbed BufferedSerial SX1276GenericLib X_NUCLEO_IKS01A2

SDCard_Y.cpp

Committer:
TMRL123
Date:
2019-06-05
Revision:
0:fb7bf6d81e5f

File content as of revision 0:fb7bf6d81e5f:

#include "SDCard_Y.hh"



#define SD_COMMAND_TIMEOUT 5000

#define R1_IDLE_STATE           (1 << 0)
#define R1_ERASE_RESET          (1 << 1)
#define R1_ILLEGAL_COMMAND      (1 << 2)
#define R1_COM_CRC_ERROR        (1 << 3)
#define R1_ERASE_SEQUENCE_ERROR (1 << 4)
#define R1_ADDRESS_ERROR        (1 << 5)
#define R1_PARAMETER_ERROR      (1 << 6)




SDCard::SDCard(SPI *t_spi, PinName t_cs) : cs(t_cs)
{
  spi = t_spi;
  cs = 1;
}

SDCard::~SDCard()
{
  delete spi;
}

int SDCard::init(void)
{
  spi->frequency(100000);
  cs = 1;

  for( int i=0 ; i<16 ; i++)
    spi->write(0xFF);

  if(cmd(0,0) != R1_IDLE_STATE)
    return -1;

  int r = cmd8();

  if(r == R1_IDLE_STATE){
    return init_card_v2();      
  } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) {
    return init_card_v1();
  } else {
    return -1;
  }
  
  return 0;
}

int SDCard::init_card_v1()
{
  for (int i = 0; i < SD_COMMAND_TIMEOUT; i++)
    {
      cmd(55, 0);
      if(cmd(41, 0) == 0)
	{
	  cdv = 512;
          return 1;
        }
    }

  return -1;
}


int SDCard::init_card_v2()
{
  for (int i = 0; i < SD_COMMAND_TIMEOUT; i++)
    {
      wait_ms(50);
      cmd58();
      cmd(55, 0);
      if (cmd(41, 0x40000000) == 0)
	{
	  cmd58();
          cdv = 1;
          return 2;
        }
    }

  return -1;
}


int SDCard::cmd(int cmd, int arg)
{
  cs = 0;
  spi->write(0x40 | cmd);
  spi->write(arg >> 24);
  spi->write(arg >> 16);
  spi->write(arg >> 8);
  spi->write(arg >> 0);
  spi->write(0x95);

  for( int i=0 ; i<SD_COMMAND_TIMEOUT ; i++)
    {
      int respuesta = spi->write(0xFF);
      if( !(respuesta & 0x80) )
	{
	  cs = 1;
	  spi->write(0xFF);
	  return respuesta;
	}
    }

  cs = 1;
  spi->write(0xFF);
  return -1;

}


int SDCard::cmd8()
{
  cs = 0;

  spi->write(0x40 | 8); // CMD8
  spi->write(0x00);     // reserved
  spi->write(0x00);     // reserved
  spi->write(0x01);     // 3.3v
  spi->write(0xAA);     // check pattern
  spi->write(0x87);     // crc

  for( int i=0 ; i<SD_COMMAND_TIMEOUT * 1000 ; i++)
    {
      char respuesta[5];
      respuesta[0] = spi->write(0xFF);
      
      if( !(respuesta[0] & 0x80))
	{
	  for( int j=1; j<5 ; j++)
	    respuesta[i] = spi->write(0xFF);

	  cs = 1;
	  spi->write(0xFF);
	  return respuesta[0];
	}
    }

  cs = 1;
  spi->write(0xFF);
  return -1;
  
}



int SDCard::cmd58()
{
  cs = 0;
  
  int arg = 0;

  spi->write(0x40 | 58);
  spi->write(arg >> 24);
  spi->write(arg >> 16);
  spi->write(arg >> 8);
  spi->write(arg >> 0);
  spi->write(0x95);

  // wait for the repsonse (response[7] == 0)
  for(int i = 0; i < SD_COMMAND_TIMEOUT; i++)
    {
      int respuesta = spi->write(0xFF);

      if( !(respuesta & 0x80) )
	{
	  int ocr = spi->write(0xFF) << 24;
          ocr |= spi->write(0xFF) << 16;
          ocr |= spi->write(0xFF) << 8;
          ocr |= spi->write(0xFF) << 0;
          cs = 1;
          spi->write(0xFF);
          return respuesta;
        }
    }
    cs = 1;
    spi->write(0xFF);
    
    return -1; // timeout
}



bool SDCard::read(uint8_t *vect, int post)
{
  while( cmd(17,post*512) == -1);

  cs = 0;

  while (spi->write(0xFF) != 0xFE);

  for (uint32_t i = 0; i < 512; i++)
    *(vect+i) = spi->write(0xFF);

  spi->write(0xFF); // checksum
  spi->write(0xFF);

  cs = 1;
  spi->write(0xFF);

  while(cmd(12,512) == -1);

  return 1;
}



bool SDCard::write(uint8_t *vect, int post)
{
  
  while( cmd(24,post*512) == -1 );
  
  cs = 0;
  
  spi->write(0xFE);
  
  for (uint32_t i = 0; i < 512; i++)
    spi->write(*(vect+i));

  spi->write(0xFF);
  spi->write(0xFF);

  if( (spi->write(0xFF) & 0x1F) != 0x05 )
    {
      cs = 1;
      spi->write(0xFF);
      return 0;
    }

  while(spi->write(0xFF) == 0);

  cs = 1;
  spi->write(0xFF);

  while(cmd(12,512) == -1);

  return 1;
    
}