Shop OBEX P1 Docs P2 Docs Learn Events
uSD Drivers FSRW and FAT32, both using same low level SPI drivers — Parallax Forums

uSD Drivers FSRW and FAT32, both using same low level SPI drivers

RaymanRayman Posts: 14,754
edited 2023-12-20 22:00 in Propeller 2

Here two uSD drivers that can both use your choice of three low level drivers.
One is inline assembly and doesn't need a cog, one uses a cog, and the other also uses a cog but adds audio output.

FSRW is a very minimalistic with only root directory access
FAT32 has more features and can access sub-directories

Tested with Propeller Tool 2.9.3

@Wuerfel_21 connected the low level driver from P2 version of FSRW to FAT32, also added the audio version..
FSRW was then modified a hair to also use the same low level drivers.

There's been a history of FSRW becoming broken by compiler changes, but I think it's OK now.
But, there's only been limited testing so far.

Attached are simple tests of both drivers.

Note: Small change made to FAT32 as suggested by @Wuerfel_21
Also made change suggested by @ke4pjw

Update: See post #23 for updated version of bashed with better release() so that can close one file and open another...

«1

Comments

  • Thanks for putting this state of play summary and code together Rayman. I've always been a bit apprehensive as to finding out which P2 SD code currently works properly and what doesn't etc and have been wondering where to look to get something that actually does work. This post might be my go to resource now with any luck.

  • Quality.

  • Actually, you should probably change

    PUB readSkipBytes(count) : result
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Reads data from the file that is currently open and advances the file position by that amount of data.
    '' //
    '' // Returns the amount of data read from the disk. Reads nothing when at the end of a file.
    '' //
    '' // This method will do nothing if a file is not currently open for reading or writing.
    '' //
    '' // If an error occurs this method will abort and return a pointer to a string describing that error.
    '' //
    '' // Count - The amount of data to read from disk.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      result~
      repeat while count >= 32768
        result := readData( $8000, 32768 )               ' read into hub ROM space          ???????????????????????????????????????
        count -= 32768
      result += readData ( $8000, count )                ' read into hub ROM space          ???????????????????????????????????????
    

    to

    PUB readSkipBytes(count) : result
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Reads data from the file that is currently open and advances the file position by that amount of data.
    '' //
    '' // Returns the amount of data read from the disk. Reads nothing when at the end of a file.
    '' //
    '' // This method will do nothing if a file is not currently open for reading or writing.
    '' //
    '' // If an error occurs this method will abort and return a pointer to a string describing that error.
    '' //
    '' // Count - The amount of data to read from disk.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      result~
      repeat while count >= 32768
        result := readData( $80000, 32768 )               ' read into unmapped space          ???????????????????????????????????????
        count -= 32768
      result += readData ( $80000, count )                ' read into unmapped space          ???????????????????????????????????????
    

    There's a more correct fix for this but that'd take effort.

  • RaymanRayman Posts: 14,754

    Thanks @Wuerfel_21 , that does look dangerous!

  • RaymanRayman Posts: 14,754
    edited 2023-06-03 21:28

    Here's a test for both that adds a VGA driver.
    It reads BMP image from uSD card and displays using VGA.

    You must have the file, bitmap2.bmp, on your uSD card.

    Note: Updated these as well as described in top post.

  • Can I humbly suggest changing sdspi_with_audio to include mountCard() to the stop method? If it is not there, you will not be able to reboot the P2 Edge properly. You won't be able to reboot the Edge arbitrarily anyway, but if you are performing a software reboot, mountCard() sends the SD Card init, which will allow you to reboot.

    PUB Stop()
        if cog
           mountCard()
           cogstop(cog-1)
    
        cog := 0
    

    This is a software fix for the fact that the SD Card is not power cycled in a reset condition on the Edge.

    There is another bug in FAT32, where once you change out of the root directly, you can't change back to the root. (Can't remember if it was using ".." or changing back to "/" ) I fixed it in my code. I will need to diff it to find it.

  • RaymanRayman Posts: 14,754

    Thanks @ke4pjw , I know you looked at this a lot. Is it just the "with_audio" that needs this?

  • @rayman I would think they all need it, but that is the only one I have tested.

  • RaymanRayman Posts: 14,754

    @ke4pjw Ok, things still seem to work with that in all the drivers. I've updated all the zips.

  • RaymanRayman Posts: 14,754

    @Wuerfel_21 Do you have an example or notes on how one can play a 16-bit PCM stereo (or mono) .wav file using your version of the driver?

    I almost have my .wav player working again, but seems silly to use two cogs when you have it integrated into one...

  • Wuerfel_21Wuerfel_21 Posts: 5,106
    edited 2023-06-04 21:36

    It's pretty much a carbon copy of what tinySDDA does on P1 except less ridiculously crammed into one cog's cog RAM. Look up that: https://forums.parallax.com/discussion/171949/tinysdda-v1-0-sdcard-sector-r-w-stereo-music-sound-effects-in-one-cog-and-almost-no-hub-ram

    In short:
    - Can play both stereo 16bit and mono A-law at the same time with looping
    - Files need to be non-fragmented raw data (A WAV header may not cause too great a disturbance, but really, just use raw files)

    The reason why it is this way is because I wanted a non-stupid way to port Spin Hexagon, which uses TinySDDA on P1.

  • @Rayman said:
    Here two uSD drivers that can both use your choice of three low level drivers.
    One is inline assembly and doesn't need a cog, one uses a cog, and the other also uses a cog but adds audio output.

    FSRW is a very minimalistic with only root directory access
    FAT32 has more features and can access sub-directories

    Tested with Propeller Tool 2.9.3

    @Wuerfel_21 connected the low level driver from P2 version of FSRW to FAT32, also added the audio version..
    FSRW was then modified a hair to also use the same low level drivers.

    There's been a history of FSRW becoming broken by compiler changes, but I think it's OK now.
    But, there's only been limited testing so far.

    Attached are simple tests of both drivers.

    Note: Small change made to FAT32 as suggested by @Wuerfel_21
    Also made change suggested by @ke4pjw

    Thanks for the taking the time @Rayman ! When I get back home I'll play a bit with this and @ke4pjw files.

  • I've been struggling with FSRW on the P2. Reading from a simple text file sometimes works, sometimes it says the file can't be opened -- even though the file shows up in the directory listing.

    I've also noticed that with Ray's test code and mine (which is based on his), the file write never works -- it only ever creates an empty file.

    I have run the code in the Eval uSD, in a Parallax uSD adaptor, and in my own (which has a PFET for switching power to the uSD) -- the behavior is the same in all.

  • Try using the _with_audio SPI code. I definitely remember fixing an issue where writes would fail like that, maybe the regular one hasn't ever had that backported to it.

  • I'll try, but would prefer an atomic object -- I don't like the idea of putting audio into the SD object (even though there is a relationship).

  • Wuerfel_21Wuerfel_21 Posts: 5,106
    edited 2023-10-30 11:51

    It's just a normal SD driver with some extra features stuffed in (that do nothing by default) - point is I know that one works and I think the other guy with the light controller also started with it and it worked for him.

    (Though the reason it exists is because the SD driver is arguably the one correct place to put audio streaming if you want to keep other cogs free of having to babysit it - though on P2 the need for a dedicated SD/SPI cog is questionable. Could probably do a PSRAM+SD+Audio combined monster thing if I wanted)

  • RaymanRayman Posts: 14,754

    It's not entirely my code, but I guess I'll take blame as latest maintainer of it.
    I'm sure I checked it all out, but there are a lot of versions floating around and many are broke by compiler and other changes.
    I'll look into this right now.

  • RaymanRayman Posts: 14,754

    I just checked my first test file and it appears to be working. It creates speed.txt and seems to write and read from it.

    @JonnyMac Can you try this? The notes need updating, and I'm not sure it's the latest. But, seems to work at least.

  • RaymanRayman Posts: 14,754
    edited 2023-10-30 15:21

    This is, it appears, is the most recent version. Just hacked to do a write test and seems to work.

  • I just checked my first test file and it appears to be working. It creates speed.txt and seems to write and read from it.> @Rayman said:
    I just checked my first test file and it appears to be working. It creates speed.txt and seems to write and read from it.

    @JonnyMac Can you try this? The notes need updating, and I'm not sure it's the latest. But, seems to work at least.

    This version seems to work. Thank you.

  • RaymanRayman Posts: 14,754

    Think found the problem with "sdspi_bashed2.spin2" version of low level driver...
    The "release" function was not good enough to close a file so another could be opened.

    Copied the release code from "sdspi_with_audio.spin2" and seems all better now.

  • RaymanRayman Posts: 14,754

    Just tested all the versions with a slideshow program that reads from 4 different bmp files continuously.
    All the low level drivers work now. Also, commented out the debug statements in low level drivers so can use Prop Tool debug window as serial terminal...

  • RaymanRayman Posts: 14,754

    Ok, I was just testing another slideshow app, this one for PSRAM, and ran into an issue where it refused to open the second image in the slideshow.
    This was with the "bashed", coggless, version.

    Just figured out that, for some reason, have to try to open twice to make it work, like this:

        'Load bmp file
        ser.PrintLn(@"Opening BMP file...")
        ser.str(p)
        ser.crlf()
        repeat  2
          i:=sd.popen(p,"r")
          if i>=0
            quit
          waitms(100)
    

    The cogged version were also not working, but that was because I was overriding the cog it was using with the PSRAM driver :(.
    So, this issue may be limited to the Bashed version.

    Anyway, if anyone is having trouble with the bashed (like @JonnyMac seemed to have had), try the above open loop.
    Guess should add something like this to the driver itself to avoid this.
    Not sure why I haven't seen this issue before...

  • RaymanRayman Posts: 14,754

    Just tried to add the above to OBEX, but OBEX won't let me log in.
    Made a new account there though and should be able to post it Monday probably.

    Was just looking around and this 20Dec23 version is probably the latest.

  • ke4pjwke4pjw Posts: 1,169

    @Rayman I would check your email (and spam box). For some reason, OBEX and the Parallax site won't allow you to login and won't tell you why. When you check your email it tells you why. Usually the account has become inactive.

    Side Rant: The information security "best practice" of not telling the user why they can't login is bogus. If a bad actor wants to brute force an account, it is easily recognizable in the logs and they should be thrown in a tar pit to slow them down, or blocked outright.

  • RaymanRayman Posts: 14,754

    My old account works again, just uploaded this to OBEX.

    New account still doesn't have upload access, but guess OK now.

  • Hadn’t spotted this before.

    The old account was temporarily locked after X incorrect passwords. Clears itself after 30 mins or so. Will check and see about increasing the allowed password fails before locking, and what the messaging is supposed to look like.

    Glad you are reconnected anyway. Feel free to pm me or email support for immediate attention on these things.

    I will be working on general OBEX improvements soon too. Will be sure to look at Membership flow and clarity on fail, and feel free to suggest anything on a new thread or pm.

  • RaymanRayman Posts: 14,754

    I guess what was surprising is that did password reset (twice) and still wouldn't let me in with old account...

  • RaymanRayman Posts: 14,754

    @JonnyMac had a suggestion about the return value for mount_explicit(). Have to remember to update that next time working on that code...

  • JonnyMacJonnyMac Posts: 9,159

Sign In or Register to comment.