SPIIN in Picaxe 40X2

Aries

New Member
I use Nordic NRF24L01 transceivers, which use SPI to communicate with the Picaxe. Originally, I used 20M2s, and so had to use bit-banging. Recently, I started to use 20X2s as well, and so "upgraded" to using SPIIN and SPIOUT. No problems. Now, for the first time, I want to use a Picaxe 40X2. When I try to use the SPIIN code which works correctly on the 20X2, the values returned are inverted (i.e. instead of getting "b0", I get "NOT b0"). Am I missing something very obvious, or is there a difference between the 40X2 and the 20X2?

This is the code I have run for both chips - the code is identical, and I plugged the 20X2 port B pins into the corresponding pins in the 40X2 holder on the PCB, so the connections are identical. The code writes to two registers (0000 and 1010), with the write bit (00100000) set, and then reads them back (without the write bit set).
Code:
#terminal 9600

symbol pinMISO = pinB.2   ' Master In, Slave Out (from NRF)
symbol MISO = B.2              ' Master In, Slave Out (from NRF)
symbol SCK  = B.3         ' SPI clock
symbol CE   = B.4         ' Chip Enable
symbol pinCE = pinB.4
symbol pinMOSI = pinB.6        ' Master Out, Slave In (to NRF)
symbol MOSI = B.6                ' Master Out, Slave In (to NRF)
symbol IRQ = pinB.5           ' Interrupt (from NRF)
symbol CSN  = B.7         ' Chip Select Not (keep high)

'symbol PowerPin = A.1
symbol PowerPin = B.0

low PowerPin
pause 5000

    for b1 = 0 to 3
        sertxd(CR,LF,"Case ",#b1,CR,LF)
        gosub InitNRF2401
        sertxd(CR,LF)
        gosub ReportNRF2401
    next b1
end
InitNRF2401:
  HIGH CSN           'Chip select
  LOW SCK
  LOW MOSI

  LOW CE            'disable transceiver

    pause 1000
  high CSN           'Chip select (not)
  low SCK
  low MOSI

'    Send 00100000
' Send 00111111
    b0 = %00100000 : gosub SendToNRF
    b0 = %00111111 : gosub SendToNRF
    high CSN
'    Send 00101010
'    Send 11100111
    b0 = %00101010 : gosub SendToNRF
    b0 = %11100111 : gosub SendToNRF
    high CSN
  return

ReportNRF2401:
    pause 1000

    b0 = %00000000 : gosub SendToNRF
  gosub GetFromNRF
    high CSN
    b0 = %00001010 : gosub SendToNRF
  gosub GetFromNRF
    high CSN
    return
SendToNRF:
  sertxd ("Send ",#bit7,#bit6,#bit5,#bit4,#bit3,#bit2,#bit1,#bit0,CR,LF)
    low CSN
    select case b1
    case 0,1
        spiout SCK,MOSI,MSBFirst_L,(b0)
    case 2,3
        for b2 = 0 to 7
          pinMOSI = bit7
        pulsout SCK,1
            b0 = b0 * 2                          ' shift variable left for MSB
      next b2
    end select
return

'*********************************************
' get one byte (MSB first) from NRF
GetFromNRF:
    select case b1
        case 0,2
            spiin SCK,MISO,MSBPre_L,(b0)
        case 1,3
          b0 = 0
            for b12 = 0 to 7
                b0 = b0 * 2 + pinMISO                ' set LSB if MISO = 1
            pulsout SCK,1
            next b12
    end select
  sertxd ("Recv ",#bit7,#bit6,#bit5,#bit4,#bit3,#bit2,#bit1,#bit0,CR,LF)
return
These are the results:
Code:
Picaxe 40X2    Picaxe 20X2
    
Case 0
Send 00100000    Send 00100000
Send 00111111    Send 00111111
Send 00101010    Send 00101010
Send 11100111    Send 11100111
    
Send 00000000    Send 00000000
Recv 11000000    Recv 00111111
Send 00001010    Send 00001010
Recv 00011000    Recv 11100111
    
Case 1
Send 00100000    Send 00100000
Send 00111111    Send 00111111
Send 00101010    Send 00101010
Send 11100111    Send 11100111
    
Send 00000000    Send 00000000
Recv 00111111    Recv 00111111
Send 00001010    Send 00001010
Recv 11100111    Recv 11100111
    
Case 2
Send 00100000    Send 00100000
Send 00111111    Send 00111111
Send 00101010    Send 00101010
Send 11100111    Send 11100111
    
Send 00000000    Send 00000000
Recv 11000000    Recv 00111111
Send 00001010    Send 00001010
Recv 00011000    Recv 11100111
    
Case 3
Send 00100000    Send 00100000
Send 00111111    Send 00111111
Send 00101010    Send 00101010
Send 11100111    Send 11100111
    
Send 00000000    Send 00000000
Recv 00111111    Recv 00111111
Send 00001010    Send 00001010
Recv 11100111    Recv 11100111
Cases 1 and 3 (bit-banging on receive) are the same with both chips
In cases 0 and 2 (SPIIN on receive), the 40X2 receives the inverse of the 20X2
 

Goeytex

Senior Member
Seems to me that with the exact same code using the same pins that the result would be the same. Possibly the firmware has a bug where the idle state is inverted on the 40X2 ?

f you can't get anywhere with this, why not try using HSPIIN/HSPIOUT instead of bit-banging with spiin/spiout. I had good success with HSPI using a 20X2 with the NRF24L01 and since this uses the PIC's MSSP module it should be significantly faster than bit-banging.

Some Sample Code Here
 

Aries

New Member
I agree that it looks like a bug in the firmware. In this particular application, I am already using HSPIIN/HSPIOUT for communication with three SPI-based memory chips. It would be possible to extend to the NRF24L01, but it would mean modifying the PCB to shift the control pins. However, the more normal application of the program is in I2C slaves, where the HSPI pins would clash with the HI2C pins, and so is not an option. It's just one large (2500 lines) program, with various bits selected by judicious use of #defines, so it was not a major change to include "if it is a 28X2 or 40X2 then use bit-banging for SPIIN", given that the bit-banging is there for the M2 chips anyway.
 

Goeytex

Senior Member
Let's assume a firmware bug where the 40x2 inverts the bits relative to the 20x2.

You are using "MSBPre_L" as the mode that works on the 20x2. This is idle low.

Why not try "MSBPre_H" on the 40x2 and see what happens ?

If the firmware has idle low and idle high reversed on the 40x2 then this may shed some light.

Goey
 

Aries

New Member
Why not try "MSBPre_H" on the 40x2 and see what happens ?
I've tried that.

Unfortunately, the "idle high" option is not available, due to a known bug ...
"Current PICAXE-40X2 production firmware is version B.3
Known issues:
ISSUE - SHIFTIN/SHIFTOUT IDLE HIGH MODES DO NOT WORK CORRECTLY
The xxxx_H 'idle high' modes of shiftin and shiftout do not operate as expected. To workaround this issue use the bit-busting routines described in manual part 2. "
 

Goeytex

Senior Member
Looks like a firmware bug crippling the HSPI functionality of this Picaxe chip.

@hippy

Can you confirm whether on not this is a bug ? Maybe test on silicon ?
 
Top