Problem with either SPI2, or PPS

Coding and general discussion relating to user created compiler modules

Moderators: David Barker, Jerry Messina

Post Reply
garryp4
Posts: 125
Joined: Mon May 21, 2007 7:18 am
Location: Loveland, CO USA

Problem with either SPI2, or PPS

Post by garryp4 » Sun Sep 29, 2019 10:39 am

I am trying to talk to a Microchip MRF89XA radio with PPS SPI pins. Here is my main routine and the radio routine

Code: Select all

Device = 18F47J13
Clock  = 8

// LCD...
#option LCD_DATA       = PORTD.4
#option LCD_RS         = PORTA.7
#option LCD_EN         = PORTA.6
#option LCD_INIT_DELAY = 100
#option LCD_DATA_US    = 50
#option LCD_COMMAND_US = 2000

Config IOL1WAY = OFF

// import modules...
Include "convert.bas"
Include "system.bas"
Include "MB85RS16.BAS"
Include "lcd.bas"
'Include "SET_UP.bas"
Include "MRF89XA_M.BAS"
Include "USART.BAS"

  
Private Dim
  red              As PORTC.0,
  green            As PORTC.1,
  enter            As PORTD.2,
  down             As PORTC.2,
  up               As PORTD.0,
  setup            As PORTD.1,
  mem_cs           As PORTD.3,

  r_irq0           As PORTB.2,
  r_irq1           As PORTA.1,
  r_reset          As PORTB.0,
  r_cscon          As PORTB.1,
  r_csdata         As PORTA.0,
    
  piezo            As PORTA.5,
  flasher          As PORTE.0,
  alarm_reset      As PORTE.1
  
Private Dim
  b1               As Byte,
  b2               As Byte,
  lp1              As Word,
  lp2              As Byte


'****************************************************************************
Private Sub BLINK_LED()
  High(red)
  DelayMS(100)
  Low(red)
  DelayMS(100)
  High(green)
  DelayMS(100)
  Low(green)
End Sub
'****************************************************************************

OSCCON   = $7F                         ' Interanl clock to 8mhz
OSCCON2  = $54
REFOCON  = $00
OSCTUNE  = $00                           
ADCON0   = $00                         ' A/D disabled
ADCON1   = $00                         ' A/D disabled
ANCON0   = $FF
ANCON1   = $1F
PMCONH   = $00                         ' Disable parallel port
DSCONH   = $00
DSCONL   = $05
ODCON1   = $00
ODCON2   = $00
CCP4CON  = $00
CCP5CON  = $00
CCP6CON  = $00
CCP7CON  = $00
CCP8CON  = $00
CCP9CON  = $00
CCP10CON = $00
CTMUCONH = $00                         ' Disable the CTMU
INTCON   = $00                         ' Disable interupts

PMDIS3  = $FF                          ' Shut down peripherals
PMDIS2  = $FF
PMDIS1  = $E0                          ' F8
PMDIS0  = $F1                          ' Only ser1 and SPI1/2 enabled

High(mem_cs)
High(r_cscon)
High(r_csdata)
Input(r_irq0)
Input(r_irq1)
Input(r_reset)
Input(enter)
Input(up)
Input(down)
Input(setup)

USART.SetBaudrate(br9600)             ' Baud rate
BLINK_LED

LCD.Initialize 
LCD.Cls
DelayMS(5)
LCD.WriteAt(1,1,"I'M ALIVE")           ' LCD
DelayMS(10)
USART.Write("I'M ALIVE ",10,13)  
LCD.Cls
DelayMS(1000)
LCD.Cls

{  b1 = 0                              ' Routine to test SPI memory chip - works fine
  b2 = 0
  For lp1 = 0 To 2048
    MB85RS16.WRITE_BYTE(lp1,b1)
    Inc(b1)
    b2 = MB85RS16.READ_BYTE(lp1)
    LCD.WriteAt(1,1,DecToStr(lp1),"  ",DecToStr(b2),"  ")
    DelayMS(5)
    
    USART.Write(DecToStr(lp1),"  ",DecToStr(b2),10,13)
    DelayMS(2)
  Next    
}


  MRF89XA_M.READ_REG
