Shop OBEX P1 Docs P2 Docs Learn Events
Anyone got a version of FSRW that _doesnt_ erase the card when trying to create a file? — Parallax Forums

Anyone got a version of FSRW that _doesnt_ erase the card when trying to create a file?

Uh yes, title. Does anyone have one or is willing to debug the one I got?

This particular one I got seems to have been tinkered on by @Rayman and @"David B" before.

Note that I added some audio features to the block layer, but that is not where the problem lies (the audio stuff does work BTW, see included sddatest.spin2, grab the referenced files from Spin Hexagon if you want to try that)

Comments

  • Cluso99Cluso99 Posts: 18,069

    Here is my SD and FAT32 code.
    https://forums.parallax.com/discussion/171642/p2-sd-drivers-cog-pasm-version-v-223/p1?new=1

    I haven't managed to get the two programs (the SD driver and the FAT32 which I converted from Kye's FAT Engine plus mods) to work nicely with other spin code :(
    I have had a few attempts and I think it's because of buffer pointers not playing nicely when spin is introduced to the mix. But I keep getting distracted from debugging it :(

  • pik33pik33 Posts: 2,366

    The basics.
    (1) Init a card and read a sector. This should be in the boot rom: is there any possibility of calling these procedures after boot?
    (2) Write a sector. This is not needed for booting.|
    (3) Build a filesystem driver around this. There was good old KyeFAT

    I need a SD driver too. As I used KyeFAT and even added LFN to it, this is the most natural way: try and translate it to P2.

    Where to find the best procedures for: init a card (ROM?), read a sector (ROM?) and write a sector (?) ?

  • Cluso99Cluso99 Posts: 18,069

    @pik33 said:
    The basics.
    (1) Init a card and read a sector. This should be in the boot rom: is there any possibility of calling these procedures after boot?
    (2) Write a sector. This is not needed for booting.|
    (3) Build a filesystem driver around this. There was good old KyeFAT

    I need a SD driver too. As I used KyeFAT and even added LFN to it, this is the most natural way: try and translate it to P2.

    Where to find the best procedures for: init a card (ROM?), read a sector (ROM?) and write a sector (?) ?

    The boot ROM is not going to change! It's not a mask!

    The boot ROM is limited in size so it wasn't possible to fit everything in. What we have is what we have. Also there was very limited time to add what we have.
    The SD and Print/Serial/Monitor/Debugger are callable from your own programs. But SPIN2 now clobbers the ROM (ie the RAM copy in hub $FC000-$FFFFF) so it's basically unusable from anything other than pure pasm, and I wrote a lot of code using this before spin obsoleted it all.

    Did you look at the code I posted on the above linked thread?
    My SD Driver and Kye's FAT converted do everything except LFN. But I've not totally debugged Kye's FAT32 in spin2. I believe I have a pointer bug in Kye's code conversion. The SD driver is self-contained pasm in cog/lut.

  • And of course if you're willing to use C or BASIC then FlexProp has file system code built in for both languages. You can even use the same functions to read data over serial from the host PC.

  • @ersmith said:
    And of course if you're willing to use C or BASIC then FlexProp has file system code built in for both languages. You can even use the same functions to read data over serial from the host PC.

    Problem is I need it to use a separate SD DMA cog, so it can play audio in the background. Can you do that with the flexprop FS code? (that is, hook it up to a set of read block / write block functions)

  • @Wuerfel_21 said:

    @ersmith said:
    And of course if you're willing to use C or BASIC then FlexProp has file system code built in for both languages. You can even use the same functions to read data over serial from the host PC.

    Problem is I need it to use a separate SD DMA cog, so it can play audio in the background. Can you do that with the flexprop FS code? (that is, hook it up to a set of read block / write block functions)

    Hmmm... it's not designed to do that, but on the other hand I don't think anything would stop it from running in another COG (using cogstart() in C or CPU in BASIC). The code isn't really designed for re-entrancy so there could be problems if more than one COG is using the file system.

    The performance of the file system code is mediocre right now, with reading 100K taking about 355 milliseconds

  • @ersmith said:

    Hmmm... it's not designed to do that, but on the other hand I don't think anything would stop it from running in another COG (using cogstart() in C or CPU in BASIC). The code isn't really designed for re-entrancy so there could be problems if more than one COG is using the file system.

    Yah, that would definitely be a problem. The SD cog also needs to service interrupts from the DAC pins and I don't think flexspin likes interrupts on a high-level language cog, right?

  • @Wuerfel_21 said:

    @ersmith said:

    Hmmm... it's not designed to do that, but on the other hand I don't think anything would stop it from running in another COG (using cogstart() in C or CPU in BASIC). The code isn't really designed for re-entrancy so there could be problems if more than one COG is using the file system.

    Yah, that would definitely be a problem. The SD cog also needs to service interrupts from the DAC pins and I don't think flexspin likes interrupts on a high-level language cog, right?

    Right, you'd have to re-structure things so the DAC interrupts are in another COG. Probably more trouble than it's worth, unless you can't find FSRW code that works.

  • Actually, I think I made my FSRW code work. Defo needs more testing though.

  • I just changed line 788 to always set dir32 to zero.That was the main difference between the FSRW you posted and the one I have. I think the point of that is to make it work with larger directories, so maybe that now doesn't work anymore

  • RaymanRayman Posts: 14,640

    Been a while since I looked at FSRW...
    Last one I used seems to be in post#13 here:
    https://forums.parallax.com/discussion/comment/1504883#Comment_1504883
    Haven't seen it erase SD cards before...

    I've been spoiled by FatFs in Fastspin...

  • Cluso99Cluso99 Posts: 18,069

    @Wuerfel_21 said:

    @ersmith said:

    Hmmm... it's not designed to do that, but on the other hand I don't think anything would stop it from running in another COG (using cogstart() in C or CPU in BASIC). The code isn't really designed for re-entrancy so there could be problems if more than one COG is using the file system.

    Yah, that would definitely be a problem. The SD cog also needs to service interrupts from the DAC pins and I don't think flexspin likes interrupts on a high-level language cog, right?

    I'm not understanding. If you just want to read SD files (8+3 filenames) using a single dedicated cog, which can also locate and load FAT32 files (from the root directory), then you would only need my SD pasm driver. You would not need Kye's FAT32 or FSRW.
    Am I missing something here?

  • @Cluso99 said:

    @Wuerfel_21 said:

    @ersmith said:

    Hmmm... it's not designed to do that, but on the other hand I don't think anything would stop it from running in another COG (using cogstart() in C or CPU in BASIC). The code isn't really designed for re-entrancy so there could be problems if more than one COG is using the file system.

    Yah, that would definitely be a problem. The SD cog also needs to service interrupts from the DAC pins and I don't think flexspin likes interrupts on a high-level language cog, right?

    I'm not understanding. If you just want to read SD files (8+3 filenames) using a single dedicated cog, which can also locate and load FAT32 files (from the root directory), then you would only need my SD pasm driver. You would not need Kye's FAT32 or FSRW.
    Am I missing something here?

    Well, this is for Spin Hexagon, so it needs to
    - Get sector address of files in the root directory
    - Sometimes, create files in the root directory
    - read and write to SD sectors
    - Play audio from the SD card

    I had the audio sorted out already, but then I tried implementing the file creation stuff and it didn't work.

    Eitherhow, I got it sortof working now, I think. The SD cog code is all fine (and I think it's actually based on yours?), the FSRW FAT layer is just jank. I think I'll try to see if I can get your KyeFAT going instead, that might be more stable.

  • I know there are various bits and pieces of SD driver code lying about that may partially work or still have bugs etc but I really like the idea of an SD/FAT32 driver COG that can be used to serve files, or SD sectors to various requesting COGs via mailboxes. Somewhat like my memory driver, but a COG would request either a file and offset and transfer length etc, (or raw SD sector) and give it a buffer so the SD COG could go off and read/write the item in the background. This could let different COGs share the underlying media (with protection where required), and would suit streaming media applications running in parallel with other code loaders transferring executables and other resources. The requesting COG could either block or periodically poll for the transfer result, or alternatively request to be notified with COGATN. This would allow DMA type flexibility and the calling COG would not have to be too aware of the filesystem format either,it just uses simple file buffer areas. The FAT32 structure would be done by the SD COG as well.

    I realise that not all applications would like to dedicate a COG for this purpose, so perhaps those that don't could default to executing the transfer code inline and simply block for the result. It would be great if a driver COG could be developed with this type of behaviour and could suit both application types. If it did and was rock solid I think it could become the defacto SD driver for P2.

  • Cluso99Cluso99 Posts: 18,069

    @Wuerfel_21 said:

    @Cluso99 said:

    @Wuerfel_21 said:

    @ersmith said:

    Hmmm... it's not designed to do that, but on the other hand I don't think anything would stop it from running in another COG (using cogstart() in C or CPU in BASIC). The code isn't really designed for re-entrancy so there could be problems if more than one COG is using the file system.

    Yah, that would definitely be a problem. The SD cog also needs to service interrupts from the DAC pins and I don't think flexspin likes interrupts on a high-level language cog, right?

    I'm not understanding. If you just want to read SD files (8+3 filenames) using a single dedicated cog, which can also locate and load FAT32 files (from the root directory), then you would only need my SD pasm driver. You would not need Kye's FAT32 or FSRW.
    Am I missing something here?

    Well, this is for Spin Hexagon, so it needs to
    - Get sector address of files in the root directory
    - Sometimes, create files in the root directory
    - read and write to SD sectors
    - Play audio from the SD card

    I had the audio sorted out already, but then I tried implementing the file creation stuff and it didn't work.

    Eitherhow, I got it sortof working now, I think. The SD cog code is all fine (and I think it's actually based on yours?), the FSRW FAT layer is just jank. I think I'll try to see if I can get your KyeFAT going instead, that might be more stable.

    The only part the SD Driver cannot do alone is to write a file. It can do everything else, so you only need add the part from Kye's FAT32 (which I have converted) that can create a file.

    I can email you the code that fails too if you want to try and locate the problem as I'm on something else P2 right now.

  • Cluso99Cluso99 Posts: 18,069

    @rogloh said:
    I know there are various bits and pieces of SD driver code lying about that may partially work or still have bugs etc but I really like the idea of an SD/FAT32 driver COG that can be used to serve files, or SD sectors to various requesting COGs via mailboxes. Somewhat like my memory driver, but a COG would request either a file and offset and transfer length etc, (or raw SD sector) and give it a buffer so the SD COG could go off and read/write the item in the background. This could let different COGs share the underlying media (with protection where required), and would suit streaming media applications running in parallel with other code loaders transferring executables and other resources. The requesting COG could either block or periodically poll for the transfer result, or alternatively request to be notified with COGATN. This would allow DMA type flexibility and the calling COG would not have to be too aware of the filesystem format either,it just uses simple file buffer areas. The FAT32 structure would be done by the SD COG as well.

    I realise that not all applications would like to dedicate a COG for this purpose, so perhaps those that don't could default to executing the transfer code inline and simply block for the result. It would be great if a driver COG could be developed with this type of behaviour and could suit both application types. If it did and was rock solid I think it could become the defacto SD driver for P2.

    My SD Driver (which fully works) uses a hub 4 long buffer for control. It's totall cog/lut resident and does everything you're suggesting with perhaps the exception of actually downloading a file to a specific hub location. I cannot recall if it's complete and tested yet. It will locate the file and returns both sector and size for an 8+3 given filename. The "other" cog(s) use the 4 long control buffer but the driver could easily be modified to create COGATN too.

    At one time I had the intention to add the FAT32 spin code into the COG but I think that's unlikely now.

    This is the interface

    '+-----------------------------------------------------------------------------+
    '+ Wait for something to do (via mailbox)                                      +
    '+-----------------------------------------------------------------------------+
    mainloop    wrbyte  #0,         PTRA[m_cmd]     ' clear ##mbox_command (after status updated)
    wait        rdbyte  sdx_status, PTRA[m_cmd] wz  ' get   ##mbox_command I/R/W/F/X
        if_z    jmp     #wait
               '+------------------------------------------------------------------+
                rdlong  sdx_bufad,  PTRA[m_bufad]   ' collect buffer address from ##mbox_bufad
                rdlong  sdx_sector, PTRA[m_sector]  ' collect sector address from ##mbox_sector
               '+------------------------------------------------------------------+
                cmp     sdx_status, #"I"        wz  ' I = initialise?
        if_e    jmp     #cmd_I
                cmp     sdx_status, #"R"        wz  ' R = readFastSector
        if_e    jmp     #cmd_R
                cmp     sdx_status, #"W"        wz  ' W = writeFastSector
        if_e    jmp     #cmd_W
                cmp     sdx_status, #"D"        wz  ' D = find Directory
        if_e    jmp     #cmd_D
                cmp     sdx_status, #"F"        wz  ' F = findFile
        if_e    jmp     #cmd_F
                cmp     sdx_status, #"X"        wz  ' X = Load/Execute (usually after "F")
        if_e    jmp     #cmd_X
    done
        if_e    wrbyte  #0,         PTRA[m_stat]    ' set ##mbox_status (success)
        if_e    jmp     #mainloop
                wrbyte  #$FF,       PTRA[m_stat]    ' set ##mbox_status (failed)
    '            setq    #32-1
    '            wrlong  sdx_status, ##$FC400        ' dump regs for debugging
                jmp     #mainloop
    '+-----------------------------------------------------------------------------+
    

    Attached is the SD Driver code.
    Note you only need the SD_DRV.spin2 object.

  • As I said, I've got the FSRW working kindof good enough right now, so I'm good for now. Will look into better alternatives at a later date.

  • pik33pik33 Posts: 2,366

    A Cluso's 2.70 cog resident driver works, so I started to write my own filesystem, because why not? I called it SURFS - a Simple Useless Retromachine File System, and it will implement old retro ideas from Atari 8bit DOS which was... simple

    The system will be incompatible with anything existing, but then there is a serial port which can be used to copy files from a PC to P2. A retromachine related copy speed :)

  • I did a lot of experiments with FSRW and Kyes FAT_ENGINE for my 4 SD kit I build years ago. RAISD.

    @lonesock did the PASM driver for FSRW and it supports read ahead and write behind. This made a huge difference on the P1, speed wise.

    The schema is as simple as good. For writing it copies the sector from HUB to COG memory and clears the mailbox to the calling COOG, then writes to the SD.

    On reading it reads the asked for sector and then reads the next sector in case it is asked for next.

    This makes a huge difference in speed because the calling COG does not need to wait for completion of the operations.

    Enjoy!

    Mike

  • RossHRossH Posts: 5,462

    Resurrecting this thread because I've just found a problem with fsrw's PASM code (which I use in Catalina). The multi-block write command it uses (CMD25 in the SD Card protocol) can result in the SD Card erasing the next sector after the sector currently being written. I believe this may be deliberate - it is not really fsrw's fault, but some SD Cards seems to pre-erase the next sector after the one you are currently writing to increase write speed - presumably on the basis that it will probably be the one written next. But sometimes the next sector is already in use! This is not usually a problem when you are adding and then updating files sequentially, but it can cause all sorts of havoc if you delete or update an existing file. Doing so can corrupt the directory structure, which might explain reports that fsrw can erase the SD card.

    Not yet sure this applies to all SD cards - it seems to occur on all the SD cards I have tried so far, but perhaps some cards do not do this - in which case fsrw would work fine.

    My current solution is very simple - disable the multi-block write functionality (i.e. write using only CMD24 instead of CMD25). Multi-block reads are ok, which means the speed loss from this change is not too dramatic in most cases.

    However, before I implement this fix in Catalina, has anyone else seen this problem and found a better solution that would allow multi-block writes to be retained?

    Ross.

  • I'm pretty sure MB writes are not supposed to corrupt the next block after. Then again, that FSRW driver (at least the version I was mucking with, see above) is kinda poor to begin with, it might be doing something wrong.

  • RaymanRayman Posts: 14,640

    There was definitely a problem with a previous version of FSRW where it would erase the card.
    Think it's fixed now. Think I posted it in one of @Wuerfel_21 's threads...

  • RaymanRayman Posts: 14,640

    Ok, it's here: https://forums.parallax.com/discussion/comment/1541639#Comment_1541639

    @Wuerfel_21 had already fixed the file erase issue I think and also a write issue with the assembly driver.
    This version has both a cogged and coggless driver and works with both Kye's high level and a slightly modified version of FSRW.

  • @Rayman the cogless driver kept smoking my cards when I tried to use it. Is the problem fixed in it?

  • RaymanRayman Posts: 14,640

    I believe so

    I was also seeing drives getting wiped and hopefully fixed it

  • RossHRossH Posts: 5,462
    edited 2022-09-10 05:47

    @Wuerfel_21 said:
    I'm pretty sure MB writes are not supposed to corrupt the next block after.

    Yes, it's definitely not supposed to.

    However, I think I am seeing a different problem to the one you fixed in your code. I can see command 24 (block write) used in your code, but not command 25 (multiple block write). But I may be missing it. Can you (or anyone!) point me to a successful use of command 25?

    UPDATE: I found the problem - multiple block writes can indeed work ok, but not on some Propeller 1 platforms that also have XMM RAM. Specifically, those platforms that need to disable the SD Card to access the XMM RAM. Doing so disrupts any ongoing multiple block writes. So I only need to revert to single block writes on those specific platforms. It's too long since I did much work on the Propeller 1 and all the complexities of its XMM support - I have been spoiled by the Propeller 2! :)

    I will include an update in the next release of Catalina.

    Thanks.

  • evanhevanh Posts: 15,915

    @RossH said:
    ... - I have been spoiled by the Propeller 2! :)

    Ain't that the truth. I'm doing my very first Prop project now and chose the Prop1 over the Prop2 because of low data demands and, oddly, the DIP40 footprint really suited the layout. Not to mention the much simpler power circuit. But the missing features keep hitting me after having spent all my hacking time exclusively on the Prop2.

  • YanomaniYanomani Posts: 1,524
    edited 2022-09-11 05:17

    @evanh said:

    I'm doing my very first Prop project now and chose the Prop1 over the Prop2 because of low data demands and, oddly, the DIP40 footprint really suited the layout. Not to mention the much simpler power circuit. But the missing features keep hitting me after having spent all my hacking time exclusively on the Prop2.

    Without intention on derailing any of your efforts, but rotating the LQFP-44 package by 45º can also prove to be a surprising option, mainly when you consider how easy the external components would fit.

  • evanhevanh Posts: 15,915

    True, I didn't try that but the question is more about making a Prop2 fit. So, what about QFP-100? That one's tougher I suspect.

Sign In or Register to comment.