Porting a P1 object to P2 - Issues with SPI
Below are my read and write routines converted from spin to spin 2. I can see activity on my oscilloscope but I cannot decode spi. I don't quite have a grasp on the smart pins yet. Is there anything obviously wrong ?
Read seems to work (PINK) but write doesnt do anything (TEAL). Yellow is clock and blue is Chip Select
pri read(): Value
dira[dout]~ ' make dout input
outa[sclk] := ClockState ' set initial clock state
dira[sclk]~~ ' make clk output
Value~ ' clear output
repeat Bits
pintoggle(sclk)
waitct(getct() + ClockDelay)
pintoggle(sclk)
waitct(getct() + ClockDelay)
Value := (Value << 1) | ina[dout]
return Value
pri write(Value)
dira[din]~~ ' make Data pin output
outa[sclk] := ClockState ' set initial clock state
dira[sclk]~~ ' make Clock pin output
Value <<= (32 - Bits) ' pre-align msb
repeat Bits
outa[din] := (Value ROL 1) & 1 ' output data bit
waitct(getct() + ClockDelay)
pintoggle(sclk)
waitct(getct() + ClockDelay)
pintoggle(sclk)
Read seems to work (PINK) but write doesnt do anything (TEAL). Yellow is clock and blue is Chip Select

Comments
Suggestions:
-- don't use dira[], outa[], ina[], etc; P2 pinxxx instructions handle all that
-- don't use post set and clear operators; they're slower than direct assignments
-- you probably don't need to slow the clock bit
Try this:
pri read(bits) : value pinclear(DIO) ' make input (clear SP mode) pinwrite(SCLK, IDLE_SCLK) ' set SCLK to output and idle repeat bits pintoggle(SCLK) ' clock the bit waitus(1) pintoggle(SCLK) waitus(1) value := (value << 1) | pinread(DIO) ' read new bit (MSBFIRST) pri write(value, bits) pinwrite(SCLK, IDLE_SCLK) ' set SCLK to output and idle value << 32-bits ' move msb to value.[31] repeat bits pinwrite(DIO, value rol= 1) ' write bit to DIO pintoggle(SCLK) ' clock the bit waitus(1) pintoggle(SCLK) waitus(1)BTW, I use different but similar routines for block SPI that reads and writes blocks in memory.
SPIRD rep @sre1,#8 ' 8 bits outnot sck ' clock (low high) nop ' stretch out the clock outnot sck RWAIT nop ' delay needed until pin registers data nop testp miso wc ' read data from card rcl a,#1 ' shift in msb first sre1 ret SPITX8 rep @.L1,r1 rol X,#1 wc ' output next msb drvc mosi ' xDDDxDDDx' drvnot sck ' ---C---C-- nop drvnot sck ' .L1 retFrom the flexspin docs (yes, may be different from PNut Spin2...):
Just trying to understand!
Thx
dgately
But...
I think you meant:
THx!
pri read(sclk, din, bits, khz) : value | tix tix := clkfreq / (khz * 1000) >> 2 ' 1/4 clock time org drvl sclk ' sclk is output/low fltl din ' make din input rep #8, bits waitx tix drvh sclk waitx tix waitx tix drvl sclk waitx tix testp din wc ' sample din rcl value, #1 ' shift into result ret end pri write(value, sclk, dout, bits, khz) | tix tix := clkfreq / (khz * 1000) >> 2 ' 1/4 clock time org drvl sclk ' sclk is output/low ror value, bits ' move msb to bit 31 rep #8, bits rol value, #1 wc ' get bit drvc dout ' write to dout waitx tix ' let dout settle drvh sclk ' clock high waitx tix waitx tix drvl sclk ' clock low waitx tix ret endThis assumes clock idle state is low (I looked at the data sheet for that device)I got it working. For some reason though I still cant decode it on my scope.
if (ina[dout] == 1) repeat until (ina[dout] == 0) else waitct(mark)...can lead to unexpected troubles if the pin is > 31. Better to use this form:if (pinread(dout)) repeat while (pinread(dout)) else waitct(mark)Suggestions:
In your start() method, change... to:
If you change the BITS constant to a parameter in read() and write() like this
pri read(bits) : value pinclear(dout) ' make dout input repeat bits pinhigh(sclk) waitus(1) pinlow(sclk) waitus(1) value := (value << 1) | pinread(dout) pri write(value, bits) value ror= bits ' pre-align msb repeat bits pinwrite(din, value rol= 1) ' output data bit pinhigh(sclk) waitus(1) pinlow(sclk) waitus(1)... then bits like this: ...become: ...and...pri sample() : result | mark mark := (clkfreq >> wsps) * 5 / 4 + getct() pinl(cs) if (pinread(dout)) repeat while (pinread(dout)) else waitct(mark) result := read(16) pinh(cs)Finally, using... ...is redundant -- unless you're modifying the return value in the last step, like this:
pri write(value, bits) value ror= bits ' move msb to value.[31] repeat bits pinwrite(DOUT, value rol= 1) ' write bit to DOUT pintoggle(SCLK) ' clock the bit waitus(1) pintoggle(SCLK) waitus(1)I ran a simple test loop:repeat pinl(CS) write($A5FF, 16) pinh(CS) waitms(50)I've attached the capture from my $13 logic analyzer running through PulseView with the SPI decoder enabled.Weird my scope cant see it.