| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| rufinopc@rufinogg.com 
 
 
 Joined: 11 Mar 2023
 Posts: 20
 
 
 
			    
 
 | 
			
				| 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:
 
 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) 	  | 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)
 
 | 
 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;
 }
 }
 }
 }
 
 | 
 |  |  
		|  |  
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9588
 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 ??
 |  |  
		|  |  
		| rufinopc@rufinogg.com 
 
 
 Joined: 11 Mar 2023
 Posts: 20
 
 
 
			    
 
 | 
			
				|  |  
				|  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
 |  |  
		|  |  
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9588
 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 ??
 |  |  
		|  |  
		| rufinopc@rufinogg.com 
 
 
 Joined: 11 Mar 2023
 Posts: 20
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Mar 13, 2023 10:52 am |   |  
				| 
 |  
				| I'm trying Thank you so much
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  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.
 |  |  
		|  |  
		| rufinopc@rufinogg.com 
 
 
 Joined: 11 Mar 2023
 Posts: 20
 
 
 
			    
 
 | 
			
				|  |  
				|  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
 
 --/--
 />
 | 
 |  |  
		|  |  
		| rufinopc@rufinogg.com 
 
 
 Joined: 11 Mar 2023
 Posts: 20
 
 
 
			    
 
 | 
			
				|  |  
				|  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.
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  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.
 |  |  
		|  |  
		| rufinopc@rufinogg.com 
 
 
 Joined: 11 Mar 2023
 Posts: 20
 
 
 
			    
 
 | 
			
				|  |  
				|  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
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  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....
 |  |  
		|  |  
		| rufinopc@rufinogg.com 
 
 
 Joined: 11 Mar 2023
 Posts: 20
 
 
 
			    
 
 | 
			
				|  |  
				|  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...
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  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.....
 |  |  
		|  |  
		| rufinopc@rufinogg.com 
 
 
 Joined: 11 Mar 2023
 Posts: 20
 
 
 
			    
 
 | 
			
				|  |  
				|  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...
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  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.
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |