ad. How to get PIC32 SPI interface working?

... and three functions preceeded by SW (software implementation of SPI1 for testing). Look at PC USB Projects PROGRAMMING GUIDE for detailed documentation.

The functions enable initialization of the microcontroller SPI interface, and single read and write access to HopeRF RFM69CW wireless communication module registers, where the address is 7-bit RFM69CW internal register address.

Digital thermometer and thermostat (ADT7410) v9 (x64) example from Downloads section provides more information in how to use HW SPI interface.

You can use only MemRead and MemWrite intstructions, too...

Let’s see a code example that initializes PIC32MS250F128B SPI1 to use advanced buffer mode, resets RFM69CW, reads a few RFM69CW registers and finally returns the data from PIC32MS250F128B SPI1 hardware buffers:

Dim addr As UInt32

Dim clear_ip7_spi1 As UInt32 = &HF000000

Dim spi1con_value As UInt32 = &H1

'addr = Convert.ToByte(TBX_Address.Text, 16)

spi1con_value <<= 16

spi1con_value += &H8527 ' We use 16-bit words to communicate with RFM69CW. Register read: Upper 8 bits = register address, lower 8 bits = data be written

clear_ip7_spi1 <<= 4

' PORTB configuration

pic.MemWrite(ANSELB, pic.MemRead(ANSELB) And &H814F) ' all SDI bits are digital

pic.MemWrite(ODCB, pic.MemRead(ODCB) And &H814F) ' all SDI bits as not open drain

pic.MemWrite(LATB, (pic.MemRead(LATB) And &H8310) Or &H10) ' Set bits {4 (RESET), 7 (SS1) ,13 (SDO1), 14 (SCK1)} to 0 and bit 5 (SD1) to 1 --> RESET RFM69CW

pic.MemWrite(TRISB, (pic.MemRead(TRISB) And &H8310) Or &H20) ' Set bits {4 (RESET), 7 (SS1) ,13 (SDO1), 14 (SCK1)} to 0 (OUTPUTS) and bit 5 (SDI1) to 1 (INPUT)

' Lb_Report.Items.Add("PORTB = " + Hex(pic.MemRead(PORTB)))

Delay(10) ' Wait until RFM69CW reset is appled (RB5=1 --> set in LATB)

'PPS configuration

pic.MemWrite(RPBR7R, 3)

pic.MemWrite(RPBR13R, 3)

pic.MemWrite(SS1R, 4)

pic.MemWrite(SDI1R, 1)

pic.MemWrite(PORTB_CLR, &H10) ' RESET = 0

Delay(10) ' Wait until RFM69CW restarts

'SPI initialization

pic.MemWrite(IEC1_CLR, &H70) ' disable SPI1 interrupts

pic.MemWrite(SPI1CON, 0) ' stop SPI operation

pic.MemWrite(PORTB_SET, &H80)

pic.MemRead(SPI1BUF) ' clear recive buffer

pic.MemWrite(IFS1_CLR, &H70) ' clear SPI1 interrupt flags

pic.MemWrite(IPC7_CLR, clear_ip7_spi1)

pic.MemWrite(SPI1BRG, 1) ' CLK freq. = (FPB = CPU freq.) / 4

pic.MemWrite(SPI1STAT, &H40) ' clear overflow

pic.MemWrite(SPI1CON2, &H300) ' set framed mode operation

pic.MemWrite(SPI1CON, spi1con_value)

' Send Read Command for register 1

pic.MemWrite(PORTB_CLR, &H80) ' NSS = 0

addr = 1 ' Read register 1

addr <<= 8 ' add second byte to enble reading

pic.MemWrite(SPI1BUF, addr) ' NSS = 1

pic.MemWrite(PORTB_SET, &H80)

pic.MemWrite(PORTB_CLR, &H80) ' NSS = 0

addr = 3 ' Read register 3

addr <<= 8 ' add second byte to enble reading

pic.MemWrite(SPI1BUF, addr) ' NSS = 1

pic.MemWrite(PORTB_SET, &H80)

pic.MemWrite(PORTB_CLR, &H80) ' NSS = 0

