This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS570LS0432: Problem with SD card interfacing

Part Number: TMS570LS0432
Other Parts Discussed in Thread: LAUNCHXL-TMS57004, , HALCOGEN

Tool/software: Code Composer Studio

Hello.

I am trying to interface an SD card with the TMS570LS0432 microcontroller. I am using the LAUNCHXL-TMS57004 and an 8GB micro SD card.inserted in an SD card reader. I am using the SPI2 pins for communication with SD Card.I am facing the following issues:-

1) I am using HALCoGen to generate the SPI drivers. The baud rate that I am selecting in the 'SPI2 Data Format' tab is 400KHz for all Data formats. However, after running the code, I am getting a clock pulse of 1MHz, when the SPI2Clk pin is probed. Changes made to the baud rate the SPI2 Data format tab is not getting reflected on the pins. Only a 1MHz clock pulse is being seen as output.

2) I am unable to initialize the SD card. Sometimes, it does work arbitratrily after several clock cycles but then displays only zero values. I am using the GIOA1 for chip select.I have attached a notepad file, containing the code. I have written the code with reference to the other SPI examples I found online. Kindly suggest if there are any faults in the code that can be rectified, to initialize the SD card.

3) Which of the SPI pins need to have a pull-up resistor in HALCoGen?

/** @file sys_main.c 
*   @brief Application main file
*   @date 07-July-2017
*   @version 04.07.00
*
*   This file contains an empty main function,
*   which can be used for the application.
*/

/* 
* Copyright (C) 2009-2016 Texas Instruments Incorporated - www.ti.com 
* 
* 
*  Redistribution and use in source and binary forms, with or without 
*  modification, are permitted provided that the following conditions 
*  are met:
*
*    Redistributions of source code must retain the above copyright 
*    notice, this list of conditions and the following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the 
*    documentation and/or other materials provided with the   
*    distribution.
*
*    Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/


/* USER CODE BEGIN (0) */

#include "sys_common.h"
#include "sci.h"
#include "spi.h"
#include "gio.h"

#define CMD0        0x00            /* GO_IDLE_STATE */
#define CMD1        0x01             /* SEND_OP_COND (MMC) */
#define CMD17       0x11             /* READ_SINGLE */
#define WRITE_SINGLE_BLOCK      0x18
#define DATA_START    0xFE
#define FO_FIRST_SECT 0x1C6           // first sector of first partition offset
#define DATA_ACCEPT   0x05

#define BR_BYTES 0x0B                 // (word) bytes par sector
#define BR_SXC 0x0D                   // (byte) number of sectors per cluster
#define BR_RES 0x0E                   // (word) number of reserved sectors for the boot record
#define BR_FAT_SIZE 0x24              // (word) FAT size in number of sectors
#define BR_FAT_CPY 0x10               // (byte) number of FAT copies
#define BR_MAX_ROOT 0x11              // (odd word) max number of entries in root dir


#define bytes_per_sectors        0x0B   // Size 2 bytes
#define sector_per_cluster       0x0D   // Size 1 bytes
#define number_reserved_sector   0x0E   // Size 2 bytes
#define number_par_fat           0x10   // Size 1 bytes
#define number_of_sector_par_fat 0x24 // Size 4 bytes
#define roots_director_par_cluster 0x2C // Size 4 bytes



#define First_Cluster_High   0x14
#define First_Cluster_Low    0x1A
#define file_capacity            0x1C

#define filetype 0x1C2    // To read file formart is FAt16 or Fat32

unsigned int i;
unsigned int i=0,status;
unsigned char buffer[512];
unsigned long volumeID;
unsigned long FAT1_address;
unsigned long FAT2_address;
unsigned long root_directory_address;
unsigned long data_directory_address;
unsigned long data_directory__sector_address;
unsigned int  bytes_per_sector;
unsigned int  sectors_par_cluster;
unsigned int  reserved_sectors;
unsigned int  fat_copies;
unsigned int  root_enteries;
//unsigned int  sectors_par_fat;
unsigned long address_data_write;
unsigned int cluster_number;
unsigned long total_sector;
unsigned long fat_sectors;
unsigned long root_sectors;
unsigned long data_sectors;
unsigned long file_size;
unsigned long sectors_par_fat;
unsigned rootdir_firstcluster;
unsigned long fat_begin_lba;
unsigned long cluster_begin_lba;
unsigned long lba_address;
unsigned char filename_check[]="BMBM";
unsigned char datalogged[520];
unsigned char CR=0x0D;// ASCII value for /r
unsigned char NL=0x0A; // ASCII code for new line
unsigned int testing[86];
uint16 TX_Data_Master[1] = { 0xFF };
/* USER CODE END */

/* Include Files */



/* USER CODE BEGIN (1) */


