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
