Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

WRITE READ SPI DATA in Oshonsoft

camerart

Well-Known Member
Hi, EDIT: As addresses appear to be a bad idea, I've changed the thread title
I'm setting up a SLAVE PIC to another MASTER PIC, and want to put a STRING of DATA into a specific memory locations.
So far I've succeded in adding the DATA into EEPROM memory, but is this the best place?
The DATA will be updated constantly and very fast.

Camerart.
 
Last edited:
Many PIC's have two serial ports, and it's always a good idea to choose one that does.

It's also very trivial to use a simple software serial port to output debugging data, and it just requires a single output pin - I add one on pretty well everything I build, and use a hardware serial port if there's a spare one (the PPI facility is very useful for moving peripherals to the pin you want).

You want to avoid 'blocking' in your routines, as you've probably got other things going on that need servicing, rather than sat waiting for something to happen. By using interrupts and flags your main routine can just loop round waiting for flags to appear.

I would also suggest writing routines that use the size of the data for transmission and reception, rather than having to hardcode FOR loops in the program.
Hi N,
I have to shop with economy in mind, and there are many components, and peripherals invloved. This PIC was chosen because it can READ incremental encoders.

The used to be a switch chip that was selected for each RX input, but that was ironed out during development, and here we are.

There are a few INTERRUPTS in the CODES (4xCODES for the project)

I'm not good at programming, and all of the technical CODE has been kindly written for me, so this is how the MAIN CODEs work, with a bit of adjustment from me.
C
 
Hi,
Carrying on with my idea. (To emulate other peripherals)
I've succeded in READing the GPS and PARSEing it including the other DATA into a memory string.
Then READ and sent to a terminal so I can check it against the GPS and incremental encode etc, in the SLAVE.
It's working :)

Next get the MASTER to request each momory DATA using SSPBUF, as above.
C
 
but I never got the DATA to be synchronised, and my tests seemed to suggest it was timing related,
That's one of the issues I alluded to in my last post.

When you have a master-slave SPI configuration, the code on the master needs to be different than if you have a normal hardware-based SPI device. The master controls the transfers, so the poor slave is at the mercy of the master code. For each byte transferred the master has to allow the slave time to receive and process the byte before it sends/receives the next byte. Since the master never knows what the slave is doing at the time, this delay needs to be long and you need to cross your fingers and hope that you've guessed right.

You also have to create a method of indicating to the slave when a new command begins/ends so that you can keep the two sides in sync. You can use the CS from the master but that involves having the slave monitor the pin and not using it to frame each byte.

You also have to ensure that the slave is initialized and ready before the master starts up.

All of this makes the communications VERY fragile and prone to failure. One wrong move and you're hosed until you cycle power.

I usually add an additional ready/busy line from the slave back to the master, and arrange the line to be automatically driven by a CCP module counting the SPI clock transitions on the slave. At least that way the master has some feedback as to what the slave is doing.

This is not for someone with limited experience. I stilll think you've made life MUCH more difficult for yourself by splitting it into so many different processors... you've just moved the problems to all the inter-processor communications paths, but that's just me.
 
Last edited:
Another thing...

From looking at the code you don't appear to be using the SPI SS slave select pin. You should. As the master lowers/raises this pin around every byte transfer it re-syncs the bit counter. If you don't use it then if you get one clock glitch on the slave you will be out of sync forever.

This can occur right from startup as the master and slave setup their SPI hardware... without it you're at the mercy of which side powers up first and initializes its pins.

You can look at the TB3265 app note for some ideas, but even this glosses over many of the issues I've pointed out, simply stating things like "A slave must always be available and has to wait until the master pulls its SS channel low" without any hints as to how to go about doing that.
 
Another thing...

From looking at the code you don't appear to be using the SPI SS slave select pin. You should. As the master lowers/raises this pin around every byte transfer it re-syncs the bit counter. If you don't use it then if you get one clock glitch on the slave you will be out of sync forever.

This can occur right from startup as the master and slave setup their SPI hardware... without it you're at the mercy of which side powers up first and initializes its pins.

You can look at the TB3265 app note for some ideas, but even this glosses over many of the issues I've pointed out, simply stating things like "A slave must always be available and has to wait until the master pulls its SS channel low" without any hints as to how to go about doing that.
Hi T,
As you know I've been playing with writing and reading memories, but even though it looked like I was succeding, I'm not sure quite, what was happening, because the Oshonsoft simultator drop downs, didn't confirm my actions.

You looked at the CODE, I pressume you mean at #19. I've been using itterations around this CODE fro months and as mentioned , getting out of sync.

I'm now going back to this type of CODE, which work (not in sync) to try your suggestions in more detail.

The MASTER does use a C/S-SS which can interrupt the SLAVE at any time, while other things are going on in the LOOP.

The DATA has been PARSED into an array (below). The DATA I'm interested in tranferring is S2M(). (SLAVE 2 MASTER)

