SPI PIC 18F4620 and BMP280 (In Oshonsoft)

jjw

Joined Dec 24, 2013
823
I have'nt looked at the burst read.
Have you initialized BMP280, the measurement and filter settings etc?

I would make two functions:
HWSPI_Write(x) where x is data or address.
HWSPI_Read(x) where x is address.
Then you can replace the Oshonsoft spi_send and spi_receive functions in the working program.
SPI_send adr -> HWSPI_Write(adr)
SPI_send data -> HWSPI_Write(data)
SPI_receive data -> data = HWSPI_Read(adr) this includes writing address and reading data from that address.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
I have'nt looked at the burst read.
Have you initialized BMP280, the measurement and filter settings etc?

I would make two functions:
HWSPI_Write(x) where x is data or address.
HWSPI_Read(x) where x is address.
Then you can replace the Oshonsoft spi_send and spi_receive functions in the working program.
SPI_send adr -> HWSPI_Write(adr)
SPI_send data -> HWSPI_Write(data)
SPI_receive data -> data = HWSPI_Read(adr) this includes writing address and reading data from that address.
Hi J,
I now am converting an old OSH SPI working program, that I will change to SSPBUF SPI bit by bit, while keeping it working, with the posted CODE #240 as it is, in the MAIN LOOP, as this makes it possible for me, then once working will add the suggested FUNCTIONS.

In the above program is the initialisation and measurement filter settings.

I tried what I thought is BURST READ, but it showed '0's, these could be the '0's in the terminal image #240?
C
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Hi J,
FUNCTIONs or no FUNCTIONs! I soon ran into complications, with my easier no FUNCTION method, getting difficult, and more tangled, so I'll add FUNCTIONs ;)
C.
 
Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Hi J,
As a matter of interest! If I first run the OSH SPI working program, then without switching off, program the SSPBUF progam, here is a terminal view, showing READings, in other words, the firast program is setting up the initialisation, then being REAd by SSPBUF SPI.
C
 

Attachments

jjw

Joined Dec 24, 2013
823
Examples of hardware SPI functions. Not tested.
Code:
Function HWSPI_Write(Dim x as Byte) ' x is either address or data
  SSPBUF = x
  While Not SSPSTAT.BF
  Wend
End Function


Using it:
' chip select here, deselect other peripherals.
HWSPI_Write(adr)
HWSPI_Write(data)

Usually functions return a value.
I have not tested if Oshonsoft accepts a function without returning a value. Could use a procedure instead or return a dummy value.

Function  HWSPI_Read(Dim x as Byte) ' x is address to read from

   SSPBUF=x
   While Not SSPSTAT.BF
   Wend

   SSPBUF= 0x00    ' dummy byte
   While Not SSPSTAT.BF
   Wend
   HWSPI_Read = SSPBUF

End Function

Using it:
' chip select, deselect others
data = HWSPI_Read( adr )
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Examples of hardware SPI functions. Not tested.
Code:
Function HWSPI_Write(Dim x as Byte) ' x is either address or data
  SSPBUF = x
  While Not SSPSTAT.BF
  Wend
End Function


Using it:
' chip select here, deselect other peripherals.
HWSPI_Write(adr)
HWSPI_Write(data)

Usually functions return a value.
I have not tested if Oshonsoft accepts a function without returning a value. Could use a procedure instead or return a dummy value.

Function  HWSPI_Read(Dim x as Byte) ' x is address to read from

   SSPBUF=x
   While Not SSPSTAT.BF
   Wend

   SSPBUF= 0x00    ' dummy byte
   While Not SSPSTAT.BF
   Wend
   HWSPI_Read = SSPBUF

End Function

Using it:
' chip select, deselect others
data = HWSPI_Read( adr )
Hi J,
I hope you don't mind, but HW and SW confuses me, so I will change HWSPI to SSPBUFSPI.

With this method, is it possible to have ADR instead of X and DATA instead of X?