unsigned char SPI_Write(unsigned char cData);
void sd_card_initalize();
unsigned int crc7(unsigned char* chr,unsigned int cnt,unsigned char crc);
void sdcard_read(unsigned char sdcard_command,unsigned int long LBA);
void fat_initialize();
void check(unsigned long value);
void file_parameter_finder(unsigned long address,unsigned char *filename);
void root_directory_read(unsigned long cluster);
//void file_write(unsigned sdcard_command,unsigned long cluster);
unsigned char SDCARD_Write(unsigned long address,unsigned int size);
void file_write(unsigned char *data,unsigned long address);
void data_arrange();

/* USER CODE END */

/** @fn void main(void)
*   @brief Application main function
*   @note This function is empty by default.
*
*   This function is called after startup.
*   The user can use this function to implement the application.
*/

/* USER CODE BEGIN (2) */


void SPI_hiSpeed (int on) {

  spiREG2->FMT0 &= 0xFFFF00FF;   // mask out baudrate prescaler
  if (on == 1) {
                                 // Max. 5 MBit used for Data Transfer.
    spiREG2->FMT0 |= 0 << 8;     // baudrate prescale 10MHz / (1+1) = 5MBit
  } else {
                                 // Max. 400 kBit used in Card Initialization.
    spiREG2->FMT0 |= 24 << 8;   // baudrate prescale 10MHz / (24+1) = 400kBit
    spiREG2->FMT1 |= 24 << 8;   // baudrate prescale 10MHz / (24+1) = 400kBit
  }
}


unsigned char SPI_send (unsigned char outb) {

  while ((spiREG2->FLG & 0x0200) == 0); // Wait until TXINTFLG is set for previous transmission
  //spiREG2->DAT1 = outb | 0x100D0000;    // transmit register address
  spiREG2->DAT1 = outb | 0x17010000;    // transmit register address
  while ((spiREG2->FLG & 0x0100) == 0); // Wait until RXINTFLG is set when new value is received
  return((unsigned char)spiREG2->BUF);  // Return received value
}

void _delay_ms(uint32 ms)
{
    uint32 i = 0;
    for( i=0; i<ms*5000; i++)
    {

    }
}

unsigned int SD_CARD_CMD(unsigned char a,unsigned long int LBA)
{
    unsigned char send[6];
    unsigned int j ;
    send[0]=(a|0x40);
    send[1]=LBA>>24;
    send[2]=LBA>>16;
    send[3]=LBA>>8;
    send[4]=LBA;
    send[5]=(crc7(send, 5, 0) << 1) | 1;
    for(i=0;i<6;i++)
    {
        SPI_send(send[i]);
    }

    i = 64;
   do {
        j= SPI_send (0xFF); // check if ready
        sciSendByte(scilinREG, (j+'0'));
      if ( j != 0xFF) break;
      } while ( --i > 0);
    return (j);
}

unsigned int crc7(unsigned char* chr,unsigned int cnt,unsigned char crc)
{
     unsigned int i, a;
     unsigned char Data;

     for(a = 0; a < cnt; a++){
          Data = chr[a];
          for(i = 0; i < 8; i++){
               crc <<= 1;
               if( (Data & 0x80) ^ (crc & 0x80) ) {crc ^= 0x09;}
               Data <<= 1;
          }
     }
     return crc & 0x7F;
}

void sd_card_initalize()
 {
   unsigned int  command_ack;
   retry1: _delay_ms(500);
   gioSetBit(gioPORTA, 1U, 0);
   _delay_ms(5);
   command_ack=SD_CARD_CMD(CMD0,0);
   _delay_ms(5);
   gioSetBit(gioPORTA, 1U, 1);
   if(command_ack==1)
     {
       sciSendByte(scilinREG, 'Y');
     }

     else
     {
         sciSendByte(scilinREG, 'N');
         //_delay_ms(4000);
      goto retry1;
     }
   retry2: _delay_ms(400);
   gioSetBit(gioPORTA, 1U, 0);
   _delay_ms(5);
   command_ack=SD_CARD_CMD(CMD1,0);
   _delay_ms(5);
   gioSetBit(gioPORTA, 1U, 1);
   if(command_ack==0)
     {
      //_delay_ms(1);
       sciSendByte(scilinREG, 'Y');
     }

     else
     {
         _delay_ms(100);
         sciSendByte(scilinREG, 'N');
      goto retry2;
     }
 }