'  MRF89XA_M.RADIO_RCV                 ' Not implemented yet

Code: Select all

Module MRF89XA_M

Include "USART.bas"
Include "convert.bas"
Include "pps.bas"
Include "lcd.bas"
Include "spi2.bas"

Private Dim 
  irq0               As PORTB.2,
  irq1               As PORTA.1,
  r_reset            As PORTB.0,
  r_cscon            As PORTB.1,
  r_csdata           As PORTA.0,
  mem_sel            As PORTD.3,
  red                As PORTC.0,
  green              As PORTC.1
    
Private Dim
  b1                 As Byte,          ' Byte holder
  b2                 As Byte,          ' Byte holder
  loop1              As Word

Private Const
  wren As Byte       = $06,            ' Write enable
  rdsr As Byte       = $05,            ' Read satus register
  wrsr As Byte       = $01,            ' Write status register
  read_data As Byte  = $03,            ' Read instruction
  write_data As Byte = $02,            ' Write instruction
  
  gcon_addr_w        = $00,            ' Write address of GCONREG
  gcon_addr_r        = $40,            ' Read address of GCONREG 
  xmit_gcon          = $8A,            ' Transmit mode
  rcv_gcon           = $6A,            ' Recieve mode
  stby_gcon          = $2A,            ' Standby mode
  dmod_addr_w        = $02,            ' Write address of DMODREG
  dmod_addr_r        = $42,            ' Read address of DMODREG
  dmod               = $8C,            ' Packet mode
  ftxrxi_addr_w      = $1A,            ' Write address of FTXRXIREG
  ftxrxi_addr_r      = $5A,            ' Read address of FTXRXIREG
  ftxrxi             = $08,            ' RCV IRQ0=PAYLD READY, IRQ1=CRC OK  - TX  IRG1=TX DONE - CLEAR FIFI FULL + OVRRUN
  clkout_addr_w      = $36,            ' Write address of CLKOUTREG
  clkout_addr_r      = $76,            ' Read address of CLKOUTREG
  clkout             = $3C,            ' Disable CLKOUT
  pload_addr_w       = $38,            ' Write address of PLOADREG
  pload_addr_r       = $78,            ' Read address of PLOADREG
  pload              = $80             ' Manchester Encoding and Payload enabled
  
'****************************************************************************
Private Sub BLINK()
  High(green)
  DelayMS(100)
  Low(green)
End Sub
'****************************************************************************
Private Sub SET_RADIO_SPI()

  USART.Write("SET_RADIO_SPI+++++++++++++++++++++++++",10,13)    
  DelayMS(5)  

  pps.unlock()  
  b1 = PPSCON
  USART.Write("PPSCON=", BinToStr(b1,8),10,13)
  DelayMS(2)
  pps.assign_output(PPS_SDO2, PPS_OUT_RP6)   ' SDO2 <- RB3  
  pps.assign_output(PPS_SCK2, PPS_OUT_RP7)   ' SCK2 <- RB4
  pps.assign_input(PPS_SDI2, PPS_IN_RP8)     ' SDI2 -> RB5
  pps.lock()

  b1 = RPOR7
  USART.Write("SCLK2 - RPOR7=",BinToStr(b1,8),"    ",DecToStr(b1),10,13)   ' Should be 11
  DelayMS(5)

  b1 = RPOR6
  USART.Write("SDO2 - RPOR6=",BinToStr(b1,8),"    ",DecToStr(b1),10,13)    ' Should be 10
  DelayMS(5)
    
  b1 = RPINR21
  USART.Write("SDI - RPINR21=",BinToStr(b1,8),"    ",DecToStr(b1),10,13)   ' Shoulld be 8
  DelayMS(5)  
  
  b1 = PPSCON
  USART.Write("PPSCON=",BinToStr(b1,8),10,13)
  
  b1 = SSP2CON1
  USART.Write("SSP2CON1=",BinToStr(b1,8),10,13)  
  USART.Write("++++++++++++++++++++++++++++++++++++++",10,10,13)    
  DelayMS(5)  