Thanks, I'll give it a go.
C.
 

jjw

Joined Dec 24, 2013
823
But HW Usart does not confuse you?
You don't call it Tx buffer and Rx buffer method.

HW SPI is a module inside a PIC ( like an Usart ) , which sends data autonomously, when loaded.
When this works, you can forget, that you ever heard of the Oshonsoft SPI :)

X is a parameter in the function definition, which is replaced by an actual value, when the function is called.

HWSPI_Write( data )
HWSPI_Write ( adr )
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
But HW Usart does not confuse you?
You don't call it Tx buffer and Rx buffer method.

HW SPI is a module inside a PIC ( like an Usart ) , which sends data autonomously, when loaded.
When this works, you can forget, that you ever heard of the Oshonsoft SPI :)

X is a parameter in the function definition, which is replaced by an actual value, when the function is called.

HWSPI_Write( data )
HWSPI_Write ( adr )
Hi J,
HW UART also confuses me. I think of the PIC as hardware and PROGRAMS and CODE as SW. The reason it's important to me, is that I used to have HW and SW in the program title, and I spent a year picking the wrong one. With OSH SPI and SSPBUF SPI I don't make that mistake anymore. I think in the Simulator is a Hardware and a Software screen, so I open both and see which one works, sad but true:), and as you say, once it is all working and in PROCEDURES, this won't be necessary.

I am trying your CODE #245, but I have tried many things to get it to compile, and so far failing.
Would you mind, if I posted a compiling program, where you could change it, as I keep checking it still compiles?
C.
 

jjw

Joined Dec 24, 2013
823
Examples of hardware SPI functions. Not tested.
Code:
Function HWSPI_Write(Dim x as Byte) ' x is either address or data
  SSPBUF = x
  While Not SSPSTAT.BF
  Wend
End Function


Using it:
' chip select here, deselect other peripherals.
HWSPI_Write(adr)
HWSPI_Write(data)

Usually functions return a value.
I have not tested if Oshonsoft accepts a function without returning a value. Could use a procedure instead or return a dummy value.

Function  HWSPI_Read(Dim x as Byte) ' x is address to read from

   SSPBUF=x
   While Not SSPSTAT.BF
   Wend

   SSPBUF= 0x00    ' dummy byte
   While Not SSPSTAT.BF
   Wend
   HWSPI_Read = SSPBUF

End Function

Using it:
' chip select, deselect others
data = HWSPI_Read( adr )
Correction:
Function HWSPI_Write(Dim x as Byte) should be
Function HWSPI_Write(x as Byte)

Function HWSPI_Read(Dim x as Byte) should be
Function HWSPI_Read(x as Byte) as Byte
 
Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Correction:
Function HWSPI_Write(Dim x as Byte) should be
Function HWSPI_Write(x as Byte)

Function HWSPI_Read(Dim x as Byte) should be
Function HWSPI_Read(x as Byte) as Byte
Hi J,
I tried your program, but couldn't get it to compile, thanks for the corrections.

I tried my own with my type of variable, and even then there are mistakes, but it compiles and gives READings.
Here is the program, which will take me a while for me to correct, but it may give you a way of re-writing yours as an initial program for me to test.

If you want to try adding 'stuff' into the (), or re-try a FUNCTION, you're welcome to try, and I'll test them.
C.
Code:
'18F46K20 32MHz EXT PCB_5 BASE 090621 1200 ALT SSPBUF ONLY
'Open up main loop to sequence the various functions
'Add 2 scheduling timers for air data/compass report and $BIRO message as main cycles too fast to
'send on each loop.

'------------- TARGET SETUP  ------------------
'Const PR2set = 125  'use this for the live board: gets 5ms per interrupt
Const PR2set = 2  'use this for fast timing to speed up simulator
Define SIMULATION_WAITMS_VALUE = 1  'Comment in for SIM out for PIC