In the #19 CODE are lines:
------------------------------------
While Not SSPSTAT.BF
Wend
-------------------------------
at both sides of the SPI. Does this do the job of the WAIT that you mentioned?

Looking at the CODES in #19, remembering that there is a C/S, how would you change it?
C



Code:
's2m(0) = "£"  '£  [TOT 35 BYTES ]
's2m(1) = gps(7)  'Time
's2m(2) = gps(8)  'Time
's2m(3) = gps(9)  'Time
's2m(4) = gps(10)  'Time
's2m(5) = gps(11)  'Time
's2m(6) = gps(12)  'Time
's2m(7) = gps(14)  'Time
's2m(8) = gps(15)  'Time
's2m(9) = gps(19)  'Lat
's2m(10) = gps(20)  'Lat
's2m(11) = gps(21)  'Lat
's2m(12) = gps(22)  'Lat
's2m(13) = gps(24)  'Lat
's2m(14) = gps(25)  'Lat
's2m(15) = gps(26)  'Lat
's2m(16) = gps(27)  'Lat
's2m(17) = gps(27)  'Lat
's2m(18) = gps(28)  'Lat
's2m(19) = gps(30)  'N
's2m(20) = gps(32)  'Lon
's2m(21) = gps(33)  'Lon
's2m(22) = gps(34)  'Lon
's2m(23) = gps(35)  'Lon
's2m(24) = gps(36)  'Lon
's2m(25) = gps(38)  'Lon
's2m(26) = gps(39)  'Lon
's2m(27) = gps(40)  'Lon
's2m(28) = gps(41)  'Lon
's2m(29) = gps(42)  'Lon
's2m(30) = gps(44)  'W
's2m(31) = POSCNTL  'QEIDEGLB
's2m(32) = POSCNTH  'QEIDEGHB
's2m(33) = 12  'Bat volt
's2m(34) = 123  'Spare DATA
 
Does the master CS output connect to the slave SPI SS in pin?
What is the slave SPI setup? I assume it doesn't enable this pin.

The BF flag does nothing to help with any of this, and having an interrupt line from the master doesn’t help any either.
 
"The MASTER does use a C/S-SS which can interrupt the SLAVE at any time, while other things are going on in the LOOP."

Is that true?
I thought the only thing that SS does, is to connect the slave to the SPI bus.
 
Does the master CS output connect to the slave SPI SS in pin?
What is the slave SPI setup? I assume it doesn't enable this pin.

The BF flag does nothing to help with any of this, and having an interrupt line from the master doesn’t help any either.
Hi T,
Yes the MASTER C/S PIN conntects to the TX PIN, which is also the SS PIN on the SLAVE.

Here is the SLAVE set-up:

Here is a digital analysis of the result:
It shows 36 LOOPs (including the initial DUMMY) for the 35xBYTES.
So 36 LOOPS of 36 BYTES, which is wrong! It should be 1x LOOP of 36xBYTES. Note the correct ARRAY is at position 35?? NOTE: the TIME at the moment.
C

Code:
Proc init_spi()  'PIC 18F4431
'4431
TRISC.6 = 1  '4431_CS=1
TRISD.3 = 1  'SCK from MASTER ******INPUT*****
TRISD.1 = 0  'MISO  ****** OUTPUT *******
TRISD.2 = 1  'MOSI  ****** INPUT *******

'MODE 0,0
SSPSTAT.SMP = 0  'Input data sampled at middle of data output time ** not about clock generation **
SSPSTAT.CKE = 0  '0 Output data changes on clock transition from active to idle ** AS ABOVE **
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

SSPCON = 0  'RESET THE CONTROL REGISTER **************************************ADDED
SSPCON.WCOL = 0  'Collision detect
SSPCON.SSPOV = 0  'Overflow
SSPCON.SSPEN = 1  'Configure SCK,SD0,SDI,/SS ** HAS TO BE 1. To reset or reconfigure SPI mode, clear the SSPEN bit,
'reinitialize the sspcon registers And Then set the SSPEN Bit from the datasheet !!!!!!!!!!!!!!!!
SSPCON.CKP = 0  '0 = Idle state for clock is a LOW level
SSPCON.SSPM3 = 0  '0100 = SPI SLAVE mode, clock = FOSC/64
SSPCON.SSPM2 = 1
SSPCON.SSPM1 = 0  'SLAVE MODE
SSPCON.SSPM0 = 0
End Proc
 

Attachments

  • Pound.jpg
    Pound.jpg
    180.7 KB · Views: 125
"The MASTER does use a C/S-SS which can interrupt the SLAVE at any time, while other things are going on in the LOOP."

Is that true?
I thought the only thing that SS does, is to connect the slave to the SPI bus.
Hi J,
All true, there is a LOOP in both MASTER and SLAVE, I was referring to the SLAVE LOOP, which is interrupted by the SS PIN. so actually there is nothing going on while interrupted!
C
 
The SPI SS input doesn't generate an interrupt. It must be controlled by code in the master.
The slave SSP is setup to use the SS pin (mode bits = 0100).