End Sub
'****************************************************************************
Public Sub OPEN_SPI()

  USART.Write("OPEN_SPI `````````````````````````````",10,13)    
  DelayMS(5)  
  SPI2.SetAsMaster(spiOscDiv64)
  SPI2.SetClock(spiIdleLow,spiRisingEdge)           ' spiRisingEdge  spiFallingEdge
  SPI2.Open(SPI_MODE_1,spiOscDiv64,spiSampleEnd)    ' spiSampleEnd, spiSampleMiddle 
  DelayMS(1)
  
  b1 = SSP2CON1
  USART.Write("SSP2CON1=", BinToStr(b1,8),10,13)    ' Make sure SSPEN is enabled
  DelayMS(5)
  USART.Write("``````````````````````````````````````",10,10,13)    
  DelayMS(5)  
    
End Sub
'****************************************************************************
Public Sub RADIO_RESET()
  High(r_reset)
  DelayMS(100)
  Input(r_reset)
  DelayMS(100)
End Sub  
'****************************************************************************
Private Sub RADIO_CONFIG_SPI()                      ' Set config Chip sel
  OPEN_SPI
  High(r_csdata)
  Low(r_cscon)
  DelayUS(2)
End Sub
'****************************************************************************
Private Sub RADIO_DATA_SPI()                        ' Set data Chip sel
  OPEN_SPI
  High(r_cscon)
  Low(r_csdata)
  DelayUS(2)
End Sub
'****************************************************************************
Private Sub DISABLE_RADIO_SPI()                     ' No Chip sel
  High(r_cscon)
  High(r_csdata)
  DelayUS(2)
  SPI2.Close
End Sub  
'****************************************************************************
Public Sub RADIO_INIT()

  USART.Write("RADIO_INIT----------------------------",10,13)    
  DelayMS(5)
  
  High(r_reset)
  DelayMS(100)
  Input(r_reset)
  DelayMS(10)

  SET_RADIO_SPI                                     ' Set PPS
  RADIO_CONFIG_SPI                                  ' Select config chip sel

'  SPI2.writebyte(gcon_addr_w)                       ' Register address write
'  SPI2.writebyte(stby_gcon)                         ' Write data to register
  SPI2.Transfer(gcon_addr_w)                        ' Register address write
  SPI2.Transfer(stby_gcon)                          ' Write data to register
  DelayMS(1)
  DISABLE_RADIO_SPI                                 ' Register writes on rising edge of Chip sel
  Toggle(green)

  RADIO_CONFIG_SPI
'  SPI2.writebyte(gcon_addr_r)                       ' Register address read                                  
  SPI2.Transfer(gcon_addr_r)                        ' Register address read
  b1 = SPI2.ReadByte                                ' Read the register to verify
  b2 = SPI2.ReadByte                                ' And read the next register too
  DISABLE_RADIO_SPI
  DelayMS(10)

  DISABLE_RADIO_SPI
  USART.Write("GCON = ",BinToStr(b1,8),"  DMOD = ",BinToStr(b2,8),10,13)    
  DelayMS(5)
  USART.Write("--------------------------------------",10,10,13)    
  DelayMS(5)
  
End Sub
'****************************************************************************
Public Sub READ_REG()

  RADIO_RESET
  RADIO_INIT
  
  While true                          ' Loop to look for SCLK, SDI, SDO with scope
  RADIO_CONFIG_SPI  
  SPI2.Transfer(gcon_addr_r)          ' $40
  DelayUS(5)
  b1 = SPI2.ReadByte
  b2 = SPI2.ReadByte                  ' DMOD register address
  DelayUS(5)
  DISABLE_RADIO_SPI

  USART.Write("GCON = ",BinToStr(b1,8)," DMOD = ",BinToStr(b2,8),10,13)
  DelayMS(2000)
  Toggle(red)
  Wend  

End Sub
'****************************************************************************
Public Sub RADIO_RCV()       ' this sub is in progress

 RADIO_RESET
 RADIO_DATA_SPI

End Sub
'****************************************************************************

