Maker Pro
Maker Pro

Dyslexic Data sheets reading

Hi H,
I think these are for Arduino, so perhaps in 'C'. I can only read BASIC, so struggle a bit with them.

The Arduino libraries that you point to, are for the same device, so somewhere in there will be what I'm looking for, thanks.
I doubt that I can navigate to find what I'm looking for, so I'll just have to keep reading the Data sheet, till I get it.

Since posting this, I did move forward a little, by using a data analyser, now it looks like it is a timing issue. e,g, C/S and Clock timing.
Cheers, C.
 

Harald Kapp

Moderator
Moderator
So you are using the SPI interface, right?
So what you need to read is chapter 5.3.
First thing to note is the correct SPI mode. Only mode '00' or mode '11' work with this sensor. You need to set-up the master's SPI controller for one of these modes.
Next you can chose 3-wire or 4-wire mode (aka use 3 or 4 wires for SPI communication). I recommend you use 4-wire mode with separate lines foe CSB (chip select), SCK (clock), SDI (data input) and SDO (data output). You connect SDI of the sensor to SDO of the master (controller) and vice versa.
Timing is comparatively easy, see figure 9 of the datasheet. Your SPI controller in the microcontroller should handle this automatically. If you plan to control the pins programatically (in case you don't have an SPI controller in the micro) ensure that the data output is stable before the clock becomes active (active clock edge is rising).
Observe the note in the datasheet about the use of the MSB of the 8 bit register address which is not used as address bit but as R/W bit. So you have to construct the register address sent over the SPI bus from the lower 7 bit s of the register address and the R/W bit as shown in figure 10.

Hope that helps.
 
So you are using the SPI interface, right?
So what you need to read is chapter 5.3.
First thing to note is the correct SPI mode. Only mode '00' or mode '11' work with this sensor. You need to set-up the master's SPI controller for one of these modes.
Next you can chose 3-wire or 4-wire mode (aka use 3 or 4 wires for SPI communication). I recommend you use 4-wire mode with separate lines foe CSB (chip select), SCK (clock), SDI (data input) and SDO (data output). You connect SDI of the sensor to SDO of the master (controller) and vice versa.
Timing is comparatively easy, see figure 9 of the datasheet. Your SPI controller in the microcontroller should handle this automatically. If you plan to control the pins programatically (in case you don't have an SPI controller in the micro) ensure that the data output is stable before the clock becomes active (active clock edge is rising).
Observe the note in the datasheet about the use of the MSB of the 8 bit register address which is not used as address bit but as R/W bit. So you have to construct the register address sent over the SPI bus from the lower 7 bit s of the register address and the R/W bit as shown in figure 10.

Hope that helps.
Hi H,
Before looking at the D/S again, here's a quick answer.
I use 4 wire SPI communication.
What should I look at first?
I noticed the [output is stable] note in the D/S, how do I program for this? I have WAIT commands if needed.
I understand the READ WRITE BIT 7 setting.
C.
 
Hi H,
The attached [4 wire] is for setting up 3 or 4 wire mode. Which says [is determined by the value of SCK after the CSB falling edge]. How is this determined? See attached [SSPBUF AN] Does this give us a clue, it is a digital analyser view of the SPI signals.
C
 

Attachments

  • SSPBUF AN.jpg
    SSPBUF AN.jpg
    194.5 KB · Views: 3
  • 4 wire.jpg
    4 wire.jpg
    73.4 KB · Views: 2

Harald Kapp

Moderator
Moderator
Your timing is incorrect. Data must be stable during the active clock edge (rising), but isn't:
upload_2021-6-3_6-38-1.png
At the green mark data is stable. At the red marks data changes simultaneously to clock. This is not allowed an can lead to race conditions and unpredictable behaviour.
This is what your signals should look like:
upload_2021-6-3_6-41-5.png

I noticed the [output is stable] note in the D/S, how do I program for this? I have WAIT commands if needed.
Do you use a built-in SPI controller or do you program the sequence manually?

The attached [4 wire] is for setting up 3 or 4 wire mode. Which says [is determined by the value of SCK after the CSB falling edge]. How is this determined?
From the link to Wikipedia I gave you:
  • CPOL determines the polarity of the clock. The polarities can be converted with a simple inverter.
    • CPOL=0 is a clock which idles at 0, and each cycle consists of a pulse of 1. That is, the leading edge is a rising edge, and the trailing edge is a falling edge.
    • CPOL=1 is a clock which idles at 1, and each cycle consists of a pulse of 0. That is, the leading edge is a falling edge, and the trailing edge is a rising edge.
Therefore:
When CLK=0 after CSB goes low, CPOL = 0 and consequently SPI mode = 00.
When CLK = 1 after CSB goes low, CPOL = 1 and consequently SPI mode = 11
 
Your timing is incorrect. Data must be stable during the active clock edge (rising), but isn't:
View attachment 51960
At the green mark data is stable. At the red marks data changes simultaneously to clock. This is not allowed an can lead to race conditions and unpredictable behaviour.
This is what your signals should look like:
View attachment 51961


Do you use a built-in SPI controller or do you program the sequence manually?


From the link to Wikipedia I gave you:
  • CPOL determines the polarity of the clock. The polarities can be converted with a simple inverter.
    • CPOL=0 is a clock which idles at 0, and each cycle consists of a pulse of 1. That is, the leading edge is a rising edge, and the trailing edge is a falling edge.
    • CPOL=1 is a clock which idles at 1, and each cycle consists of a pulse of 0. That is, the leading edge is a falling edge, and the trailing edge is a rising edge.
Therefore:
When CLK=0 after CSB goes low, CPOL = 0 and consequently SPI mode = 00.
When CLK = 1 after CSB goes low, CPOL = 1 and consequently SPI mode = 11
Hi H,
I previously used the Oshonsoft SPI set-up (works ok) I now want to improve the system and program the sequence manually.

In SSPBUF AN #6, on the right second line it shows 0x58, which isthe I.D. of the peripheral, so the analyser etc is working, but as you say 'race conditions' show that the PIC is not READing correctly.

Your RED and GREEN lines are a good explanation.

Previously, I've seen CPOL setting in my programs, so next I'll look for an old OSH SPI program, and check how it was done.
Thanks, C.
 

Harald Kapp

Moderator
Moderator
I previously used the Oshonsoft SPI set-up (works ok) I now want to improve the system and program the sequence manually.
Laudable if you want to learn how to do it.
But in terms of efficiency and reliability the Oshonsoft library functions are probably your better choice. These should be optimized by the developers and proven to be good by many users. I doubt you can do much better than they do.
 
Laudable if you want to learn how to do it.
But in terms of efficiency and reliability the Oshonsoft library functions are probably your better choice. These should be optimized by the developers and proven to be good by many users. I doubt you can do much better than they do.
Hi H,
My project has developed over a few years, and I have only been able to get this far, by using forums like this. Along the way I get valuable help form people such as you.
I was previously helped get 2x PICs to 'talk' to each other and it was advised that the SSPBUF method is used over OSH SPI, but perhaps the CPOL is incorrect there too, but working. This is what I'm about to check.
C
 
Hi H,
We're getting there :)
I've been round the houses and back today, names have been changed, but the trail led back to my existing programs, where some settings in it need changing.
I'm using an 18F46K20 PIC and in it's D/S is SSPSTAT ans SSPCON1 where what was called CPOL CPHA is now called CKP and CKE (I think) Anyway I changed on of the BITs which moved the timing a bit, and now the PIC is READing the I.D. of the peripheral ok (First test)

I've got to have a break today, but should have it correct by tomorrow.
Cheers, C..
 

Attachments

  • SPI.jpg
    SPI.jpg
    318.6 KB · Views: 2
Thumbs up!
Hi H,
I tweaked the 3x timing settings in the CODE, just '1' more than when it errors, in some way.
___________________________________________________________
altmtr_cs = 0
WaitUs 1 '<1= Logic analyser 'The initial state of the CLK line does not match the settings.
SSPBUF = 0xd0 '0xd0 address of ID =0x58
data = SSPBUF
WaitUs 17 '<17= Incorrect result.
SSPBUF = 0x00
WaitUs 16 '<16= Incorrect result.
data = SSPBUF
altmtr_cs = 1
__________________________________________________________
So this is where it breaks. How much should I add to each WAITUS to be safe?
C.
 

Attachments

  • WAIT.jpg
    WAIT.jpg
    197.2 KB · Views: 2

Harald Kapp

Moderator
Moderator
You obviously use SPI mode 11 (clk = 1 when CS goes from 1 to 0).
The timing diagram looks perfect: data is stable during the active clock edge. So what is the problem? Incorrect data?
I assume you use the built-in SPI controller as I do not see any code for toggling the port pins.
The 'correct' way to control such an interface is not to add wait statements (although it can be done, I do not consider this good coding practice). Rather you wait in a loop for the SPI status bit to indicate correct transmission and reception of the data. That is this part in the code I will link below (example for read, write is similar):
Code:
unsigned char ReadSPI( void )
{
  unsigned char TempVar;
  TempVar = SSPBUF;        // Clear BF
  PIR1bits.SSPIF = 0;      // Clear interrupt flag
  SSPBUF = 0x00;           // initiate bus cycle
  while(!PIR1bits.SSPIF);  // wait until cycle complete
  return ( SSPBUF );       // return with byte read
}

I'm sorry for being able to help only on an abstract level as I haven't used PIC controllers. But the procedure is similar regardless of the type of controller. Maybe this link gives you more helpful background information?
 
You obviously use SPI mode 11 (clk = 1 when CS goes from 1 to 0).
The timing diagram looks perfect: data is stable during the active clock edge. So what is the problem? Incorrect data?
I assume you use the built-in SPI controller as I do not see any code for toggling the port pins.
The 'correct' way to control such an interface is not to add wait statements (although it can be done, I do not consider this good coding practice). Rather you wait in a loop for the SPI status bit to indicate correct transmission and reception of the data. That is this part in the code I will link below (example for read, write is similar):
Code:
unsigned char ReadSPI( void )
{
  unsigned char TempVar;
  TempVar = SSPBUF;        // Clear BF
  PIR1bits.SSPIF = 0;      // Clear interrupt flag
  SSPBUF = 0x00;           // initiate bus cycle
  while(!PIR1bits.SSPIF);  // wait until cycle complete
  return ( SSPBUF );       // return with byte read
}

I'm sorry for being able to help only on an abstract level as I haven't used PIC controllers. But the procedure is similar regardless of the type of controller. Maybe this link gives you more helpful background information?
Hi H,
Your abstract method is fine, as long as it's one step at a time.
My problem is getting into loops, where I don't know where to get out.
Your RED line GREEN line view in #7 broke weeks of looping, where I then got results.

I'll have to go back and check which MODE I'm using later, after working on the 'correct' way. Remind me when it's done, please.

Regarding your link, in one eye and out of the other, I'm afraid, far too wordy and uses a different language.

There was a WEND WHILE in this section of CODE previously, I think a BIT switched it. I'll investigate.

I also use a different forum Allaboutcircuits, where they are familiar with this project, and Oshonsoft BASIC, so I'll ask there.
Cheers, C.
 

Harald Kapp

Moderator
Moderator
As I noted in post #4, the sensor operates in eiter SPI mode "00" or "11". Excerpt from the datasheet:
5. Digital interfaces
The BMP280 supports the I²C and SPI digital interfaces; it acts as a slave for both protocols. The
I²C interface supports the Standard, Fast and High Speed modes. The SPI interface supports
both SPI mode ‘00’ (CPOL = CPHA = ‘0’) and mode ‘11’ (CPOL = CPHA = ‘1’) in 4-wire and 3-
wire configuration.
But you seem to use mode "10" (CKP=1, CKE=0) which wasn't obvious to me from post #13 but is clearly shown in post #16. This may be the cause for your problems. Correct the SPI mode to "00" or "11".
 
As I noted in post #4, the sensor operates in eiter SPI mode "00" or "11". Excerpt from the datasheet:

But you seem to use mode "10" (CKP=1, CKE=0) which wasn't obvious to me from post #13 but is clearly shown in post #16. This may be the cause for your problems. Correct the SPI mode to "00" or "11".
Hi H,
I was re-checking all this and found the same, which is confusing as it's working, but I understand that it needs correcting.

I noticed that the PIC should follow the peripheral set-up, and as you say the BMP280 is different, so I'll go through it all again and unravel it.
First I'll clarify the difference between CPOL CPHA CKP and CKE. and work from there. It's all here, so just a bit of concentration needed.
Cheers, C.
 
Top