Quote Originally Posted by hankshone View Post
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