'****************************************************************************
High(r_cscon)
High(r_csdata)
Input(irq0)
Input(irq1)
USART.SetBaudrate(br9600)              ' Baud rate
LCD.Initialize
Here are the PIC register values output to hterm:
I'M ALIVE
RADIO_INIT----------------------------
SET_RADIO_SPI+++++++++++++++++++++++++
PPSCON=00000000
SCLK2 - RPOR7=00001011 11
SDO2 - RPOR6=00001010 10
SDI - RPINR21=00001000 8
PPSCON=00000001
SSP2CON1=00000000
++++++++++++++++++++++++++++++++++++++

OPEN_SPI `````````````````````````````
SSP2CON1=00100010
``````````````````````````````````````

OPEN_SPI `````````````````````````````
SSP2CON1=00100010
``````````````````````````````````````

GCON = 00000000 DMOD = 00000000
--------------------------------------

OPEN_SPI `````````````````````````````
SSP2CON1=00100010
``````````````````````````````````````

GCON = 00000000 DMOD = 00000000
OPEN_SPI `````````````````````````````
SSP2CON1=00100010
``````````````````````````````````````

GCON = 00000000 DMOD = 00000000

When I watch for SCLK2, SDO2, or SDI2 with a scope, I get no signal. The chip select signals work fine as do SPI1 signals to a memory chip. I can't figure if the problem is with the SPI2 or with the PPS. That would not be your modules but how I am probably using them wrong.

Thanks in advance for any help!

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Problem with either SPI2, or PPS

Post by Jerry Messina » Mon Sep 30, 2019 10:03 am

Unfortunately, there's no way for the peripheral modules to automatically know about PPS mapped pins.

If you have the latest SPI2 module (V1.2, attached), try adding options to set the pin definitions for SPI2 before including spi2.bas:

Code: Select all

Module MRF89XA_M

Include "USART.bas"
Include "convert.bas"
Include "pps.bas"
Include "lcd.bas"

#option SPI2_SCK = PORTB.4         // SPI clock
#option SPI2_SDI = PORTB.5         // SPI data in
#option SPI2_SDO = PORTB.3         // SPI data out
Include "spi2.bas"
Those should match up with the pps assignments you listed:

Code: Select all

  pps.assign_output(PPS_SDO2, PPS_OUT_RP6)   ' SDO2 <- RB3 
  pps.assign_output(PPS_SCK2, PPS_OUT_RP7)   ' SCK2 <- RB4
  pps.assign_input(PPS_SDI2, PPS_IN_RP8)     ' SDI2 -> RB5
Also, because of the nature of SPI, on some devices you have to map the SCK signal as both output AND input so you may find that you have to add that in too...

Code: Select all

  pps.assign_input(PPS_SCK2IN, PPS_IN_RP7)     ' SCK2 in <- RB4
See if that helps...
Attachments
SPI2.zip
(3.88 KiB) Downloaded 155 times

garryp4
Posts: 125
Joined: Mon May 21, 2007 7:18 am
Location: Loveland, CO USA

Re: Problem with either SPI2, or PPS

Post by garryp4 » Tue Oct 08, 2019 2:36 am

Thanks, that worked.

One more question. What is the correct syntax for SPI send and receive using 'Transfer'?

Code: Select all

  
  SPI2.Transfer(gcon_addr_r)
  b1 = SPI2.ReadByte
works but the module implies it is used for both send and recieve.

Thanks!

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Problem with either SPI2, or PPS

Post by Jerry Messina » Tue Oct 08, 2019 9:34 am

The Transfer() function always does a write-read operation since that's the nature of SPI. If you don't assign the return value then it's just discarded.

If you use Transfer() with no parameters it will send a dummy 0 byte, read the value sent by the slave, and return it.

So...

Code: Select all

// write 'gcon_addr_r', read the byte transferred and discard it
SPI2.Transfer(gcon_addr_r)

// write a dummy 0, read the byte transferred and return it
b1 = SPI2.Transfer()

// same as above (write a dummy 0, read the byte transferred and return it)
b1 = SPI2.Transfer(0)

// write and read in the same transaction (not as common)
b1 = SPI2.Transfer(gcon_addr_r)

Post Reply