Initialize()
Modified Hardware SPI Module
{
****************************************************************************
* Name : SPI.BAS *
* Author : John Barrat *
* : David John Barker *
* Notice : Copyright (c) 2006 Mecanique *
* : All Rights Reserved *
* Date : 26/05/2006 *
* Version : 1.1 Changed WriteByte() param to WREG for silicon workaround *
* : 1.0 Release *
* : ============================================================= *
* Notes : This post was made on the Swordfish forum by Steve B on *
* : April 8th 2007... *
* : I was having some trouble with the SPI module as well. I am *
* : using an 18F2620, Silicon A4, and was getting some *
* : inconsistent reads/writes, especially when doing a lot of *
* : TX/RX one after another. After looking at the errata, I *
* : changed the ReadByte and WriteByte routines as follows... *
* : *
* : Public Function ReadByte() As SSPBuffer *
* : SSPIF = 0 *
* : SSPBuffer = 0 *
* : Repeat *
* : ClrWDT *
* : Until SSPIF = 1 *
* : End Function *
* : *
* : Public Sub WriteByte(pData As WREG) *
* : SSPIF = 0 *
* : SSPBuffer = pData *
* : Repeat *
* : ClrWDT *
* : Until SSPIF = 1 *
* : End Sub *
* : *
* : Now they use the SSP Interrupt flag instead of the Buffer *
* : Full flag (SSPSTAT.0). I also added a subroutine to enable *
* : the SPI module *
* : *
* : Public Sub EnableSPI() *
* : Dim pDummy As Byte *
* : Enabled = true *
* : pDummy = SSPBuffer *
* : SSPIF = 0 *
* : End Sub *
****************************************************************************
}
Module SPI
Include "system.bas"
// map registers to SSP(x)
#if _mssp = 0
#error _device + " does not support MSSP"
// single SSP...
#elseif _mssp = 1
Dim
SSPControl1 As SSPCON1,
SSPStatus As SSPSTAT,
SSPBuffer As SSPBUF,
SCK As PORTC.3,
SDI As PORTC.4,
SDO As PORTC.5,
_SS As PORTA.5
// has more than one SSP module...
#else
Dim // -> MSSP2
SSPControl1 As SSP1CON1, // as SSP2CON1
SSPStatus As SSP1STAT, // as SSP2STAT
SSPBuffer As SSP1BUF, // as SSP2BUF
SCK As PORTC.3,
SDI As PORTC.4,
SDO As PORTC.5,
_SS As PORTA.5
#endif
// SSPSTAT bitnames
Public Dim
BF As SSPStatus.0, // buffer full (receive and transmit)
SMP As SSPStatus.7, // read sample mode
CKE As SSPStatus.6 // clock edge control
// SSPCON1 bitnames, master mode only...
Public Dim
WCOL As SSPControl1.7, // write collision Detect
SSPOV As SSPControl1.6, // receive overflow
SSPEN As SSPControl1.5, // synchronous receive enable
CKP As SSPControl1.4, // clock polarity
// synchronous mode select bits, %00XX for master mode
SSPM3 As SSPControl1.3, // always zero
SSPM2 As SSPControl1.2, // slave Mode
SSPM1 As SSPControl1.1, // clock Mode (MSB)
SSPM0 As SSPControl1.0 // clock Mode (LSB)
// interrupt flag
Public Dim
SSPIF As PIR1.3
Public Const
spiOscDiv4 = 0, // master mode FOSC/4
spiOscDiv16 = 1, // master mode FOSC/16
spiOscDiv64 = 2, // master mode FOSC/64
spiOscTimer2 = 3, // master mode TMR2 provides clock
spiSlaveSSEnabled = 4, // slave mode slave synch enabled
spiSlaveSSDisabled = 5, // slave mode slave synch disabled
// clock idle and edge settings (SPI Mode compatible)
spiRisingEdge = $40, // data transmitted on rising edge of clock
spiFallingEdge = $00, // data transmitted on falling edge of clock
spiIdleHigh = $10, // idle state for clock is high
spiIdleLow = $00, // idle state for clock is low
// RX data sampling settings (SSPStatus.6 - SMP)
spiSampleEnd = $80, // input data sampled at end of data output time
spiSampleMiddle = $00 // input data sampled at middle of data output time
// local helper aliases...
Dim
FBufferIsFull As SSPStatus.Booleans(0) // BF as boolean
// public aliases...
Public Dim
Enabled As SSPControl1.Booleans(5), // SSPEN as boolean
Overflow As SSPControl1.Booleans(6), // SSPOV as boolean
WriteCollision As SSPControl1.Booleans(7) // WCOL as boolean
{
****************************************************************************
* Name : SetAsMaster *
* Purpose : Set SPI to master mode *
* : spiOscDiv4 (DEFAULT), spiOscDiv16, spiOscDiv64, spiOscTmr2 *
****************************************************************************
}
Public Sub SetAsMaster(pMode As Byte = spiOscDiv4)
SSPControl1 = SSPControl1 And $F0
SSPControl1 = SSPControl1 Or pMode
Output(SDO)
Output(SCK)
End Sub
{
****************************************************************************
* Name : SetAsSlave *
* Purpose : Set SPI to slave mode *
* : spiSlaveSSEnabled, spiSlaveSSDisabled (DEFAULT) *
****************************************************************************
}
Public Sub SetAsSlave(pMode As Byte = spiSlaveSSDisabled)
SSPControl1 = SSPControl1 And $F0
SSPControl1 = SSPControl1 Or pMode
Output(SDO)
Input(SCK)
Input(_SS)
End Sub
{
****************************************************************************
* Name : SetSample *
* Purpose : Sets when the SPI input data in sampled *
* : spiSampleEnd, spiSampleMiddle. For slave mode, sample should *
* : always be spiSampleMiddle *
****************************************************************************
}
Public Sub SetSample(pSample As Byte)
SSPStatus = SSPStatus And $7F
SSPStatus = SSPStatus Or pSample
End Sub
{
****************************************************************************
* Name : SetClock *
* Purpose : Set SPI idle state and data transmission clock edge *
* : pIdle -> spiIdleHigh, spiIdleLow *
* : pEdge -> spiRisingEdge, spiFallingEdge *
****************************************************************************
}
Public Sub SetClock(pIdle As Byte, pEdge As Byte)
SSPControl1 = SSPControl1 And $EF
SSPControl1 = SSPControl1 Or pIdle
If pIdle = spiIdleHigh Then
pEdge = Not pEdge And $BF
EndIf
SSPStatus = SSPStatus And $BF
SSPStatus = SSPStatus Or pEdge
End Sub
{
****************************************************************************
* Name : ReadByte *
* Purpose : Read a single byte from the SPI bus *
****************************************************************************
}
'Public Function ReadByte() As SSPBuffer
' SSPBuffer = 0
' Repeat
' ClrWDT
' Until FBufferIsFull
'End Function
Public Function ReadByte() As SSPBuffer
SSPIF = 0
SSPBuffer = $FF
Repeat
ClrWDT
Until SSPIF = 1
ReadByte = SSPBuffer
End Function
Public Sub WriteByte(pData As Byte)
SSPIF = 0
SSPBuffer = pData
Repeat
ClrWDT
Until SSPIF = 1
End Sub
{
****************************************************************************
* Name : WriteByte *
* Purpose : Write a single byte to the SPI bus *
****************************************************************************
}
'Public Sub WriteByte(pData As WREG)
' SSPBuffer = pData
' Repeat
' ClrWDT
' Until FBufferIsFull
'End Sub
Public Sub EnableSPI()
Dim pDummy As Byte
Enabled = true
pDummy = SSPBuffer
SSPIF = 0
End Sub