'----------- SYSTEM CONFIG  --------------------
'PIC Config
Define CONFIG1L = 0x00
Define CONFIG1H = 0x06  'EXT 8 + PLL=32MHz'02  '8=INT  2=EXT
Define CONFIG2L = 0x1e
Define CONFIG2H = 0x00
Define CONFIG3L = 0x00
Define CONFIG3H = 0x81  'Set for HVP
Define CONFIG4L = 0x80
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40
Define CLOCK_FREQUENCY = 32

'OSH config
Define SINGLE_DECIMAL_PLACES = 2
Define STRING_MAX_LENGTH = 20  'long enough?

'IO MAP
'SET BITS ON/OFF before TRIS!
Const LATAinit = %00000000  'ON/OFF
Const LATBinit = %00000000
Const LATCinit = %00000000
Const LATDinit = %00000000
Const LATEinit = %00000000  'POSS MCLR RE3

'SET PIN IN/OUT
Const TRISAinit = %00101111  '7=XTL 6=XTL 5=ANALOGUE IN (POT) 4=SERIN 18f4431 3210= ANALOGUE INPUTS (POTS)
Const TRISBinit = %00000000  '7=PGD 6=PGC 543210 SPARE
Const TRISCinit = %10010000  '7=RX=1, 6=TX=0, 5=SDO, 4=SDI=1, 3=SCK=0, 2=RLED, 1=YLED
Const TRISDinit = %00000000  '7=CS SPARE, 6=CS DATASW_S1, 5=CS DATASW_S0, 4=CS RADSET HC-12, 3=CS BMP280, 2=CS AK8963C_DRDY, 1=AK8963C_TRIG, 0=CS AK8963C_CS
Const TRISEinit = %00000000  '=Button


'HC-12 RADIO
Symbol radset = LATD.4  'HC-12 0=COMMAND ON 1=DATA ON
Const RADIO_COMMAND_MODE = 0
Const RADIO_DATA_MODE = 1

'BMP280 ALTIMETER
Symbol altmtr_cs = LATD.3  'BMP280 BAROMETER/TEMP
Dim data As Byte
Dim data1 As Byte
Dim x As Byte

'================= CODE BEGINS ====================================
'IO Config
'Init LATx flip flops before TRIS regs
    LATA = LATAinit
    LATB = LATBinit
    LATC = LATCinit
    LATD = LATDinit
    LATE = LATEinit

    TRISA = TRISAinit
    TRISB = TRISBinit
    TRISC = TRISCinit
    TRISD = TRISDinit
    TRISE = TRISEinit
   
    SPIPrepare
   
Symbol yled = LATE.1
Symbol rled = LATE.2

'START UP LEDS
    yled = 1
    rled = 1
    WaitMs 1000
    yled = 0
    rled = 0
    WaitMs 1000

'Set up UART and RX interrupt for immediate use
    Hseropen 9600  'does a basic config of TX and RX including BAUDCON, SPEN, CREN, TXEN etc.
    RCSTA.CREN = 0  'not ready to receive yet
    INTCON = 0  'kill any interrupts
   
Hserout "TEST", CrLf
   
    Gosub init_HC12  'init radio

    Hserout "READY", CrLf  'Needs HC-12 configured to show on live PC
   
Call spi_init()  'initialise spi -here SSPEN=1 sets the pin directions for SPI

'BMP280 INITIALISATION
   
    '0x60  'WRITE 0xe0 RESET ADDR [Is this needed?]
    '0xb6  '%10110110 RESET TO 0x00
   
    '0x74  'WRITE 0xF4 Control CTRL_MEAS reg addr
    '0x5f  '%01011111 T/ON P/ON 't_x2 px16 Normal Mode
   
    '0x75  'WRITE 0xF5 Control CONFIG reg addr
    '0x1c  '%00011100 osrs_t 0.5ms Table 11-11R filter x16 table 6
   

WaitMs 1000