void sdcard_read(unsigned char sdcard_command,unsigned int long LBA)
 {
    unsigned char send[6];
    unsigned int  command_ack;
    send[0]=(sdcard_command|0x40);
    send[1]=LBA>>24;
    send[2]=LBA>>16;
    send[3]=LBA>>8;
    send[4]=LBA;
    send[5]=(crc7(send, 5, 0) << 1) | 1;
    for(i=0;i<6;i++)
    {
        SPI_send(send[i]);
    }
    for(i=0;i<10000;i++)
      {
       command_ack=SPI_send(0xFF);
       if(command_ack==DATA_START)
        {
           sciSendByte(scilinREG, 'A');
          break;
        }
      }
     for(i=0;i<512;i++)
        {
          buffer[i]=SPI_send(0xFF);
        }
     SPI_send(0xFF);
     SPI_send(0xFF);
 }

 void fat_initialize()
  {
    unsigned long fat_offset=0;
    gioSetBit(gioPORTA, 1U, 0);
    sdcard_read(CMD17,0);
    gioSetBit(gioPORTA, 1U, 1);
    for(i=0;i<512;i++)
            {
              //buffer[i]=SPI_send(0xFF);
              sciSendByte(scilinREG, buffer[i]);
            }
    check(volumeID);
      // File format is FAT32
        //fat_offset|=((unsigned long)(buffer[FO_FIRST_SECT+0x03]<<16));
        fat_offset=(((unsigned long)(buffer[FO_FIRST_SECT+0x03]))<<24)|(((unsigned long)(buffer[FO_FIRST_SECT+0x02]))<<16)|(((unsigned long)(buffer[FO_FIRST_SECT+0x01]))<<8)|(((unsigned long)(buffer[FO_FIRST_SECT])));
        volumeID=512*fat_offset;
        check(volumeID);
        gioSetBit(gioPORTA, 1U, 0);
        sdcard_read(CMD17,volumeID);
        gioSetBit(gioPORTA, 1U, 1);
        bytes_per_sector=(((unsigned int)(buffer[ bytes_per_sectors+0x01])<<8))|(((unsigned int)(buffer[bytes_per_sectors])));
        sectors_par_cluster=(((unsigned int)(buffer[sector_per_cluster])));
        reserved_sectors=(((unsigned int)(buffer[number_reserved_sector+0x01])<<8))|(((unsigned int)(buffer[number_reserved_sector])));
        fat_copies=(((unsigned int)(buffer[number_par_fat])));
        sectors_par_fat=(((unsigned long)(buffer[number_of_sector_par_fat+0x03]))<<24)|(((unsigned long)(buffer[number_of_sector_par_fat+0x02]))<<16)|(((unsigned long)(buffer[number_of_sector_par_fat+0x01]))<<8)|(((unsigned long)(buffer[number_of_sector_par_fat])));
        rootdir_firstcluster=(((unsigned long)(buffer[roots_director_par_cluster+0x03]))<<24)|(((unsigned long)(buffer[roots_director_par_cluster+0x02]))<<16)|(((unsigned long)(buffer[roots_director_par_cluster+0x01]))<<8)|(((unsigned long)(buffer[roots_director_par_cluster])));
        fat_begin_lba=fat_offset+reserved_sectors;
        cluster_begin_lba=fat_begin_lba+(((unsigned long)(fat_copies))*((unsigned  long)(sectors_par_fat)));
        check(reserved_sectors);
        check(fat_begin_lba);
        check(cluster_begin_lba);
        check(sectors_par_cluster);


  }


/* USER CODE END */

int main(void)
{
/* USER CODE BEGIN (3) */

        gioInit();
        spiInit();
        //SPI_hiSpeed (0);
        sciInit();
        gioSetBit(gioPORTA, 1U, 1);
        sciSendByte(scilinREG, 'A');
        //gioSetBit(gioPORTA, 1U, 1);
        //_delay_ms(10);
        //gioSetBit(gioPORTA, 1U, 0);

        sd_card_initalize();
            //SPI_hiSpeed (1);
            //_delay_ms(4000);
            //fat_initialize();





/* USER CODE END */

    return 0;
}


/* USER CODE BEGIN (4) */

void check(unsigned long value)
{
    unsigned long data;
    data=value;
    data=data/1000000;
    sciSendByte(scilinREG,(data+'0'));
    data=value;
    data=data%1000000;
    data=data/100000;
    sciSendByte(scilinREG,(data+'0'));
    data=value;
    data=data%100000;
    data=data/10000;
    sciSendByte(scilinREG,(data+'0'));
    data=value;
    data=data%100000;
    data=data%10000;
    data=data/1000;
    sciSendByte(scilinREG,(data+'0'));
    data=value;
    data=data%100000;
    data=data%10000;
    data=data%1000;
    data=data/100;
    sciSendByte(scilinREG,(data+'0'));
    data=value;
    data=data%100000;
    data=data%10000;
    data=data%1000;
    data=data%100;
    data=data/10;
    sciSendByte(scilinREG,(data+'0'));
    data=value;
    data=data%100000;
    data=data%10000;
    data=data%1000;
    data=data%100;
    data=data%10;
    sciSendByte(scilinREG,(data+'0'));
    sciSendByte(scilinREG, 0x0D);
    sciSendByte(scilinREG, 0x0A);
}




/* USER CODE END */

Thank you in advance.

-

Kartik