Shop OBEX P1 Docs P2 Docs Learn Events
Difference between simpletools.h SD card access and propgcc stdio.h implementation — Parallax Forums

Difference between simpletools.h SD card access and propgcc stdio.h implementation

trancefreaktrancefreak Posts: 186
edited 2014-02-20 14:47 in Propeller 1
I have an issue using the stdio.h implementation of propgcc for accessing a sd card.

I made a custom pcb board for my pinball project containing two propeller controller which communicate with each other and each controller has its own sd card, eeprom, flash and sram (flash currently not mounted).
Both controller have their own programming pin headers which can be connected to a prop plug.

All works well, programming hub ram directly, programming eeprom and executing XMMC mode from eeprom on both controllers.

But I have a problem accessing the SD card when using stdio.h. When using simpletools.h it works.
I use SimpleIDE version 0.9.45 (propgcc version propellergcc_v1_0_0_2162 which was in the SimpleIDE installer package).
When using simpletools.h, I can read/write to SD card in all modes (CMM, LMM, XMMC [eeprom]) but when I use stdio.h, access fails. When using stdio.h, I get the error message "File did not open."

The test code I'm using is as follows:
simpletools.h version
/*
  SD Minimal.side


  Create test.txt, write characters in, read back out, display. 
  
  http://learn.parallax.com/propeller-c-simple-devices/sd-card-data
*/


#include "simpletools.h"                      // Include simpletools header    


int DO = 10, CLK = 9, DI = 8, CS = 7;      // SD card pins
uint8_t videoBuffer[1024];


int main(void)                                // main function
{
  int a;
  for (a = 0; a < 1024; a++) {
    videoBuffer[a] = 65;
  }


  waitcnt(80000000 + CNT);
  print("Starting...");
  int erc = sd_mount(DO, CLK, DI, CS);                  // Mount SD card
  if (!erc) {
  FILE* fp = fopen("test.txt", "w");
  if(fp) {                                               // Good, continue
    fwrite(videoBuffer, 1, 1024, fp);  // Add contents to the file
    print("Buffer written...");
  } else {                                               // Bad, error message.
    printf("File did not open.\n");         
  }                                         


  fclose(fp);
  // Clearing videoBuffer
  for (a = 0; a < 1024; a++) {
    videoBuffer[a] = 0;
  }


  fp = fopen("test.txt", "r");
  if(fp)                                          // Nonzero file pinter?  
  {                                              // Good, continue.
    print("Start reading buffer...");
    int startCnt = CNT;
    fread(videoBuffer, 1, 512, fp);                           
    int endCnt = CNT;


    print("Read took ticks: %d", endCnt - startCnt);
    print("\n");                                    // With a newline at the end.
  }
    else                                            // Zero file pointer?
  {                                               // Bad, print error.
      printf("File did not open.\n");         
      printf("\n");
  }
    fclose(fp); 


  } else {
    print("Error mounting file system.");
  }
}

stdio.h version
/*
  SD with Tests.side


  SD Minimal modified so that it tests for drive and file before performing
  any read/write operations.  
  
  http://learn.parallax.com/propeller-c-simple-devices/sd-card-data
*/


#include <stdio.h>                            // Include simpletools header  
#include <stdint.h>   
#include <propeller.h>


int a;
int DO = 10, CLK = 9, DI = 8, CS = 7;            // SD card pins
uint8_t videoBuffer[1024];


