Shop OBEX P1 Docs P2 Docs Learn Events
Sharing SD SPI pins without unmounting — Parallax Forums

Sharing SD SPI pins without unmounting

Kal_ZakkathKal_Zakkath Posts: 72
edited 2009-11-13 22:11 in Propeller 1
I have an SD card and an LCD screen (nokia 3310) that I want to have sharing the 3 SPI pins (DI\DO\CLK on the SD).
All works fine if I do this:


sd.mount(10)
sd.unmount
 
lcd.Init
lcd.str(String("Test"))


My problem is that I'll be playing wav files from the SD card and want the lcd to continue updating, but if I do this:

sd.mount(10)
 
lcd.Init
lcd.str(String("Test"))



then the LCD does not initialise properly.
my understanding is that the CS pin is used to tell devices when to listen to the SPI bus, so it shouldn't matter what the LCD does when not accessing the SD card (in my actual code I am using mutex locks to ensure the SD and LCD are not clashing with each other).

For the SD I'm using fsrw24 (but rolling back to 2.3 or 1.6 makes no difference), the lcd code I have written myself, as far as I can see the issue is not because of anything I've done but I'm attaching the source code here just in case.
Currently the pinout is:
SD: DO = 10, Clk = 11, DI = 12, CS = 13
LCD: Reset = 8, CS = 9, DC = 10, DI = 11, Clk = 12