If the master has code to use the output then that will sync the clock on each byte transfer, but it will do nothing to sync the entire block transfer or control the timing. As I said, that's entirely controlled by the master.

PS - setting SSPCON.SSPEN = 1 should be the last thing done in that init routine.
 
Hi J and P,
The C/S enables the SLAVE SPI HW.

How can the MASTER control the SYNC?
When I tried SPI initially, "MESSAGES" were used instead of an ARRAY. Which is the best method?
C
 
Last edited:
How can the MASTER control the SYNC?
Without additional hardware it can't. And really what you need is for the slave to control the sync of transfers.

The master has no idea when/if the slave can accept bytes... it will quite happily send data even if there's no slave there, and it'll send it at the speed it wants to. The slave has no buffering so if the master sends two bytes faster than the slave accepts them then data is lost and you're out of sync at the message level, and the master has no way of knowing this.

That's the problem with master-slave SPI. The master has complete control over the transfers, but it has no feedback mechanism. Basically you need a signal back to the master for the slave to say "I'm ready to accept data".

I don't know that there's a different between messages and arrays. To me, an array of data is a "message". That's not your problem.
 
Looking back at some of those posts from 10 years ago on AAC vs your current code, it appears you've changed the SPI setup (it's no longer mode 0,0) and removed all the delays in the master routines. The SPI slave also changes from using hardware SS to not using SS in some of those posts, so it's hard to track what "used to work".

The delays in the master are important. They give the slave a chance to react, although you never know if it's "good enough" so they'll be unreliable and eventually fail at some point.
 
Without additional hardware it can't. And really what you need is for the slave to control the sync of transfers.

The master has no idea when/if the slave can accept bytes... it will quite happily send data even if there's no slave there, and it'll send it at the speed it wants to. The slave has no buffering so if the master sends two bytes faster than the slave accepts them then data is lost and you're out of sync at the message level, and the master has no way of knowing this.

That's the problem with master-slave SPI. The master has complete control over the transfers, but it has no feedback mechanism. Basically you need a signal back to the master for the slave to say "I'm ready to accept data".

I don't know that there's a different between messages and arrays. To me, an array of data is a "message". That's not your problem.
Hi T,
Ok, I'll keep trying to find the key.

The 'message' method, uses a message STRING, where the ARRAY uses an array of BYTES.
C
 
Looking back at some of those posts from 10 years ago on AAC vs your current code, it appears you've changed the SPI setup (it's no longer mode 0,0) and removed all the delays in the master routines. The SPI slave also changes from using hardware SS to not using SS in some of those posts, so it's hard to track what "used to work".

The delays in the master are important. They give the slave a chance to react, although you never know if it's "good enough" so they'll be unreliable and eventually fail at some point.
Hi T,
It's difficult looking back, as I keep doing too, as lots of things have been suggested and tried since then. The 'old' one I just looked at was a SLAVE program, and it was set 0100 SLAVE MODE.

Delays were suggested a day or so ago, and I replied does the WHILE/WEND do that job, I think you answered, it's different?

The 'message' method used then was reliable, but I'm not sure it can be applied here, with a STRING of BYTES?

I also notice one of the settings, not used no, I think it was WCOL, but there may be others.
C
 
The 'message' method used then was reliable,
None of the methods you've shown so far are what I would call 'reliable'.
They may work for simple examples but they won't be when you add it to your app program code.
That's why I haven't bothered correcting the examples.

Strings and bytes and messages are all the same thing when it comes to transferring data.
No trying to be rude, but why would a WHILE/WEND do anything regarding the use of delays?

You're really out of your comfort zone here. I expect you'll still be working on this in another 10 years.
 
None of the methods you've shown so far are what I would call 'reliable'.
They may work for simple examples but they won't be when you add it to your app program code.
That's why I haven't bothered correcting the examples.

Strings and bytes and messages are all the same thing when it comes to transferring data.
No trying to be rude, but why would a WHILE/WEND do anything regarding the use of delays?

You're really out of your comfort zone here. I expect you'll still be working on this in another 10 years.
Hi T,
Ok, I'll have to try different methods. Yes, examples may waist your time, but ideas will help.
You can be as rude as you like, as long as it's constructive :)

The WHILE/WEND was to delay, while the buffer fills, so it may have helped.

I've been out of my confort zone, since I started programming in the 80s, so another 10 years will be normal.
Cheers, C
 
Hi,
You're really out of your comfort zone here. I expect you'll still be working on this in another 10 years.

Or perhaps 1 day, I think I've done it!
I added a wire between SLAVE and MASTER, as a kind of reverse C/S. (S2M_WIRE)
Now when the MASTER C/S goes ON, it switches on the SLAVE SPI.
Once the SLAVE C/S goes ON, the S2M_WIRE goes ON.
The MASTER WHILE/WENDS until it 'sees' the S2M_WIRE go ON, then carries on through its 35xBYTES od DATA.
It now is synced.
C
 

Latest threads

New Articles From Microcontroller Tips

Back
Top