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