
Originally Posted by
hankshone
Hi Paul: I am actually trying to figure out the hardware SPI module for F-RAM. So can you share your codes for that part? I appreciate it very much!!!
Vinson
Hello Vinson,
Here it is, warts and all...
Code:
'****************************************************************
'* Name : HW_FRAM_SPI_Test.pbp *
'* Notes : Demo of using hardware SPI port to read and write *
'* : a Ramtron FM25C106-G 16K 5V F-RAM chip. *
'* : *
'* : Assembled on an Olimex DEV-00021 40-pin *
'* : board from Sparkfun. *
'* : *
'* : Much information on working with the hardware *
'* : SPI was gleaned from Jeremy Grotte's *
'* : sdfshc32d.pbp file. *
'* : *
'* : Compiled using PBP v2.60L *
'* : *
'****************************************************************
' PIC18F452 DIP Package
' Pin Assignments
' Pin # Use Hookup
' 1 MCLR/VPP To Vdd through 4.7k resistor
' 2 RA0/AN0 n/c, reserved for analog input
' 3 RA1/AN1 n/c
' 4 RA2/AN2/VREF- n/c
' 5 RA3/AN3/VREF+ n/c
' 6 RA4/T0CKI n/c
' 7 RA5/AN4/SS n/c
' 8 RE0/RD/AN5 n/c
' 9 RE1/WR/AN6 n/c
' 10 RE2/CS/AN7 n/c
' 11 Vdd Power, +5V
' 12 Vss Ground
' 13 OSC1/CLKIN To 20MHz crystal
' 14 OSC2/CLKOUT To 20MHz crystal
' 15 RC0/T1OSO/T1CKI n/c
' 16 RC1/T1OSI/CCP2 n/c
' 17 RC2/CCP1 n/c
' 18 RC3/SCK/SCL to F-RAM SCK (pin 6)
' 19 RD0/PSP0 n/c
' 20 RD1/PSP1 n/c
' 21 RD2/PSP2 n/c
' 22 RD3/PSP3 FRAM_CS, to F-RAM CS (pin 1)
' 23 RC4/SDI/SDA SDI, to F-RAM SO (pin 2)
' 24 RC5/SDO SDO, to F-RAM SI (pin 5)
' 25 RC6/TX/CK TX; to MAX232A Pin 11 (goes out from pin 14 to DB9F pin 2)
' 26 RC7/RX/DT RX; to MAX232A Pin 12 (goes out from pin 13 to DB9F pin 3)
' 27 RD4/PSP4 n/c
' 28 RD5/PSP5 n/c
' 29 RD6/PSP6 n/c
' 30 RD7/PSP7 n/c
' 31 Vss Ground
' 32 Vdd Power, +5V
' 33 RB0/INT n/c
' 34 RB1 n/c
' 35 RB2 n/c
' 36 RB3/PGM n/c
' 37 RB4 n/c
' 38 RB5 n/c
' 39 RB6/PGC n/c
' 40 RB7/PGD n/c
'Notes
'-----
'SETUP RS232:
'Target device uses 115200 baud, 8 bits, 1 stop bit, flow control = none
'--------------------------------------------------------------------------------
'### Includes
'--------------------------------------------------------------------------------
'none
'--------------------------------------------------------------------------------
'### Defines
'--------------------------------------------------------------------------------
DEFINE LOADER_USED 1
DEFINE OSC 20
'Set receive register to receiver enabled
DEFINE HSER_RCSTA 90h
'Set transmit register to transmitter enabled, high speed BRGH
DEFINE HSER_TXSTA 24h
'Set baud rate
DEFINE HSER_BAUD 115200
'automatically clear any USART overflows
DEFINE HSER_CLROERR 1
'--------------------------------------------------------------------------------
'### Constants
'--------------------------------------------------------------------------------
TRUE CON 1
FALSE CON 0
OCWREN con %00000110 'F-RAM Write Enable Op-Code
OCRDSR con %00000101 'F-RAM Read Status Register Op-Code
OCWRSR con %00000001 'F-RAM Write Status Register Op-Code
OCREAD con %00000011 'F-RAM Read Memory Op-Code
OCWRITE con %00000010 'F-RAM Write Memory Op-Code
'--------------------------------------------------------------------------------
'### Aliases
'--------------------------------------------------------------------------------
SCK Var PORTC.3 ' SPI clock
SCK_TRIS Var TRISC.3 ' SPI clock direction
SDI Var PORTC.4 ' SPI data in
SDI_TRIS Var TRISC.4 ' SPI data in direction
SDO Var PORTC.5 ' SPI data out
SDO_TRIS Var TRISC.5 ' SPI data out direction
FRAM_CS Var PORTD.3 ' F-RAM chip select
FRAM_CS_TRIS Var TRISD.3 ' F-RAM chip select direction
WCOL Var SSPCON1.7 ' SSP write collision
SSPEN Var SSPCON1.5 ' SSP enable
SSPIF Var PIR1.3 ' SSP interrupt flag
'--------------------------------------------------------------------------------
'### Set Up Registers
'--------------------------------------------------------------------------------
ADCON1 = %10001110 'left justified, RA0/AN0 is analog input
'Set up SPI port
SSPSTAT = %01000000 ' Sample at middle of data output time, Transmit on idle rising edge of SCK
'SSPCON1 = %00000010 ' SPI master mode, clock = Fosc/64, Clock idle LOW.
'SSPCON1 = %00000001 ' SPI master mode, clock = Fosc/16, Clock idle LOW.
SSPCON1 = %00000000 ' SPI master mode, clock = Fosc/4, Clock idle LOW.
SSPEN = 1 ' Enable hardware SPI port.
'--------------------------------------------------------------------------------
'### Variables
'--------------------------------------------------------------------------------
nSPI_Data_In var byte
nSPI_Data_Out var byte
lVal var long
wFRAM_Addr var word
'--------------------------------------------------------------------------------
'### Initialization
'--------------------------------------------------------------------------------
FRAM_CS = 1 ' F-RAM chip not selected.
FRAM_CS_TRIS = 0' F-RAM chip select as output
SDO = 1 ' Start SPI data out high
SDO_TRIS = 0 ' SPI data out as Output
SDI_TRIS = 1 ' SPI data in as Input
SCK = 0 ' SPI clock idles low
SCK_TRIS = 0 ' SPI clock as Output
wFRAM_Addr = $000F ' Set an arbitray memory location
lVal = -5000 ' Set lVal to some starting point
pause 500
hserout["lVal initalized to ", dec lVal,13,10]
'Jump to Main program
goto main
'--------------------------------------------------------------------------------
'### Helper Functions
'--------------------------------------------------------------------------------
WriteSPI:
WCOL = 0
nSPI_Data_In = SSPBUF ' Clear the buffer.
SSPIF = 0 ' Clear the interrupt flag.
SSPBUF = nSPI_Data_Out ' Send the byte.
If (WCOL) Then Return ' Check for write collision.
While (!SSPIF) ' Wait for send to complete.
Wend
Return
ReadSPI:
nSPI_Data_In = SSPBUF ' Clear the buffer.
SSPIF = 0 ' Clear the interrupt flag.
SSPBUF = $ff ' Shift out a dummy byte.
While (!SSPIF) ' Wait for receive byte.
Wend
nSPI_Data_In = SSPBUF ' Get the byte.
return
'--------------------------------------------------------------------------------
'### MAIN PROGRAM
'--------------------------------------------------------------------------------
Main:
' Do a write
' Select the F-RAM
FRAM_CS = 0
' Begin with WREN
nSPI_Data_Out = OCWREN
gosub WriteSPI
' un-select the F-RAM
FRAM_CS = 1 ' only one Op-code per chip select!!!
' Select the F-RAM
FRAM_cs = 0
' Next send WRITE OpCode
nSPI_Data_Out = OCWrite
gosub WriteSPI
' Send two bytes of address (upper 5 bits are "don't care")
nSPI_Data_Out = wFRAM_Addr.HighByte '$00
gosub WriteSPI
nSPI_Data_Out = wFRAM_Addr.LowByte '$0f
gosub WriteSPI
' next byte(s) are data, address will increment with each write
nSPI_Data_Out = lVal.Byte0
gosub WriteSPI
nSPI_Data_Out = lVal.Byte1
gosub WriteSPI
nSPI_Data_Out = lVal.Byte2
gosub WriteSPI
nSPI_Data_Out = lVal.Byte3
gosub WriteSPI
' un-select the F-RAM
FRAM_CS = 1
' do a read
FRAM_CS = 0
' Begin by sending the read OpCode
nSPI_Data_Out = OCREAD '=READ command
gosub WriteSPI
' Send two bytes of address (upper 5 bits are "don't care")
nSPI_Data_Out = wFRAM_Addr.HighByte
gosub WriteSPI
nSPI_Data_Out = wFRAM_Addr.LowByte
gosub WriteSPI
' Now read in the value one byte at a time
gosub ReadSPI 'one byte into nSPI_Data_In
lVal.Byte0 = nSPI_Data_In
gosub ReadSPI 'one byte into nSPI_Data_In
lVal.Byte1 = nSPI_Data_In
gosub ReadSPI 'one byte into nSPI_Data_In
lVal.Byte2 = nSPI_Data_In
gosub ReadSPI 'one byte into nSPI_Data_In
lVal.Byte3 = nSPI_Data_In
FRAM_CS = 1
hserout["lVal=",dec lVal,13,10];
' Add one and write it back to the same location
lVal = lVal + 1
goto Main
Let us know if there are questions or difficulties.
Best Regards,
Paul
Bookmarks