Shop Learn P1 Docs P2 Docs
[EDITED] fast SPI out, 1 bit per instruction - Page 2 — Parallax Forums

[EDITED] fast SPI out, 1 bit per instruction

2»

Comments

  • pgbpsupgbpsu Posts: 460
    edited 2012-10-01 18:13
    Kuroneko-

    That's the relevant bit I was missing! I'm not in a position to test this at the moment, but this makes sense. Although even if I trigger the data line I don't see anything. In what you describe I can see why I get no clock, but I would have expected data to be shifted out. Sounds like this might be the same problem. The phsX register can't manipulate the expected bin because it just so happened that I pick a test value that ended in bit[0]=1. I guess that's better than having chosen it to end in 0 in which case I'd have had a really hard time finding it.

    Again, thanks for your help.
    Regards,
    Peter
  • kuronekokuroneko Posts: 3,623
    edited 2012-10-01 18:38
    It just occurred to me that you could use the counter even for the slow code. neg phsb, #1 would raise the clock line and mov phsb, #0 lower it (NCO, pin := phsx[31]). This way outa wouldn't get in the way. The only thing to be aware of here is that the clock for fast mode is then delayed for one system clock (since phsb is left at -1). This may or may not be an issue. Just something to be aware off. HTH
    Sounds like this might be the same problem. The phsX register can't manipulate the expected bin because it just so happened that I pick a test value that ended in bit[0]=1.
    Confirmed. Again, you could use a similar approach as the one outlined above (instead of muxc use rcr phsa, #1).

    Just noticed that you preset phsb for the clock anyway so there would be no clock delay.
  • pgbpsupgbpsu Posts: 460
    edited 2012-10-09 06:42
    With Kuroneko's help I was able to get this sorted. As he pointed out, the complete code I posted above left some pins high when I exited my slow routines which meant the fast routines (and the counter in particular) couldn't lower the clock or output pins because the output state is the logical OR of all the different factions that have control over the state of a pin. By making sure my slow routines left both clock and data low on exit, I was able to get lonesock's code working. Thanks to all for the help, especially kuroneko.

    Here are the working versions. A slow read/write, fast read, faster write:
    {******************************** RW_BYTE ******************************************************
    This command grabs reads the number of bytes to write from the HUB location byteCountPtr, then
    writes (byte wise) the bytes beginning at bufferVal.  Because it is SPI it also reads from the
    WIFI module at the same time.  The result is placed in the same slot of the buffer as the sent
    value.
    Z=1 when we enter.  Z=1 when finished.  
    ***************************************************************************************************}
    RW_BYTE
              rdlong  numBytes,     byteCountPtr    ' how many bytes are we supposed to write?
    '          mov     temp,         bufferPtr       ' bufferPtr points to the HUB mailbox
                                                    ' get a copy of that location for future use
              rdlong  hubAddress,   bufferPtr            ' read the addresss of the buffer; currently found in HUB mailbox
    :byteLoop
              mov     inData,       #0              ' init before filling
              mov     numBits,      #8              ' init number of bits to read/write
              rdbyte  outData,      hubAddress      ' get local copy of data to write
              shl     outData,      #24             ' shift lowest byte into MSB; bit[7]->bit[31]
    
    :bitLoop 
              shl     outData,      #1        wc    ' set C = outData[31] then shift          
              muxc    outa,         mosiMask        ' put value of C onto MOSI
              muxz    outa,         clkMask         ' raise clock
              test    misoMask,     ina       wc    ' C=ina[miso]
              muxnz   outa,         clkMask         ' lower clock
              rcl     inData,       #1              ' shift C left into inByte
              djnz    numBits,      #:bitLoop       ' decrement loop          
              
              wrbyte  inData,       hubAddress      ' write the data back to the buffer
              muxnz   outa,         mosiMask        ' make sure data line is low on exit
              add     hubAddress,   #1              ' set pointer to next byte in buffer     
              djnz    numBytes,     #:byteLoop      ' Decrement loop count.
    
    
    RW_BYTE_ret       ret
    
    {******************************** R_BYTE ******************************************************
    High speed read ONLY for SINGLE byte.  This method clocks out $00 and reads the data
    coming in on MISO.  Clock is about 9.6Mhz.  Writes the input data back to hub memory
    address that was passed to this method.  Using lonesock's method from FSRW.  
    Z=1 when we enter.  Z=1 when finished.  
    ***************************************************************************************************}
    R_BYTE
              rdlong  hubAddress,   bufferPtr       ' read the addresss of the buffer; currently found in HUB mailbox
              neg     phsa,         #1              ' DI high
              mov     inData,       #0
    
              ' set up my clock, and start it
              movi    phsb,         #%011_000000
              movi    frqb,         #%001_000000
              ' keep reading in my value
              test    misoMask,     ina   wc
              rcl     inData,       #1
              test    misoMask,     ina   wc
              rcl     inData,       #1
              test    misoMask,     ina   wc
              rcl     inData,       #1
              test    misoMask,     ina   wc
              rcl     inData,       #1
              test    misoMask,     ina   wc
              rcl     inData,       #1
              test    misoMask,     ina   wc
              rcl     inData,       #1
              test    misoMask,     ina   wc
              rcl     inData,       #1
              test    misoMask,     ina   wc
              mov     frqb,         #0 ' stop the clock
              rcl     inData,       #1
              mov     phsa,         #0 'DI low
    
              wrbyte  inData,       hubAddress      ' write the data back to the buffer
    R_BYTE_ret         ret
    
    {******************************** W_FAST ******************************************************
    This command reads the number of bytes to write from the HUB location byteCountPtr, then
    writes (byte wise) the bytes beginning at bufferVal.  This is a stripped down version of the RW_BYTE
    code and does NOT capture a response.  It's write ONLY.  Also based on lonesock/rokicki's FSRW code
    Z=1 when we enter.  Z=1 when finished.  
    ***************************************************************************************************}
    W_FAST
              rdlong  numBytes,     byteCountPtr    ' how many bytes are we supposed to write?
              rdlong  hubAddress,   bufferPtr       ' read the addresss of the buffer; currently found in HUB mailbox
    :byteLoop
              rdbyte  outData,      hubAddress      ' get local copy of data to write
              mov     phsa,         outData         ' start with the raw data byte
              shl     phsa,         #24             ' get the MSb into position 31
              'rev     phsa,         #0             ' do this instead of the above line for LSb first
              movi    phsb,         #%000000000     ' set up my clock register        
              movi    frqb,         #%010000000     ' start my clock line ticking!
              shl     phsa,         #1              ' move next bit into the PHSA[31] slot
              shl     phsa,         #1              ' move next bit into the PHSA[31] slot
              shl     phsa,         #1              ' move next bit into the PHSA[31] slot
              shl     phsa,         #1              ' move next bit into the PHSA[31] slot
              shl     phsa,         #1              ' move next bit into the PHSA[31] slot
              shl     phsa,         #1              ' move next bit into the PHSA[31] slot
              shl     phsa,         #1              ' move next bit into the PHSA[31] slot
              mov     frqb,         #0              ' stop my clock
            
    
              add     hubAddress,   #1              ' set pointer to next byte in buffer     
              djnz    numBytes,     #:byteLoop      ' Decrement loop count.
    W_FAST_ret        ret
    
Sign In or Register to comment.