int main(void)                                      // main function
{
  waitcnt(40000000 + CNT);
  //int erc = sd_mount(DO, CLK, DI, CS);              // Mount SD card
  int erc = 0;
  if(!erc)                                          // Error code = 0, good, continue
  {
    FILE* fp = fopen("test.txt", "w");              // Open a file for writing
    
    if(fp)                                          // Nonzero file pointer?  
    {                                               // Good, continue
      fwrite(videoBuffer, 1, 1024, fp);  // Add contents to the file
    }
    else                                            // Zero file pinter?
    {                                               // Bad, error message.
      printf("File did not open.\n");         
    }                                         
    fclose(fp);                                     // Close the file
  
    fp = fopen("test.txt", "r");                    // Reopen file for reading.
  
    uint8_t videoBuffer2[1024];                      // Buffer for characters.
  
    if(fp)                                          // Nonzero file pinter?  
    {                                               // Good, continue.
    int startCnt = CNT;
    fread(videoBuffer2, 1, 1024, fp);                           
    int endCnt = CNT;


    printf("Read took ticks: %d", endCnt - startCnt);
    printf("\n");                                    // With a newline at the end.
    }
    else                                            // Zero file pointer?
    {                                               // Bad, print error.
      printf("File did not open.\n");         
      printf("\n");
    }
    fclose(fp);                                     // Close the file.
  }
  else                                              // Mount error code not zero?
  {                                                 // Bad, display code
    printf("Error opening card.");
    printf("error code = %d\n", erc);
  }
}

Is there a known issue with regards to stdio.h and SD card or is there something I'm doing wrong?
I know when using stdio.h, I have to configure the SD pins in the board.cfg file which is selected in SimpleIDE. I made sure that the correct pins are configured.
The config looks as follows:
# pinballMCU.cfg
    clkfreq: 80000000
    clkmode: XTAL1+PLL16X
    baudrate: 115200
    rxpin: 31
    txpin: 30
    cache-driver: eeprom_cache.dat
    cache-size: 8K
    cache-param1: 0
    cache-param2: 0
    eeprom-first: TRUE
    sd-driver: sd_driver.dat
    sdspi-do: 10
    sdspi-clk: 9
    sdspi-di: 8
    sdspi-cs: 7

I really appreciate any input on what can cause the problem.

Christian