addr = 4 ' Read register 3

addr <<= 8 ' add second byte to enble reading

pic.MemWrite(SPI1BUF, addr) ' NSS = 1

pic.MemWrite(PORTB_SET, &H80)

pic.MemWrite(PORTB_CLR, &H80) ' NSS = 0

addr = 6 ' Read register 3

addr <<= 8 ' add second byte to enble reading

pic.MemWrite(SPI1BUF, addr) ' NSS = 1

pic.MemWrite(PORTB_SET, &H80)

pic.MemWrite(PORTB_CLR, &H80) ' NSS = 0

addr = 3 ' Read register 3

addr <<= 8 ' add second byte to enble reading

pic.MemWrite(SPI1BUF, addr) ' NSS = 1

pic.MemWrite(PORTB_SET, &H80)

' Read all the received data from the buffer..

Lb_Report.Items.Add("SPI1BUF = " + Hex(pic.MemRead(SPI1BUF)))

Lb_Report.Items.Add("SPI1BUF = " + Hex(pic.MemRead(SPI1BUF)))

Lb_Report.Items.Add("SPI1BUF = " + Hex(pic.MemRead(SPI1BUF)))

Lb_Report.Items.Add("SPI1BUF = " + Hex(pic.MemRead(SPI1BUF)))

Lb_Report.Items.Add("SPI1BUF = " + Hex(pic.MemRead(SPI1BUF)))

PIC32MX microcontrollers have two SPI (Serial Peripheral Interface) modules. Unlike PIC18’s MSSPs they are fully automated and buffered. Two 16-byte buffers are provided in the enhanced buffer mode. Therefore no interrupt handlers are needed in FW for simple applications. The buffers depth depends on the selected operating mode in SPI1CON register: 8-bit, 16-bit or 32-bit. RFM69CW transceiver prefers 16-bit mode which enables a human programmers to send and receive data by sending a single 16-bit word. Upper 8-bits consist of 1-bit read/write flag followed by 7-bit register address. Lower 8-bits are data to be written to RFM69CW, or dummy data, if a RFM69CW register is read.

SPI is a three wire interface: SDO, SDI and SCK. The data is simultaneously transmitted and received on a master and a slave device. A special SSPxBUF hardware buffer is used as a gateway to read and write bytes to SSPxSR shift register. When a byte of data on the master device is written to SSPxBUF register, it is copied to SSPxSR shift register and automatically transmitted to the slave device. As each bit is shifted out to the slave device a bit from the slave device is shifted into the SSPxSR register. After 8 shift operations the contents of the master SSPxSR register and the slave SSPxSR are exchanged.

So, a PIC18 microcontroller is just a toy compared to a PIC32. It’s surprising that a PIC32 in fact needs much less programming and it is much easier to program than a PIC32 microcontroller.

SPI functions in PIC32F250J128B firmware v2.9.1 or later and LIB_PCUSBProjects v6.2.NET4(x64).dll or later

There are nine functions: six functions for HW SPI1 implementation:

Function SPI1Init() as Integer

Function SPI1ReadReg(addr as Byte) as Integer

Function SPI1WriteReg(addr as Byte, dta as Byte) as Integer

Function SPI1Write(dta as UInt16) as Integer

Function SPI1BurstReadReg(addr as Byte, size as Byte) as Integer

Function SPI1BurstWriteReg(addr as Byte, size as Byte) as Integer

Click on the schematic to enlarge it

NOTE:

As one can easily see, only simple 32-bit memory write and 32-bit memory read commands were used to access PIC32MX250F128B registers. But due to hardware buffers, this code is as efficient as PIC18F26J50’s additional firmware functions.

Full sample code is available as an extension of Digital thermometer and thermostat example. Get Digital thermometer and thermostat (ADT7410) v9 x64 with RFM69CW SPI connection example.zip from Downloads section.

ALSO READ:

- PC USB Projects PROGRAMMING GUIDE

- How to properly configure RFM69CW and transfer data?

- How to get PIC18 SPI interface working?

Example: PIC32MX250F128B to RFM69CW connection