Dim wr_adr As Byte  '0xxxxxxx
Dim rd_adr As Byte  '1xxxxxxx
Dim wr_data As Byte
Dim rd_data As Byte
Dim wr_dummy As Byte
wr_dummy = 0  'Dummy

main:  '/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

wr_adr = 0x74  'WRITE 0xF4 Control CTRL_MEAS reg addr
wr_data = 0x5f  '%01011111 T/ON P/ON 't_x2 px16 Normal Mode

Call sspbufspi_write()
Hserout "SSPBUF WRITE address  ", #wr_adr, CrLf
Hserout "SSPBUF WRITE data  ", #wr_data, CrLf

rd_adr = 0xf7  'TEST should READ 0x80

Call sspbufspi_read()
Hserout "SSPBUF READ address  ", #rd_adr, CrLf
Hserout "SSPBUF READ data  ", #rd_data, CrLf

Toggle rled
WaitMs 100


Goto main
   
End                                              

'----------- PERIPHERAL UTILITIES  -------------
'HC-12 INITIALISATION
init_HC12:
                'PRESS BUTTON (OR RADSET)
    radset = RADIO_COMMAND_MODE  'SET HC-12 COMMAND ON
    Hserout "AT+C002", CrLf  '433.800
    radset = RADIO_DATA_MODE  'SET HC-12 RUN ON
    Return
'------------------

Proc spi_init()  'looks like straight from the datasheet
'4620
TRISC.3 = 0  'SCK to Slave
TRISC.4 = 1  'MISO
TRISC.5 = 0  'MOSI

'MODE 0,0
SSPSTAT.SMP = 0  'Input data sampled at middle of data output time
SSPSTAT.CKE = 0  '1 Output data changes on clock transition from idle to active
SSPSTAT.5 = 0  'I2C only
SSPSTAT.4 = 0  'I2C only
SSPSTAT.3 = 0  'I2C only
SSPSTAT.2 = 0  'I2C only
SSPSTAT.1 = 0  'I2C only
SSPSTAT.BF = 0  'If SSPBUF=1=Full

SSPCON1.WCOL = 0  'Collision detect
SSPCON1.SSPOV = 0  'Overflow
SSPCON1.SSPEN = 1  'Configure SCK,SD0,SDI,/SS
SSPCON1.CKP = 1  '[0]  'Clock Idle high, Active low [Clock Idle Low, Active High]
SSPCON1.SSPM3 = 0  '0010 = SPI Master mode, clock = FOSC/64
SSPCON1.SSPM2 = 0
SSPCON1.SSPM1 = 1
SSPCON1.SSPM0 = 0

End Proc                                        
Proc sspbufspi_write()

altmtr_cs = 0
WaitUs 1
    SSPBUF = wr_adr  'Send address to WRITE
    wr_adr = SSPBUF
    While Not SSPSTAT.BF
    Wend
    SSPBUF = wr_data
    While Not SSPSTAT.BF
    Wend
    wr_data = SSPBUF
altmtr_cs = 1

End Proc                                        
Proc sspbufspi_read()

altmtr_cs = 0
WaitUs 1
    SSPBUF = rd_adr  'Send address to be READ
    rd_adr = SSPBUF
    While Not SSPSTAT.BF
    Wend
    SSPBUF = wr_dummy  '0x00
    While Not SSPSTAT.BF
    Wend
    rd_data = SSPBUF
altmtr_cs = 1

End Proc
 

Attachments

jjw

Joined Dec 24, 2013
823
These compiles:
Code:
Function HWSPI_Write(x as Byte) as Byte ' <--- Added the return value
  SSPBUF = x
  While Not SSPSTAT.BF
  Wend
End Function 

Function  HWSPI_Read( x as Byte) as Byte  ' x is address to read from
   SSPBUF=x
   While Not SSPSTAT.BF
   Wend

   SSPBUF= 0x00    ' dummy byte
   While Not SSPSTAT.BF
   Wend
   HWSPI_Read = SSPBUF
