![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
rufinopc@rufinogg.com
Joined: 11 Mar 2023 Posts: 17
|
SDCARD problems |
Posted: Mon Mar 13, 2023 6:35 am |
|
|
SDCARD problems
Say hello to everyone in this forum since I'm new here and apologize for using Google's Spanish to English translator.
For several days I have been reading countless pages related to SD cards and the CCS compiler, including the contributions made by various people in this forum. None of the examples have worked for me.
I am using an OLIMEX insert with the micro ESP33EP256MU. With these boards I have made countless applications without any problem, but I had never used the SD. The version of CCS that I am using is 5.109 and as an example the version of CCS ex_fat.c. Obviously I have changed the configuration parts of the PIC33EP... which work perfectly since I have checked with the oscilloscope the four signals used by the SD:
Code: |
#define MMCSD_PIN_SDO PIN_G
#pin_select SCK1OUT = MMCSD_PIN_SCL
#pin_select SDI1 = MMCSD_PIN_SDI
#pin_select SDO1 = MMCSD_PIN_SDO
#use spi(SPI1,MASTER,BITS=8,CLK=MMCSD_PIN_SCL,DO= MMCSD_PIN_SDO,DI=MMCSD_PIN_SDI,ENABLE=MMCSD_PIN_SELECT,MODE=0,stream = mmcsd_spi)
#define MMCSD_SPI_XFER(x) spi_xfer(mmcsd_spi, x)
| The only correct response is boot when the SD is initialized, but the response to the "dir" command is "--/-- />" and on the card there are two text files and two folders with both text files ( just a few letters)
As a measure I have replaced all the ints with uint8_t, but I have run out of ideas from so many changes and tests that I have done
Any ideas or has anyone fixed these issues?
Thank you so much
Code: |
#ifndef TarjetaSDFat_C
#define TarjetaSDFat_C
#include <stdlib.h> // for atoi32
///////////////////////////////////////////////////////////////////////////////
#FUSES PR_PLL //Primary Oscillator with PLL
#FUSES HS //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOGSSK //General Segment Key bits, use if using either NOWRT or NOPROTECT fuses
#FUSES CKSNOFSM //Clock Switching is enabled, fail Safe clock monitor is disabled
#FUSES NOIOL1WAY //Multiples reconfiguraciones
#FUSES ALTI2C1 //I2C1 mapped to SDA1/SCL1 pins
// #FUSES ALTI2C2 //I2C2 mapped to SDA2/SCL2 pins
#FUSES NOJTAG //JTAG disabled
#FUSES NOAPLK
#FUSES WDT
#FUSES NOBROWNOUT
#FUSES NOWRT
#use delay(clock=120MHz,crystal=8MHz,restart_wdt)
//CONEXIONES DIRECTAS PARA EL CONVERSOR UART/USB
#pin_select U1RX=PIN_F4
#pin_select U1TX=PIN_F5
#use RS232(UART1,BAUD=115200,BRGH1OK,RESTART_WDT,STREAM = ExitUART1)
/////////////////// CONEXIONES DIRECTAS PARA LAS UART
#define SD_CS PIN_B13
#define MMCSD_PIN_SCL PIN_G6 //o
#define MMCSD_PIN_SDI PIN_G7 //i
#define MMCSD_PIN_SDO PIN_G8 //o#define MMCSD_PIN_SELECT SD_CS
#pin_select SCK1OUT = MMCSD_PIN_SCL
#pin_select SDI1 = MMCSD_PIN_SDI
#pin_select SDO1 = MMCSD_PIN_SDO
#use spi(SPI1,MASTER,BITS=8,CLK=MMCSD_PIN_SCL,DO=MMCSD_PIN_SDO,DI=MMCSD_PIN_SDI,ENABLE=MMCSD_PIN_SELECT,MODE=0,stream = mmcsd_spi)
#define MMCSD_SPI_XFER(x) spi_xfer(mmcsd_spi, x)
#endif
|
Code: |
/////////////////////////////////////////////////////////////////////////
#include <33EP256MU806.h>
#device PASS_STRINGS = IN_RAM
#include "TarjetaSDFat32.h"
#define FAT32
#device PASS_STRINGS = IN_RAM
//
#include <mmcsd.c>
#include <fat.c>
//////////////////////
/// ///
/// Useful Defines ///
/// ///
//////////////////////
#define COMMAND_SIZE 10
#define NUM_COMMANDS 11
#define MMCSD_MAX_BLOCK_SIZE 512
////////////////////////
/// ///
/// Global Variables ///
/// ///
////////////////////////
char g_CWD[200] = "/"; //current working directory
char commands[NUM_COMMANDS][COMMAND_SIZE]=
{
"del", //option1=filename. delete file.
"make", //option1=filename. create an empty file, give error if file already exists
"append", //option1=filename, option2=string. append string to end of file
"cd", //option1=new cwd. change working directory. / is root.
"dir", //show files in directory
"cat", //option1=filename. display full contents in ascii
"tail", //option1=filename. display the last 20 lines of file.
"mkdir", //option1=dir. create directory. see 'cd' for rules on dir
"rmdir", //option1=dir. remove directory. see 'cd' for rules on dir.
"format", // option1=media size in bytes. formats the media.
"help" // help!
};
////////////////////////////////
/// ///
/// Function Implementations ///
/// ///
////////////////////////////////
/*
Summary: Finds a command from the global list of commands.
Param: A pointer to the command string.
Returns: The command number if the command is found in the command list.
0xFF if the command isn't found
*/
uint8_t FindCommand(char *cmd)
{
char buf[COMMAND_SIZE];
uint8_t i;
for (i=0; i<NUM_COMMANDS; i++)
{
strcpy(buf, &commands[i][0]);
if (stricmp(buf, cmd)==0)
return(i);
}
return(0xFF);
}
/*
Summary: Displays the current working directory.
Param: None.
Returns: None.
*/
void DisplayPrompt(void)
{
printf("\r\n%s> ", g_CWD);
}
/*
Summary: Deletes a file.
Param: The full path of the file to delete.
Returns: None.
*/
void DeleteFile(char *fileName)
{
printf("\r\nDeleting '%s': ", fileName);
if(rm_file(fileName) != GOODEC)
{
printf("Error deleting file");
return;
}
printf("OK");
}
/*
Summary: Creates a file.
Param: The full path of the file to create.
Returns: None.
Example Usage: \> make "Log.txt"
*/
void MakeFile(char *fileName)
{
printf("\r\nMaking file '%s': ", fileName);
if(mk_file(fileName) != GOODEC)
{
printf("Error creating file");
return;
}
printf("OK");
}
/*
Summary: Append a string to a file.
Param: The full path of the file to append to.
Param: A pointer to a string to append to the file.
Returns: None.
Example Usage: \> append "Log.txt" "This will be appended to the end of Log.txt"
Note: A "\r\n" will be appended after the appendString.
*/
void AppendFile(char *fileName, char *appendString)
{
FILE stream;
printf("\r\nAppending '%s' to '%s': ", appendString, fileName);
if(fatopen(fileName, "a", &stream) != GOODEC)
{
printf("Error opening file");
return;
}
fatputs(appendString, &stream);
fatputs("\r\n", &stream);
if(fatclose(&stream) != GOODEC)
{
printf("Error closing file");
return;
}
printf("OK");
}
/*
Summary: Change the working directory.
Param: The new working directory to switch to.
Returns: None.
Example Usage: \> cd ftp/ -> /ftp/
\ftp\> cd files/ -> /ftp/files/
\ftp\files> cd.. -> /ftp/
\ftp\> cd .. -> /
\> cd /ftp/files/ -> /ftp/files/
Note: Changing the directory to .. will go up a directory.
*/
void ChangeDirectory(char *newCWD)
{
FILE stream;
//append a / to the end of the filename if it doesn't exist
//making an assumption here that newCWD can hold 1 more character
if (newCWD[strlen(newCWD)-1] != '/')
strcat(newCWD, "/");
if((strstr(newCWD, "../") != 0) && (strcmp(g_CWD, "/") != 0))
{
g_CWD[strlen(g_CWD) - 1] = '\0';
g_CWD[strrchr(g_CWD, '/') - g_CWD + 1] = '\0';
}
else
{
if(fatopen(newCWD, "r", &stream) != GOODEC)
{
printf("\r\nError changing directory");
return;
}
strcpy(g_CWD, newCWD);
}
}
/*
Summary: Display the contents of the working directory.
Param: The full path of the directory contents to display.
Returns: None.
Example Usage: /> dir
*/
void DisplayDirectory(char *dir)
{
disp_folder_contents(dir);
}
/*
Summary: Create a directory.
Param: The full path of the directory to create.
Returns: None.
Example Usage: /> mkdir "Backlog"
*/
void MakeDirectory(char *dir)
{
//append a / to the end of the filename if it doesn't exist
//making an assumption here that newCWD can hold 1 more character
if (dir[strlen(dir)-1] != '/')
strcat(dir, "/");
printf("\r\nMaking directory '%s': ", dir);
if(mk_dir(dir) != GOODEC)
{
printf("Error creating directory");
return;
}
printf("OK");
}
/*
Summary: Remove a directory.
Param: The full path of the directory to remove.
Returns: None.
Example Usage: /> rmdir "Backlog"
Note: The directory needs to be empty in order for this command to work.
*/
void RemoveDirectory(char *dir)
{
printf("\r\nRemoving directory '%s': ", dir);
//append a / to the end of the filename if it doesn't exist
//making an assumption here that newCWD can hold 1 more character
if (dir[strlen(dir)-1] != '/')
strcat(dir, "/");
if(rm_dir(dir) != GOODEC)
{
printf("Error removing directory");
return;
}
printf("OK");
}
#define CAT_FROM_START FALSE
#define CAT_FROM_END TRUE
/*
Summary: Prints either all of or the last 80 characters in a file.
Param: The full path of the file to print off.
Param: If true, this function will print off the last 80 characters in the file.
If false, this funciton will print off the entire file.
Returns: None.
Example Usage: /> cat "Logs.txt" (this will display the entire file)
Example Usage: /> tail "Logs.txt" (this will display the last 80 characters in the file)
*/
void PrintFile(char *fileName, int1 startFromEnd)
{
FILE stream;
if(fatopen(fileName, "r", &stream) != GOODEC)
{
printf("\r\nError opening file");
return;
}
printf("\r\n");
if(startFromEnd)
fatseek(&stream, 80, SEEK_END);
fatprintf(&stream);
fatclose(&stream);
}
/*
Summary: Formats the media to a specified size.
Param: The size of the media, in kB, in string form.
Returns: None.
Example Usage: /> format 524288 (format a 512MB card)
*/
void FormatMedia(char *mediaSize)
{
int32 size;
size = atoi32(mediaSize);
printf("\r\nFormatting media (size=%LU): ", size);
if(format(size) != GOODEC)
{
printf("Error formatting media");
return;
}
printf("OK");
}
/*
Summary: Shows a help prompt.
Param: None.
Returns: None.
Example Usage: /> help
*/
void ShowHelp()
{
printf("\r\nFAT Shell Help");
printf("\r\n del filename --- Deletes the file");
printf("\r\n make filename --- Creates an empty file");
printf("\r\n append filename string --- Appends string to the end of the file");
printf("\r\n cd dir --- Change the working directory");
printf("\r\n dir --- Shows the contents of the directory");
printf("\r\n cat filename --- Displays content of file");
printf("\r\n tail filename --- Displays the last 80 characters of file");
printf("\r\n mkdir dir --- Create a directory");
printf("\r\n rmdir dir --- Deletes the directory");
printf("\r\n format size --- Format card. (Example: 'format 5524288' formats a 512MB card)");
printf("\r\n help\tYou are here");
printf("\r\n Put a parameter in quotes if it has spaces");
}
char * GetCMD(char *in)
{
char tokens[]=" \r\n";
return(strtok(in,tokens));
}
char * GetOption(char *in)
{
char tokensSpace[]=" \r\n";
char tokensQuote[]="\"\r\n";
//trim leading spaces
while (*in==' ')
in++;
//if first char is a quote, then end token on a quote. ELSE end token on a space
if (*in == '\"')
return(strtok(in,tokensQuote));
else
return(strtok(in,tokensSpace));
}
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
#zero_ram
void main(void){
char buffer[255];
char opt_buffer[255];
char *cmd, *option1, *option2;
uint8_t i; // pointer to the buffer
// initialize the FAT
// keep in mind that this will automagically initialize the media
//while (!CardInserted()){
// if (!CardInserted()){
printf("\r\nTarjeta NO Insertada!\r\n");
delay_ms(1000);
// }
if (mmcsd_init())
printf("NO puedo Iniciar MMC/SD!!!!\r\n");
else
printf("Iniciada MMC/SD!!!!\r\n");
i = fat_init();
if (i)
printf("ERROR INITIALIZING FAT\r\n");
else
printf("FAT Inicializada\r\n");
// main loop
while(TRUE){
i = 0;
DisplayPrompt();
do
{
buffer[i] = getch();
// check for a backspace
if(buffer[i] != 8)
{
printf("%c", buffer[i]);
i++;
}
else if(i > 0)
{
// delete the last character
i--;
putc(8);
putc(' ');
putc(8);
}
buffer[i] = '\0';
} while(buffer[i - 1] != '\r');
// parse the command and options
cmd = GetCMD(buffer);
option1 = GetOption(cmd + strlen(cmd) + 1);
option2 = GetOption(option1 + strlen(option1) + 1);
/*
//if option1 starts with a '/', that means the file in the option includes
//the full path to the file. if the file doesn't start with a '/', the
//current working directory must be added.
//si la opción1 comienza con '/', eso significa que el archivo en la opción incluye
//la ruta completa al archivo. si el archivo no comienza con '/', el
//Se debe agregar el directorio de trabajo actual.
*/
if (option1 && (option1[0]=='/'))
{
//option1 is a full path
strcpy(opt_buffer, option1);
}
else if (option1)
{
// tack on the current working directory to option1
strcpy(opt_buffer, g_CWD);
strcat(opt_buffer, option1);
}
delay_cycles(2);
delay_cycles(2);
if (cmd)
{
switch(FindCommand(cmd))
{
case 0: //del
DeleteFile(opt_buffer);
break;
case 1: //make
MakeFile(opt_buffer);
break;
case 2: //append
AppendFile(opt_buffer, option2);
break;
case 3: //change directory
ChangeDirectory(opt_buffer);
break;
case 4:{ //show directory contents
delay_us(2);
delay_us(2);
DisplayDirectory(g_CWD); }
break;
case 5: //cat, display file
PrintFile(opt_buffer, CAT_FROM_START);
break;
case 6: //tail, display last 80 charachters
PrintFile(opt_buffer, CAT_FROM_END);
break;
case 7: //mkdir, make a directory
MakeDirectory(opt_buffer);
break;
case 8: //rmdir, make a directory
RemoveDirectory(opt_buffer);
break;
case 9: //format, format the card
FormatMedia(option1);
break;
case 10: //help, display help
ShowHelp();
break;
default:
printf("Unkown Command '%s'\r\n", cmd);
break;
}
}
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Mon Mar 13, 2023 9:38 am |
|
|
hmm, I don't use that PIC or SD but....
what OLIMEX board are you using ? Will it properly interface to 5 volt PICs ?
what size SD card ? original driver was limited I think to 2GB ?? |
|
![](templates/subSilver/images/spacer.gif) |
rufinopc@rufinogg.com
Joined: 11 Mar 2023 Posts: 17
|
|
Posted: Mon Mar 13, 2023 9:43 am |
|
|
The board is a PENGUIN PIC33, and the SD is powered by 3.3V.
It is an 8GB SD |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Mon Mar 13, 2023 10:48 am |
|
|
hmm, downloaded OLIMEX's PIC32-Pinguino datasheet and the SD interfcae is built onto the PCB, both 3 volt devices, so not an interface problem....
Hopefully someone who used SD will reply soon...
Maybe ask on the Olimex forum ?? |
|
![](templates/subSilver/images/spacer.gif) |
rufinopc@rufinogg.com
Joined: 11 Mar 2023 Posts: 17
|
|
Posted: Mon Mar 13, 2023 10:52 am |
|
|
I'm trying
Thank you so much |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Mon Mar 13, 2023 12:36 pm |
|
|
Thing that leaps out, is that the initialisation may not be taking place
correctly. The initialisation sequence has to be sent at a much slower
speed than the later communications. On my own PIC32 code for
SD, I program two streams. One using the pins, and software SPI
setup at 400Kbps. The other set to use the hardware SPI port.
The initialisation is done on the former, and once this is sent, I use
the software pps_select command to attach the pins to the SPI port,
and then use the second stream for the rest of the communications.
The SSD definitions say 400K max for the SPI during initialisation.
The standard code has this being done by changing the divider to the
SPI. On the DsPIC's the two stream approach is easier. |
|
![](templates/subSilver/images/spacer.gif) |
rufinopc@rufinogg.com
Joined: 11 Mar 2023 Posts: 17
|
|
Posted: Tue Mar 14, 2023 12:51 am |
|
|
Thank you for the interest shown.
Indeed it seems that it is not initialized. I've lowered the speed to 400KHz, but it's still the same; I have connected the oscilloscope and there are no pulses of any kind, there is only one falling edge in each signal, however, when I execute a command (dir, for example) all the pulses appear correctly:
Code: |
/> Insertada!
Iniciada MMC/SD!!!!
FAT Inicializada
/> dir
--/--
/> |
|
|
![](templates/subSilver/images/spacer.gif) |
rufinopc@rufinogg.com
Joined: 11 Mar 2023 Posts: 17
|
|
Posted: Tue Mar 14, 2023 1:40 am |
|
|
I have verified that the MMCSD_PIN_SELECT pin was not programmed correctly, I don't know why:
Code: |
MMCSD_err mmcsd_init(){
uint8_t
i,
r1;
g_CRC_enabled = TRUE;
g_mmcsdBufferAddress = 0;
#if defined(MMCSD_PIN_SCL)
output_drive(MMCSD_PIN_SCL);
#endif
#if defined(MMCSD_PIN_SDO)
output_drive(MMCSD_PIN_SDO);
#endif
output_drive(MMCSD_PIN_SELECT);
#if defined(MMCSD_PIN_SDI)
output_float(MMCSD_PIN_SDI);
#endif
mmcsd_deselect();
delay_ms(15);
|
Until it was not executed:
Code: |
void mmcsd_deselect(){
MMCSD_SPI_XFER(0xFF);
output_high(MMCSD_PIN_SELECT);
|
Now all the pulses are correctly in the initialization, also in the first -> dir that is sent, although it still does not show data; in successive ->dir pulses of any kind no longer appear nor, obviously, data. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Tue Mar 14, 2023 2:25 am |
|
|
Do your SPI setups as:
Code: |
#define SD_CS PIN_B13
#define MMCSD_PIN_SCL PIN_G6 //o
#define MMCSD_PIN_SDI PIN_G7 //i
#define MMCSD_PIN_SDO PIN_G8 //o#define MMCSD_PIN_SELECT SD_CS
//do not have these
//#pin_select SCK1OUT = MMCSD_PIN_SCL
//#pin_select SDI1 = MMCSD_PIN_SDI
//#pin_select SDO1 = MMCSD_PIN_SDO
#use spi(SPI1,MASTER,BITS=8,ENABLE=MMCSD_PIN_SELECT,MODE=0,stream = mmcsd_spi, baud=400000)
//Do not name the pins here,
|
Then at the start of mmcsd_init, have:
Code: |
pin_select(SCK1OUT,NULL);
pin_select(SDI1,NULL);
pin_select(SDO1,NULL);
|
Have it then do the outputs on the pins, and then do the proper select:
Code: |
pin_select(SCK1OUT,MMCSD_PIN_SCL);
pin_select(SDI1,MMCSD_PIN_SDI);
pin_select(SDO1,MMCSD_PIN_SDO);
|
Then when it gets to the line "this would be a good time to set a higher
clock speed", have:
spi_speed(mmcsd_spi, 10000000);
As a comment, if you instead of using SPI1, could use SPI2 with it's
dedicated pins, you can clock the SPI faster than this. SPI2 can go to
15MHz.
Also turn up the WDT time, or disable it for the initial testing. What you
are doing with the watchdog is pretty much pointless (the chip can hit
restart instructions even if the code has gone badly wrong, since you have
them scattered everywhere in the delays and serial), and there is a big
risk that with the default timeout, loops handling the SD could watchdog. |
|
![](templates/subSilver/images/spacer.gif) |
rufinopc@rufinogg.com
Joined: 11 Mar 2023 Posts: 17
|
|
Posted: Tue Mar 14, 2023 3:42 am |
|
|
I am using an OLIMEX board with the micro PIC33EP256MU806 and the wiring that this board has for the SD is the one that I am configuring, so I cannot change to SPI2. Regarding the WDT, I have deactivated it, although I knew it was not causing problems, but just in case...
I have made the suggested changes (alter the pin programming and configuration of SPI1) but the result at INITIALIZATION (or after a RESET) is the same:
1.- A low pulse on MMCSD_PIN_SELECT during which there are only 8 pulses of MMCSD_PIN_SCL
2.- When MMCSD_PIN_SELECT goes low, the level of MCSD_PIN_SDO goes high and stays that way all the time.
3.- During all the time MMCSD_PIN_SDI remains high, that is, there is no output in the SD (PULL UP)
After a first "dir" command there are a lot of MMCSD_PIN_SELECT and MMCSD_PIN_SCL pulses, for about 100us there are pulses on the MCSD_PIN_SDO output, then there is a wait of about 300us (there are still multiples of both pulses) until the SD starts to output through MCSD_PIN_SDO which lasts about 10ms.
After this, there are no more pulses of any kind with any command, although there is always a response from the UART:
Code: |
Error opening file: /Test1/
/> dir
--/--
/> cd "Test1"
Error changing directory
/>cat
Error opening file: /Test1/
/>cat
Error opening file: /Test1/
/> dir
--/--
/> md "Test1"
Unknown Command 'md'
/> cd dir Test1
Error changing directory
/>
|
Everything points to the fact that it is a problem of protocols |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Tue Mar 14, 2023 4:48 am |
|
|
'1' and '2' are the sequence to put the command into the idle state.
These should then be followed by another 8 pulses, with the bottom bit
SDI set. There should be a minimum of 32 clocks, and a couple of
commands sent. If SDO is not changing, the card is not responding.
mmcsd_init, does not really return TRUE/FALSE, it returns the value
from the card, which should be zero if there is a legitimate return. However
it can also be zero if SDO stays low. It sounds as if this is what is happening
for you.
What is the part number of your Olimex board?. I don't see one with that
processor on their site.
I see you say earlier it is the Penguin board. If you have the
dsPIC33EP256MU806 put into that board, then the SD card is connected
to SPI2, not SPI1!....
Look at the wiring diagrams. It shows MISO and MOSI going to pins 5 and
6 on the processor. These are the fixed SDI2 and SDO2 lines.
If this is the board, not surprising it doesn't work with SPI1.... |
|
![](templates/subSilver/images/spacer.gif) |
rufinopc@rufinogg.com
Joined: 11 Mar 2023 Posts: 17
|
|
Posted: Tue Mar 14, 2023 5:57 am |
|
|
I'll start at the end of your answer: It's actually OLIMEX PIC32-PINGUINO with a PIC32MX440F256H micro, but I replaced these boards with a PIC33EP256MU806 micro; their prints are identical. I have been using them for many applications, but it is the first time that I have used the SD (for them I have been using the Mega series)
As you know, these micros can have the connections of certain modules with different outputs altered, hence if you don't use the native connections you have to use the #pin_selectxxxx, #use(SPIxx.... ),etc.
However, I have changed it so that it works like SPI1 and it does exactly the same, that is, it works perfectly like SPI1 or SPI2.
In my opinion, the hardware is working perfectly, it is the software that is "stuck" somewhere due to so many conversions from 8-bit "int" to "int16", etc. The proof of this is that there are pulses of all kinds, another thing is that they are the right ones. I don't know how to include an image of the capture of the four signals... |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Tue Mar 14, 2023 7:59 am |
|
|
The point is that SPI2 is directly connected to those pins, so use it.
It is better in several ways. First supports higher speed. Second though
(and importantly here), not using pin_select allows the pins to still
function for standard I/O, which is needed during the setup.
However I've seen one more glaring problem. Get rid of your 'ENABLE'
setting in your SPI setup. This is wrong. The SD driver handles enable
itself. Doesn't want the peripheral to do this.
Just use:
Code: |
//remove these
//#pin_select SCK1OUT = MMCSD_PIN_SCL
//#pin_select SDI1 = MMCSD_PIN_SDI
//#pin_select SDO1 = MMCSD_PIN_SDO
#use spi(SPI2,MASTER,BITS=8,MODE=0,stream = mmcsd_spi, baud=400000)
|
Then just change speed to say 8000000 where the speed change
is needed in the init.
You have two separate things trying to control the enable..... |
|
![](templates/subSilver/images/spacer.gif) |
rufinopc@rufinogg.com
Joined: 11 Mar 2023 Posts: 17
|
|
Posted: Tue Mar 14, 2023 10:29 am |
|
|
As the oscilloscope signals were the same at all times, when I changed the oscilloscope sweep I realized that many milliseconds after the first MMCSD_PIN_SELECT there were more pulses, but since the distance to them was so great I couldn't expand the oscilloscope that much without lose them, so I ran the parser to see what was going on and looked at all the startup and response sequences to the "dir" command:
At the start SPI sends about 8 or 9 frames of 9 bits each in which only the first byte of each of them changes (0x40 in the first, 0x41 in the second, 0x77, 0x69, 0x6D... etc. ) and as a response from the SD it sends a byte in the eighth byte of each frame (it is usually 00 or 01)
The response to "dir" is more difficult to represent because there are many bytes, but among them you can see: "MSDOS 5.0".... "FAT32"..... "Disk error, press a key.... ..." etc.
With a second, third, etc. command no longer appears any pulse, although there is always a response by UART, as I said before.
All this indicates that the communications work perfectly, what happens is that there is a serious error in my software that I cannot detect.
However, as you advise me, I have changed the way of configuring the SPI (already SPI2) and there has been no change, it has behaved the same as described.
The only thing that I have not changed is the baud rate (on line 315 of the mmcsd.c) because if I increase the speed a lot I can lose capture data from the analyzer (On this computer and with three programs running it only reaches 8MS/a)
I'm a little lost and I don't know where to go... |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Wed Mar 15, 2023 1:54 am |
|
|
OK.
The long delay is correct, the init requires a 1mSec delay after select
on the first accesses.
If you are actually now talking to the card (the way to really test is
to do a byte read, rather than using FAT access), then your problem now
is almost certainly FAT. Which FAT driver are you using?. You need to be
using the version in the code library. How large is your card?. Key here is
that the original FAT driver handled FAT16 only. This was later modified
to handle FAT32, but still has a few issues, which handled the cards just
over 2GB. Then as SD card sizes grew, the format was changed to SDHC.
The supplied CCS driver has never handled these properly. The version in
the code library has about three sets of fixes implemented, to allow these
all to work.
It sounds now as if you probably do have a working SD interface, but just
not a working FAT driver for your card. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|