Here attached is a working code fragment. At the moment SPI master only.
I have a few questions.
1. The hardware SPI is as expected is very fast, however the chip select CS is relatively slow. Question is there anyway I can speed the CS (ENABLE) up? I have tried, but seem to be stuck to the speed of the interpreter. At 4m/z the /CS (ENABLE on the graph) active low time is about 1.04ms whilst the 8 bit data burst is only 120us (using the /64 clock rate). I realize adjusting the master clock from 4mh/z to 16mh/z or higher will make a big difference. But I was hoping to do better than this. Note for testing SDO is linked to SDI
Right now this hardware SPI is approx 10x quicker than the bit bang routine, but potentially could be another 10x quicker if the /CS speed can be improved.
2. Is there a way to get closer to the built in definitions. ie. like hspisetup spimode00, spimedium ; spi mode 0,0 ?
Compared to this clean code, my initialization method looks quite clunky, is there a better way?
3. Please, if there are any obvious coding improvements to be made please be critical.
4. I plan to try to modify this to work as an i2C slave - it seems doable.
I have a few questions.
1. The hardware SPI is as expected is very fast, however the chip select CS is relatively slow. Question is there anyway I can speed the CS (ENABLE) up? I have tried, but seem to be stuck to the speed of the interpreter. At 4m/z the /CS (ENABLE on the graph) active low time is about 1.04ms whilst the 8 bit data burst is only 120us (using the /64 clock rate). I realize adjusting the master clock from 4mh/z to 16mh/z or higher will make a big difference. But I was hoping to do better than this. Note for testing SDO is linked to SDI
Right now this hardware SPI is approx 10x quicker than the bit bang routine, but potentially could be another 10x quicker if the /CS speed can be improved.
2. Is there a way to get closer to the built in definitions. ie. like hspisetup spimode00, spimedium ; spi mode 0,0 ?
Compared to this clean code, my initialization method looks quite clunky, is there a better way?
3. Please, if there are any obvious coding improvements to be made please be critical.
4. I plan to try to modify this to work as an i2C slave - it seems doable.
Code:
; -------------------------------------------------------------------------
;|
;| Hardware SPI for M2 series Version 001 2/9/12
;|
; -------------------------------------------------------------------------
#define test
#picaxe 14M2
#no_data ' reduce upload time
#terminal 4800
; -------------------------------------------------------------------------
;|
;| Project Description
;|
; -------------------------------------------------------------------------
{
; Work in progress.....Current requirement SPI driver for a graphics display
; SDI not required right now.
;
; Routines providing hardware SPI in Master mode,intended to replace the
; bit banging xxM2 routines. This method should be both quicker and more
; code efficient.
;
; Hopefully this will work in the M2 multitasking mode and may be able
; to co-exist with I2C.
;
; 14M2 pin connections
; pin8 B5 = SDO
; pin9 B4 = SDI
; pin10 B3 = SCL
; pin11 B2 = /CS
;
; Note1 The CS select deselect is slow, the Buffer Full check does not seem
; to be required.
;
; Notes For each byte sent @ 4mh/z the /CS active time is 1.04ms,
; data time 120us using /64 clock rate.
; To Do:-
; Activate Alternative Pin mode.
; SPI read under interrupt
; Test alongside I2C
}
; --------------------------------------------------------------------------
;|
;| I/O and SPI Mode Definitions
;|
; -------------------------------------------------------------------------
{
symbol APFCON0 = $5D
symbol APFCON1 = $5E
symbol SSP1BUF = $91
symbol SSP1STAT = $94
symbol SSP1CON1 = $95
symbol CS = B.2
'Mode is a constant/variable to define the mode
symbol spimode00 = %00000000 '(mode 0,0 - TX idle-Active, input sampled middle of data time)
symbol spimode01 = %01000000 '(mode 0,1 - TX idle-Active, input sampled middle of data time
symbol spimode10 = %10000000 '(mode 1,0 - TX Active-idle, input sampled end of data time)
symbol spimode11 = %11000000 '(mode 1,1 - TX Active-idle, input sampled end of data time)
'Spispeed is a constant/variable to define the clock speed
symbol spifast = %00100000 '(clock freq / 4 ) (= 1MHz with 4MHz resonator)
symbol spimedium = %00100001 '(clock freq / 16) (= 250kHz with 4MHz resonator)
symbol spislow = %00100010 '(clock freq / 64) (= 63 kHz with 4MHz resonator)
symbol SSP1STAT_BIT = bit0 ; Buffer full status bit
}
; --------------------------------------------------------------------------
;|
;| Variable Definitions
;|
; -------------------------------------------------------------------------
{
Symbol V1 = b0 ' scratch0
Symbol V2 = b1 ' scratch1
Symbol SpiMode = b2 '
Symbol SpiSpeed = b3 '
Symbol SPItxd = b4 ' Data to send to SPI bus
Symbol SPIrxd = b5 ' Received Data from SPI bus
}
; ---------------------------------------------------------------------------
;| Testing section
; ---------------------------------------------------------------------------
#ifdef test
SpiMode= SpiMode01 : SpiSpeed= SpiSlow '
Gosub SPISETUP
Main:
For V2= $85 to $127
SpiTxd = V2 : Gosub WriteToSPI
SERTXD ("SP1Txd = ", #SpiTxd," SP1Rxd = ", #SpiRxd,CR,LF)
Pause 1000
Next V2
Goto main
#endif
; ---------------------------------------------------------------------------
;| SPI Initialisation
; ---------------------------------------------------------------------------
SpiSetup: ' b2 = spimode, b3 = spispeed
'B2 CS output, B3 SCK0 output, B4 SDI input, B5 SDO output
'76543210
let dirsB = %11101111 ' set port pin directions
PeekSFR SSP1CON1, V1 : V1 = V1 AND %11011111
PokeSFR SSP1CON1, V1 'turn off module, in case it was on
PeekSFR SSP1STAT, V1 : V1 = V1 AND %00111111 : V1 = V1 OR SpiMode
PokeSFR SSP1STAT, V1 ' Set the SPImode
PeekSFR SSP1CON1, V1 : V1 = V1 AND %11011100 : V1 = V1 OR SpiSpeed
PokeSFR SSP1CON1, V1 'enable MSSP, idle is low,set clock rate
' pokesfr APFCON1,0 'alternate pin config
return
; ---------------------------------------------------------------------------
;| SPI Transmit Routines
; ---------------------------------------------------------------------------
WriteToSPI:
Low CS
pokesfr SSP1BUF,SpiTxd
' Do while SSP1STAT_BIT=1 loop ' * see note 1
High CS
peeksfr SSP1BUF,SpiRxd
return
end