Comments

  • trancefreaktrancefreak Posts: 186
    edited 2014-02-16 05:14
    Sorry, I created the thread too fast.
    I forgot using the following when using stdio.h:
    extern _Driver _SimpleSerialDriver;
    extern _Driver _FileDriver;
    
    
    _Driver *_driverlist[] = {
      &_SimpleSerialDriver,
      &_FileDriver,
      NULL
    };
    

    When defining the drivers, the stdio.h version works in CMM mode. For LMM, the program gets too big and overflows hub by around 8k.
    I can remember I used stdio.h sd card access many month ago in LMM mode and code didn't overflow hub.

    Was there something changed that even such a "short" program will not fit into hub ram?

    Christian
  • jazzedjazzed Posts: 11,803
    edited 2014-02-16 08:49
    Use print or printf, not both. They are both pretty big. Better yet, use the smaller put utilities instead of print. putLine(), putStr(), putDec(), putHex(), putBin(). That way you get exactly what you need and nothing more. Just a warning here: using fprintf is essentially the same as using printf.
  • trancefreaktrancefreak Posts: 186
    edited 2014-02-19 15:31
    I have an issue with simpletools.h and SD card access. The program I have shown above (simpletools.h version) works when using CMM mode. When I switch to LMM mode, reads and writes do not work anymore. o_O

    As far as I know SD access is handled by an external driver which runs in a cog regardless of the selected memory model. So I hooked up a logic analyzer and saw, that in both memory models the CLK frequency to the SD card is 4 Mhz. So same speed if selecting CMM or LMM.

    Next I tried to get the stdio.h version below 32Kb by using the putStr and putDec functions instead of printf and that worked. The stdio.h version works in both modes CMM and LMM reliably.

    I'd prefer the simpletools.h version because code size is much smaller even when using SD access.
    Is there any known bug in the simpletools library? Because SD access speed is always the same by the "SD" cog, I think there might be a problem when handing over data from the program to the
    "SD" cog.

    Any ideas/help is appreciated. :-)

    Christian
  • trancefreaktrancefreak Posts: 186
    edited 2014-02-20 07:04
    Would be great if someone who has a board with sd card (or a parallax memory card, which also has a SD card connector) could execute the following code in LMM mode a few times and
    post if it works. I don't have luck using LMM mode, only CMM works.
    /*
      SD Minimal.side
    
    
      Create test.txt, write characters in, read back out, display. 
      
      http://learn.parallax.com/propeller-c-simple-devices/sd-card-data
    */
    
    
    #include "simpletools.h"                      // Include simpletools header    
    
    
    int DO = 10, CLK = 9, DI = 8, CS = 7;      // SD card pins
    uint8_t videoBuffer[1024];
    
    
    int main(void)                                // main function
    {
      int a;
      for (a = 0; a < 1024; a++) {
        videoBuffer[a] = 65;
      }
    
    
      waitcnt(80000000 + CNT);
      print("Starting...");
      int erc = sd_mount(DO, CLK, DI, CS);                  // Mount SD card
      if (!erc) {
      FILE* fp = fopen("test.txt", "w");
      if(fp) {                                               // Good, continue
        fwrite(videoBuffer, 1, 1024, fp);  // Add contents to the file
        print("Buffer written...");
      } else {                                               // Bad, error message.
        printf("File did not open.\n");         
      }                                         
    
    
      fclose(fp);
      // Clearing videoBuffer
      for (a = 0; a < 1024; a++) {
        videoBuffer[a] = 0;
      }
    
    
      fp = fopen("test.txt", "r");
      if(fp)                                          // Nonzero file pinter?  
      {                                              // Good, continue.
        print("Start reading buffer...");
        int startCnt = CNT;
        fread(videoBuffer, 1, 512, fp);                           
        int endCnt = CNT;
    
    
        print("Read took ticks: %d", endCnt - startCnt);
        print("\n");                                    // With a newline at the end.
      }
        else                                            // Zero file pointer?
      {                                               // Bad, print error.
          printf("File did not open.\n");         
          printf("\n");
      }
        fclose(fp); 
    
    
      } else {
        print("Error mounting file system.");
      }
    }
    
  • jazzedjazzed Posts: 11,803
    edited 2014-02-20 10:53
    I don't have the PMC at this moment, but I do have an activityboard. No problems with CMM or LMM.
    // Defines for activityboard.
    
    #define  DO 22
    #define  CLK 23
    #define  DI 24
    #define  CS 25
    
    //int DO = 10, CLK = 9, DI = 8, CS = 7;      // SD card pins
    
    CMM Starting...Buffer written...Start reading buffer...Read took ticks: 169104
    LMM Starting...Buffer written...Start reading buffer...Read took ticks: 145824
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-02-20 11:04
    It seems to work on the GG PPUSB, in both modes.

    Ray
    // Defines for Gadget Gangster PPUSB
    int DO = 0, CLK = 1, DI = 2, CS = 3;      // SD card pins
    
    LMM Starting...Buffer written...Start reading buffer...Read took ticks: 132160
    CMM Starting...Buffer written...Start reading buffer...Read took ticks: 152192
    
  • edited 2014-02-20 11:15
    No problems with either memory model on Activity Board, but there's only a few hundred bytes left in LMM. Following Steve's recommendation to replace print with putStr and putDec reduced program size by 5 KB in LMM.
    /*
      SD Minimal (Modified).side
    
      Create test.txt, write characters in, read back out, display. 
      
      http://learn.parallax.com/propeller-c-simple-devices/sd-card-data
    */
    
    
    #include "simpletools.h"                      // Include simpletools header    
    
    
    int DO = 22, CLK = 23, DI = 24, CS = 25;      // SD card pins
    uint8_t videoBuffer[1024];
    
    
    int main(void)                                // main function
    {
      int a;
      for (a = 0; a < 1024; a++) {
        videoBuffer[a] = 65;
      }
    
    
      waitcnt(80000000 + CNT);
      putStr("Starting...");
      int erc = sd_mount(DO, CLK, DI, CS);        // Mount SD card
      if (!erc) {
      FILE* fp = fopen("test.txt", "w");
      if(fp) {                                    // Good, continue
        fwrite(videoBuffer, 1, 1024, fp);         // Add contents to the file
        putStr("Buffer written...");
      } else {                                    // Bad, error message.
        putStr("File did not open.\n");         
      }                                         
    
    
      fclose(fp);
      // Clearing videoBuffer
      for (a = 0; a < 1024; a++) {
        videoBuffer[a] = 0;
      }
    
    
      fp = fopen("test.txt", "r");
      if(fp)                                      // Nonzero file pinter?  
      {                                           // Good, continue.
        putStr("Start reading buffer...");
        int startCnt = CNT;
        fread(videoBuffer, 1, 512, fp);                           
        int endCnt = CNT;
    
    
        putStr("Read took ticks: ");
        putDec(endCnt - startCnt);
        putStr("\n");                             // With a newline at the end.
      }
        else                                      // Zero file pointer?
      {                                           // Bad, putStr error.
          putStr("File did not open.\n");         
          putStr("\n");
      }
        fclose(fp); 
    
    
      } else {
        putStr("Error mounting file system.");
      }
    }
    
  • jazzedjazzed Posts: 11,803
    edited 2014-02-20 11:30
    No problems with either memory model on Activity Board, but there's only a few hundred bytes left in LMM. Following Steve's recommendation to replace print with putStr and putDec reduced program size by 5 KB in LMM.
    Thanks for noticing that. Exhausting memory certainly can cause issues.

    These lines are equivalent.

    putStr("hello\n");
    putLine("hello");
  • trancefreaktrancefreak Posts: 186
    edited 2014-02-20 12:24
    Hmmm... that's interesting. I can't get it to work in LMM mode, only CMM on the quickstart + PMC and my self designed board + PMC.
    The signals to the PMC SD card connector have the same CLK frequency, so I don't think it's a communication timing issue.

    Were there any changes recently in the simpletools library regarding SD access I might not have? (Because it works well with propgcc stdio impl.)
  • jazzedjazzed Posts: 11,803
    edited 2014-02-20 12:29
    Hmmm... that's interesting. I can't get it to work in LMM mode, only CMM on the quickstart + PMC and my self designed board + PMC.
    The signals to the PMC SD card connector have the same CLK frequency, so I don't think it's a communication timing issue.

    Were there any changes recently in the simpletools library I regarding SD access I might not have?

    Try it on a different board if possible just as a test ... preferably not a Quickstart ........
  • trancefreaktrancefreak Posts: 186
    edited 2014-02-20 13:06
    I only have the quickstart and a board with two propellers I designed by myself. Both behave the same with simpletools. When using stdio implementation, it works in LMM. I could live with that but I wanna know what is causing the trouble.
    Any ideas what I can check? I have a scope and logic analyzer.
  • jazzedjazzed Posts: 11,803
    edited 2014-02-20 13:30
    I only have the quickstart and a board with two propellers I designed by myself. Both behave the same with simpletools. When using stdio implementation, it works in LMM. I could live with that but I wanna know what is causing the trouble.
    Any ideas what I can check? I have a scope and logic analyzer.

    Quickstart is a noisy board ... the board that keeps on giving :) ... giving me headaches.

    One thing to try is to choose GENERIC as the board type instead of PMC. I ran into some interference with the "automatic" aspect of the underlying implementation. The other alternative is just to leave out sd_mount() all-together.

    BTW, If you put your probe on a pin and suddenly everything starts working that is an indication of a hardware problem.
  • trancefreaktrancefreak Posts: 186
    edited 2014-02-20 13:36
    jazzed wrote: »
    Quickstart is a noisy board ... the board that keeps on giving :) ... giving me headaches.

    One thing to try is to choose GENERIC as the board type instead of PMC. I ran into some interference with the "automatic" aspect of the underlying implementation. The other alternative is just to leave out sd_mount() all-together.

    BTW, If you put your probe on a pin and suddenly everything starts working that is an indication of a hardware problem.

    Thanks for your input! :-)
    I´ll try out the GENERIC board type.

    It doesn't make a difference if I attach a probe or not. It does not work in LMM. I will also try to leave out the sd_mount line... Do I have to include the drivers the same way as I would use stdio when I leave out the sd_mount line?
  • trancefreaktrancefreak Posts: 186
    edited 2014-02-20 13:42
    Using GENERIC as board type didn't solve the issue. When I remove the sd_mount line it works (but then I'm again using more or less the propgcc version ;-)
    So it's interesting, that using another mount routine solves the issue. Does the propgcc implementation initialize the sd card in another way than the simpletools mount routine?
  • jazzedjazzed Posts: 11,803
    edited 2014-02-20 14:15
    Using GENERIC as board type didn't solve the issue. When I remove the sd_mount line it works (but then I'm again using more or less the propgcc version ;-)
    So it's interesting, that using another mount routine solves the issue. Does the propgcc implementation initialize the sd card in another way than the simpletools mount routine?
    Simple Libraries uses the propgcc version too - nothing wrong with that.

    You don't need sd_mount(). It's just syntax sugar. The only time I've ever had a problems with sd_mount() is if I use a board-type that already has some SD card configuration that is in conflict with the parameters I pass to sd_mount().

    If you have the right board-type, and add the driver struct like below, you get what you need (you don't really even need the mount() function in that code ... it's just a way for me to test with GENERIC).

    The only issue with the driver struct is the serial driver needs to be replaced with _NullDriver so that only the simpletools stuff gets used without interference from the stdio serial driver.

    I'd like to see the root cause of your problem, but I can't really duplicate it. Try this code for mounting with GENERIC board type and let me know if it works. Remove the mount() call if you use the PMC board type.

    /**
     * Copyright (c) 2014 by Steve Denson. All rights MIT licensed.
     * This is the main wavtest program file.
     */
    #include "simpletools.h"
    
    // your pin defs here
    #define  _MISO 22
    #define  _SCLK 23
    #define  _MOSI 24
    #define  _CSEL 25
    
    extern _Driver _SimpleSerialDriver;
    extern _Driver _FileDriver;
    extern _Driver _NullDriver; 
    
    /* Driver list */
    _Driver *_driverlist[] = {
        &_NullDriver,
        //&_SimpleSerialDriver,
        &_FileDriver,
        NULL
    };
    
    
    /*
     * mount sdcard if it is not mounted.
     */
    void mount(void)
    {
        extern int dfs_mountflag;
    
    
        _SD_Params sdspi;
        sdspi.AttachmentType = _SDA_SingleSPI;
        sdspi.pins.SingleSPI.CLK  = _SCLK;
        sdspi.pins.SingleSPI.MISO = _MISO;
        sdspi.pins.SingleSPI.MOSI = _MOSI;
        sdspi.pins.SingleSPI.CS   = _CSEL;
    
    
        if(!dfs_mountflag)
            dfs_mount(&sdspi);
    }
    
    
    int main(void)
    {
    mount(); // Mount SD card
    
    
    /// your code here ....
    
    return 0;
    }
    
    
    
  • trancefreaktrancefreak Posts: 186
    edited 2014-02-20 14:47
    Thanks for your support, Steve! Your code works well when using LMM.
    If I select GENERIC board type, I have to use the mount() call. If I use the board type I made for my own board (same as quickstart, but SD pins adapted), it also works and I can remove the mount() call.

    So I have no issue. Why do I have a problem when I directly use the simpletools version without the mount() code in the main program? Does this make sense?
Sign In or Register to comment.