So far I can only think of three options:
  1. Alter fsrw somehow (seems like it would take too long to be worth the effort)
  2. Alter the wav code to unmount the SD card between reads (would require seeking back to the last file position, which could be too slow)
  3. Don't share any pins between the SD and LCD (looking like my favourite option because it was my original design so it's easy to go back to... would be nice to have a few more pins spare though)

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-11-07 07:07
    The problem is that the LCD code and the SD code are not designed for those lines to be shared. Each cog has its own direction and output registers and the SD routines use a separate cog to do the low-level I/O. The two cogs (the main one and the low-level SD one) are both trying to control the output pins (Clk and DI). The simplest thing is to use separate I/O pins for each. It is possible to modify the I/O routines to share the I/O pins "nicely", but it would be a bit of work to go through the code to make it happen.
  • Cluso99Cluso99 Posts: 18,069
    edited 2009-11-07 10:23
    Further to what Mike has said, there is another problem with sharing the pins. DO from the SD card does not release (tristate) normally when CS is removed. It requires a number of clock pulses as well.

    See the TriBlade and ZiCog threads. I have solved the fsrw driver for Femto in the ZiCog/TriBlade femto driver. Lonesock/rokicki have added some extra code to disable the DO as well, but I don't have it working on TriBlade yet.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Links to other interesting threads:

    · Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)
    · Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
  • Kal_ZakkathKal_Zakkath Posts: 72
    edited 2009-11-07 12:48
    Thanks for the quick replies.

    Mike: Yeah I realised that would be the issue, I thought I might get passed it since A) all the lines to the LCD are outputs (so it should be fine provided the SD cog leaves the lines as either inputs or low outputs, as all cog outputs are OR'd together) and B) as far as I can tell all calls to fsrw (spin) block until the low-level cog is finished, so there shouldn't be any instances when both the 'Main' cog and the 'low-level' cog are both trying to output to the same pins.

    I could be wrong about B, if A is the only problem though (the low-level SD code not reverting the pins back to inputs\low) it should just be a matter of having it switch the pins on\off when it goes to\from it's idle state (this is of course my 'ideal simplistic world' thinking).


    Cluso99: Thanks for that tip. I wonder, if Lonesock\rokicki have done code for it, does that mean pin sharing may work with the next·version of fsrw?


    As with so many things this idea of sharing the pins sounded great (and simple) on paper, but is turning out to be more complicated in practicality.
    32 pins seemed like a lot when I started this project! heh
  • lonesocklonesock Posts: 917
    edited 2009-11-07 17:46
    In FSRW 2.4, the block layer has a "release" command. The block layer is designed to have only one instance, so it's OK to do something like this:
    OBJ
      sdfat: "fsrw"
      sdspi: "mb_rawb_spi" ' make sure this matches exactly the block layer used in "fsrw"
    
    '...
    ' bunch of code
    '...
    
      ' finished reading WAV data
      sdspi.release
      ' now update my LCD
    
    
    


    FSRW will automatically reacquire the lines next time you ask "sdfat" to do something, so make sure the LCD is no longer using those lines before you read/write/open/close, etc.

    You will need to uncomment the line immediately after "for Cluso99" in the release_DO section of the "mb_rawb_spi.spin", so it should read:
    mov dira,#0
    



    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • Kal_ZakkathKal_Zakkath Posts: 72
    edited 2009-11-10 08:39
    Hmm, I tried that but still no go. According to a logic probe all lines are fine except for DO which is still high after calling release.
    If I try to then make it low in the 'main' cog, it pulses (or at least the logic probe says it is [noparse][[/noparse]Sq. wave < 100kHz], I don't have an oscilloscope to see what it's really doing unfortunately).

    I tried adding more calls to in8 in release_DO·in case it needed more clock cycles but it didn't seem to make any difference.

    And as before if I call unmount first it all works fine.
    ·
  • lonesocklonesock Posts: 917
    edited 2009-11-10 16:36
    OK. If the card refuses to release the DO line I'm not sure what else to do (the driver cog is not driving that...it's an input to the prop, from the SD card). You could try it with a card from a different manufacturer. I suppose we could even write the mount logic in PASM to speed up a remount, but I'm very hesitant to do that, for the resulting code size, readability, and debug-ability.

    sorry,
    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • Cluso99Cluso99 Posts: 18,069
    edited 2009-11-11 03:18
    Jonathan: I haven't had the time to debug, but that could be the same problem I was finding. As soon as time permits, I will get back to finishing the ZiCog/TriBlade code and that may perhaps showup the problem. For now, I have just presumed I am missing something.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Links to other interesting threads:

    · Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)
    · Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
  • RossHRossH Posts: 5,344
    edited 2009-11-11 09:00
    @all,

    Also, look in the Catalina code I wrote for the TriBladeProp - I also had to rewrite the spdi low level code to get it working, and make sure the XMM Kernel and the SD plugin correctly tristated the control lines in each case. The files to look at are:

    Catalina_SD_Plugin_Input.spin
    Catalina_XMM_Input.spin

    both in Catalina\target\input - look for the "#ifdef TRIBLADEPROP" sections

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • Kal_ZakkathKal_Zakkath Posts: 72
    edited 2009-11-13 10:44
    just re-checked the pins and I was wrong, it is DI (pin #13 on the prop, pin #2 on the card, adjacent to CS) being held high not DO.
    After calling release, DO and CLK are fine (tristated), CS is high (as it should be) and DI is still high.

    At the moment I'm sharing DO and CLK pins with DI moved to its own pin and everything works fine.
    I·should be able to make do this way,·can't see why DI isn't tristated though as release_DO clearly zeros dira, unless the card itself is doing something weird.

    The test code I have now is:

    i := \sd.mount_explicit(10, 11, 13, 14)                                'Mount SD Card
    if(i <> 0)
       repeat 
      
     repeat 5
       waitcnt(cnt + 80_000_000)
        
    
      sd.release
          
      repeat 5
        waitcnt(cnt + 80_000_000)
     
      sd.unmount
    



    sd.release is just a pass-through function that calls sdspi.release
    logic probe shows DI pulsing after mount,·still pulsing·after release, then tristated after unmount.
    I've also tried two different SD card brands (Transcend and Adata) and also tried using pins 2,3,5,6 just in case but got the same results.
    Oh and the cards are microSD with SD adapters... shouldn't matter but thought I should give as much information as I can just in case.

    As I said it's working now by giving DI its own pin, and whilst it would be a bit tidier to share the three SPI pins I'll pick a design that works over one that's tidy any day [noparse];)[/noparse]
  • lonesocklonesock Posts: 917
    edited 2009-11-13 16:17
    You know what...I think you found a bug in my code!

    I have some code that will auto-release after an inactivity timeout (currently 0.125 seconds). Once the timeout is exceeded, the release_DO code gets called repeatedly under the theory that it couldn't hurt. However, in my command handler if the last command was a reset, then it re-enables the output lines...then processes the fact that the new command is another release, and releases the lines. So, of the state of outa doesn't happen to match your pull-ups/downs, then the pins that don't match will be toggling!

    This particular bug _should_ only happen 1/8th a second after you call release, though (I think, anyway).

    Nice catch, and I'll try to fix this today...I just need to make sure my fix doesn't break anything else. (Hopefully this will make it work for Cluso as well.)

    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • lonesocklonesock Posts: 917
    edited 2009-11-13 17:07
    Please try this updated version of the block layer. If it fixes the problem, I will then make the changes across the board to the other block layers (the smaller versions, etc.). We will then push out a 2.5 release as soon as possible.

    Note: you will still need to uncomment the "mov dira,#0" line again.

    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • Kal_ZakkathKal_Zakkath Posts: 72
    edited 2009-11-13 22:11
    Yes! That seems to have fixed it, both the test code and my full app now run fine sharing all three pins, awesome job! thanks for·all the hard work smile.gif
Sign In or Register to comment.