End Function
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
These compiles:
Code:
Function HWSPI_Write(x as Byte) as Byte ' <--- Added the return value
  SSPBUF = x
  While Not SSPSTAT.BF
  Wend
End Function

Function  HWSPI_Read( x as Byte) as Byte  ' x is address to read from
   SSPBUF=x
   While Not SSPSTAT.BF
   Wend

   SSPBUF= 0x00    ' dummy byte
   While Not SSPSTAT.BF
   Wend
   HWSPI_Read = SSPBUF
End Function
Hi J,
Thanks,
In #250 [x is either address or data] is this still the same?
When X is used for both functions, how do you set them separately? and remember which is which?
C
 

jjw

Joined Dec 24, 2013
823
Hi J,
Thanks,
In #250 [x is either address or data] is this still the same?
When X is used for both functions, how do you set them separately? and remember which is which?
C
It doesn't matter.
You should know, when writing data or address.
X is an internal variable of the function, which gets it's value, when the function is called.
Different functions can have the same name of a variable, but they won't get mixed.
You call the function with a value of either address or data.
For example:
adr=0x88
HWSPI_Write(adr)
or
HWSPI_Write(0x88)
or
data=0xF4
HWSPI_Write(data) etc.

Reading from an address.
data= HWSPI_Read(adr)
data= HWSPI_Read(0x88)
etc.
 
Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Hi,
Can a FUNCTION be CALLed in 2x different ways?

What would a CALL look like for 2xBYTES e,g,
[wr_adr = 0x74 'WRITE 0xF4 Control CTRL_MEAS reg addr]
[wr_data = 0x5f '%01011111 T/ON P/ON 't_x2 px16 Normal Mode]
or are they CALLed one after the other?

In this example there is an X also a MSG1 as a VARIABLE, where yours use all X's
or What am I doing wrong?
C.
 

Attachments

Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Hi J,
I've found a FUNCTION in a previous program, that I can copy it's shape, I'll give it a try.

EDIT: It now compiles :)
C.
 

jjw

Joined Dec 24, 2013
823
Hi,
Can a FUNCTION be CALLed in 2x different ways?

What would a CALL look like for 2xBYTES e,g,
[wr_adr = 0x74 'WRITE 0xF4 Control CTRL_MEAS reg addr]
[wr_data = 0x5f '%01011111 T/ON P/ON 't_x2 px16 Normal Mode]
or are they CALLed one after the other?

In this example there is an X also a MSG1 as a VARIABLE, where yours use all X's
or What am I doing wrong?
C.
Do you mean, that x is used elsewhere in the program?

A function can be made to write both address and data in one go.
Function HWSPI_Write( wr_address as Byte, wr_data as Byte) as Byte
-----
----
End Function

using it:
HWSPI_Write( adr, data)
or
HWSPI_Write(0x74, 0x5F)
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Do you mean, that x is used elsewhere in the program?

A function can be made to write both address and data in one go.
Function HWSPI_Write( wr_address as Byte, wr_data as Byte) as Byte
-----
----
End Function

using it:
HWSPI_Write( adr, data)
or
HWSPI_Write(0x74, 0x5F)
Hi J,
I see!
Thanks, I should be able to get it to work now, we'll see.
C
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Hi,
I'm trying to find an intermittent error, and it could be the SSPBUF exchange.
The peripheral in question is BMP280, which has a BIT: [ STATUS.3 ] When this is [ 0 ] the measurment is in its buffer, so can be READ.
READ needs a dummy [ 0 ] to exchange with the DATA.
The error is: sometimes [ STATUS.3 ] shows there is DATA and it shows when shown. Sometimes there is a [ 0 ]
I'm wondering if the [ 0 ] is the dummy [ 0 ] sometimes and not the DATA, could this be possible?
C
 
Top