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