Syncing SSPBUF in Oshonsoft.

jjw

Joined Dec 24, 2013
823
Hi,
I can't understand, why if the 1st CHAR in the SLAVE BUFFER is £ and the 1st CHAR in MASTER BFFER is 1, and the SLAVE CS goes ON, then the SPI CLOCK starts, why doesn't the 1st step, show a £ appear in the MASTER and 1 arrive in the SLAVE, then the next CHARS in sequence of each BUFFER?
C
£ must be in slave SSPBUF before 1 is written to master SSPBUF.

Have you noticed from the manual:
When the SPI is in Slave mode, with
the SS pin control enabled,
(SSPCON<3:0> = 0100), the SPI
module will reset if the SS pin is set to
VDD.

So if you switch SS on and then off the setup of the slave SPI is lost.
Are there other SPI slaves on the bus which must be selected alternately?
Otherwise SS can be permanently ON.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,831
Sorry!! What do you mean with


You cannot use serout here.
Hi I,
A slight mistake! I meant an HSEROUT. Once each side has swapped their SPIs, I can (HSEROUT) via radio, e,g, what's in a BUFFER to my computer screen as a running check. I move them about, where ever I need them for troubleshooting. You can see results in previous posts.
Are you saying that I can't have an HSEOUT in the SPI LOOP? Note: although it looks like a list, it is single BYTEs one after the other.
C
 
Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
3,831
£ must be in slave SSPBUF before 1 is written to master SSPBUF.

Have you noticed from the manual:
When the SPI is in Slave mode, with
the SS pin control enabled,
(SSPCON<3:0> = 0100), the SPI
module will reset if the SS pin is set to
VDD.

So if you switch SS on and then off the setup of the slave SPI is lost.
Are there other SPI slaves on the bus which must be selected alternately?
Otherwise SS can be permanently ON.
Hi J,
Yes, The S2M list is in the BUFFER before C/S

Re: (SSPCON<3:0> = 0100) The C/S-SS, is switched ON before the SPI 35 CHAR exchange, and OFF afterwards.
There are multiple SLAVES, but they only show the MOSI MISO, when their C/Ss are ON. I can see their HSEROUTs though.
Here:

Here is the starting HSEOUTs showing the ALT parameters, then the last 8 CHARs of the LAT section, and noticed that over multiple times, it always shows the same for the first pass. This gives me a clue!
C
 

Attachments

Ian Rogers

Joined Dec 12, 2012
1,136
No... Serout and Hserout are for usart only.. SPI uses SPIReceive and SPISend if you use hserout the data will be corrupt as there is too many bits.. Hserout will send 9.5 bits and SPISend will send 8 bits
 

Ian Rogers

Joined Dec 12, 2012
1,136
If you use SPI then use hserout there should't be a problem The usart uses RCREG and SPI uses SSPBUF so shouldn't be a problem

Forget my last comment, I thought you were using the USART to send via SPI... Clearly not the case
 

sagor

Joined Mar 10, 2019
1,050
Putting a Hserout statement in the middle of a SPI loop may in fact hinder the SPI, depending on the SPI speed. Sending a single character out with HSerout takes at least 1ms. If the SPI characters come in faster than that (time per character), you may risk losing characters or have other timing issues.
You should only use serial debugging in sections of code that are not dependent on timing, not in time critical loops.
You could use serial outputs only if using a routine to put the character into the TX serial buffer if it is empty and trigger the UART, which will run the serial data on its own. Of course, in a SPI loop, if the TX buffer is not empty yet, you cannot send any more characters, as the SPI needs to be processed immediately.
You have to remember that serial output for debugging can badly affect the code you are trying to debug. Serial output is very slow compared to the PIC processing of the rest of the code.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,831
Putting a Hserout statement in the middle of a SPI loop may in fact hinder the SPI, depending on the SPI speed. Sending a single character out with HSerout takes at least 1ms. If the SPI characters come in faster than that (time per character), you may risk losing characters or have other timing issues.
You should only use serial debugging in sections of code that are not dependent on timing, not in time critical loops.
You could use serial outputs only if using a routine to put the character into the TX serial buffer if it is empty and trigger the UART, which will run the serial data on its own. Of course, in a SPI loop, if the TX buffer is not empty yet, you cannot send any more characters, as the SPI needs to be processed immediately.
You have to remember that serial output for debugging can badly affect the code you are trying to debug. Serial output is very slow compared to the PIC processing of the rest of the code.
Hi S,
I removed the HSEROUT, and used a data analyser instead for checking.
It now returns what the MASTER is sending, 123.....34
I've since tried 20 different anagrams of the SPI procedure, and it sometimes works, then reverts to 123...34 from MASTER.

(SPI is easy, until it's not!)
C.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,831
Hi,
Hi S,
I removed the HSEROUT, and used a data analyser instead for checking.
It now returns what the MASTER is sending, 123.....34 instead of the expected GPS BUFFER STRING
I've since tried 20 different anagrams of the SPI procedure, and it sometimes works, then reverts to 123...34 from MASTER.

(SPI is easy, until it's not!)
EDITED:
C.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,831
Hi,
I've gone round the houses, trying to get this to work (properly), and just been reminded to use I's (set the SLAVE BUFFER in a particular address) method. I'm now concentrating on this now.

I used an AI and asked how to do it, and it helped, but kind of gave ambiguous replies.
It suggested use POINTERS and Oshosoft has them, and they appear to be 16BIT
It also suggested to use the VARIABLE in MASTER.

I'm experimenting round this.
Here is the example from the D/S, I'm find it difficult to see what it's saying, can someone comment each line please?
The actual BUFFER VARIABLE is S2M(35) in the SLAVE
----------------------------------------------------------------------
Any integer variable can be used as a pointer to user RAM memory when it is used as an argument of POINTER function. The value contained in the variable that is used as a pointer should be in the range 0-4095. Here is one example:
Dim x As Word
Dim y As Byte
x = 0x3f
y = Pointer(x)
y = y + 0x55
x = x - 1
Pointer(x) = y
y = 0xaa
x = x - 1
Pointer(x) = y
----------------------------------------------------------------------------
EDIT:
Here's my first attempt: I find it difficult to check it!!
Dim s2m(35) As Word 'Variable name
Dim s2m_pnt As Byte 'Variable pointer
s2m = 0x3f 'Variable pointer address
s2m_pnt = Pointer(s2m)
s2m_pnt = s2m_pnt + 0x55
s2m = s2m - 1
Pointer(s2m) = s2m_pnt
s2m_pnt = 0xaa 'Variable pointer address
s2m = s2m - 1
Pointer(s2m) = s2m_pnt

C
 
Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
3,831
Hi,
I tried the above in the 2x progs and all is completely dead.
It looks like it's best try 2x simple only POINTERS and SPI progs.
C
 

Thread Starter

camerart

Joined Feb 25, 2013
3,831
Hi,
I tried the Oshonsoft POINTER example from it's D/S, but it isn't very clear, so (with help I think I've commented the first few lines. Correct me if it's wrong!
-----------------------------------------------
'***********POINTER*******************
'any variable that is declared As A Byte Or Word variable using Dim statement can be used As A
'Pointer To user RAM memory when it is used As an argument of Pointer Function. The value
'contained in the variable that is used As A Pointer should be in the range 0-511. Here is one
'example:

'Dim x As Word'Is the address where a BYTE/WORD is stored
'Dim y As Byte'
'x = 0x3f
'y = Pointer(x)
'y = y + 0x55
'x = x - 1
'Pointer(x) = y
'y = 0xaa
'x = x - 1
'Pointer(x) = y

Dim s2m As Byte @ 0xaa
Dim y As Byte

x = 0x00c 'Memory location of stored BYTE e,g, F
Pointer(s2m) = "F" 'Write the BYTE to memory address X
y = Pointer(s2m) 'Y is assigned the returned value of the POINTER FUNCTION given the argument (X), X is a memory address. BYTE at address X (ARGUMENT)
-----------------------------------------------------------------------------------------------
I then tried the SIM, with my variables S2M (SLAVE to MASTER) for SPI.
Usually, I declare the DIM as e,g, S2M(35) for the DATA to be sent to MASTER.
This line [ Dim s2m As Byte @ 0xaa ] was ok, but [ Dim s2m(35) As Byte @ 0xaa ] of course wasn't because it is not 1x BYTE.
Any ideas?
C
 

sagor

Joined Mar 10, 2019
1,050
Don’t use pointers. That points to a specific ram address and if other variables are using that space, you corrupt everything. The only way you could use pointers is to find the address assigned to a variable array, and map the pointer to it. But that is useless as you can address the variable array directly with an array index anyway.
ie: buf(x)
 

Thread Starter

camerart

Joined Feb 25, 2013
3,831
Don’t use pointers. That points to a specific ram address and if other variables are using that space, you corrupt everything. The only way you could use pointers is to find the address assigned to a variable array, and map the pointer to it. But that is useless as you can address the variable array directly with an array index anyway.
ie: buf(x)
Hi S,
I'm trying to connect a number of loose ends, that contributers have sent over the project, e,g, POINTER, BYREF, etc
I've found out how to set a BYTE adress in OSH [ Dim s2m As Byte @ 0xaa ] which avoids being over written I think.
This doesn't allow e,g, [ DIM s2m(35) ] as it's an array of BYTES.

I'm not sure how BYREF works, and have asked an AI to explain simply, but it's complicated.

The master READ CODE looks like this:
--------------------------------------------------------
Function periph_rd(rd_adr As Byte) As Byte
SSPBUF = rd_adr
While Not SSPSTAT.BF 'PIC
Wend
While STATUS.3 'STATUS.3=0 When register ready. When Must have this or WAIT
Wend
SSPBUF = 0 'Dummy BYTE
While Not SSPSTAT.BF 'PIC
Wend
periph_rd = SSPBUF
End Function
------------------------------------------------------------
The READ ADDRESS is in RED and must be looped through 35 BYTES for the ARRAY.

EDIT: I'll see a mate of mine tomorrow, and I think he may be using your method.

C
 
Last edited:

sagor

Joined Mar 10, 2019
1,050
There is no need to set any address, the compiler will assign ram addresses to variables as it sees fit. I doubt you can do any better, but in fact make things worse.
ByRef is a means of passing an argument to a function or subroutine. Normally you pass a fixed variable "value" to the routine. ByRef passes the address of the variable, allowing the function/subroutine to read amd modify that value, even before the function exits. As per Oshonsoft help manual:
" When ByRef prefix is used to pass a variable argument to a procedure, the procedure will use the input variable value, but it can also change the value of the variable during the procedure execution. The calling variable will be exposed to change. "
You would use ByRef only in special circumstances, where you want the passed variable(s) to be modified by the routine it is calling, regardless of what the function/subroutine/procedure does or what value it returns (like a Function).
 

Thread Starter

camerart

Joined Feb 25, 2013
3,831
There is no need to set any address, the compiler will assign ram addresses to variables as it sees fit. I doubt you can do any better, but in fact make things worse.
ByRef is a means of passing an argument to a function or subroutine. Normally you pass a fixed variable "value" to the routine. ByRef passes the address of the variable, allowing the function/subroutine to read amd modify that value, even before the function exits. As per Oshonsoft help manual:
" When ByRef prefix is used to pass a variable argument to a procedure, the procedure will use the input variable value, but it can also change the value of the variable during the procedure execution. The calling variable will be exposed to change. "
You would use ByRef only in special circumstances, where you want the passed variable(s) to be modified by the routine it is calling, regardless of what the function/subroutine/procedure does or what value it returns (like a Function).
Hi S,
In your reply, you didn't mention the MASTER/SLAVE pair. The MASTER must know where the SLAVE BUFFER address is previous to switching on. Is it possible that the compiler could use different addresses. I tried allowing the compiler to do it's thing, it didn't sync, so MASTER results were not in their correct places.
A previous reply suggested the SLAVE sets the address of the BUFFER, so this can be set in the MASTER.
I'm happy to try any CODE pairs you post.
I will see a mate tomorrow, and we may find the 'answer'?
EDITED
Thanks, C.
 
Last edited:

sagor

Joined Mar 10, 2019
1,050
Your buffers are in your code, and you control how you point to the buffer array with your code. SPI has nothing to do with that, other than it is a means of transfering bytes of data. There may be a case where one sends an address to read a specific RAM or register location, and get a response, but that is again controlled by your code.
You may be confusing buffer storage (Oshonsoft byte array) with SPI low level protocol, two different things. It is up to your code to synchronize what is being sent and how/where to store it. You have to have a data transfer protocol where you can determine what is going on, what data is being sent and when, rather than guessing. Ignore incomplete data, re-sync your transfers with known indicators or flags.
Your slave transfer should start from a known position (known code function) when enabled by master.
 

Ian Rogers

Joined Dec 12, 2012
1,136
The reason I mentioned "setting the address" was purely so the master could ASK for the address and receive the correct byte.

In any SPI device EEprom, RTC etc.. data is in a specific address, I was trying to stop confusion.. This is how I would do it.
Remember! Oshonsoft has no software stack, or linear memory so I was trying to eliminate that type of error.

That of course is irrelevant now as he can access the string in bytes thus... myString(address).
 

Thread Starter

camerart

Joined Feb 25, 2013
3,831
The reason I mentioned "setting the address" was purely so the master could ASK for the address and receive the correct byte.

In any SPI device EEprom, RTC etc.. data is in a specific address, I was trying to stop confusion.. This is how I would do it.
Remember! Oshonsoft has no software stack, or linear memory so I was trying to eliminate that type of error.

That of course is irrelevant now as he can access the string in bytes thus... myString(address).
Hi I,
I'm glad you're here, can you clarify a couple of questions please?
I understood your 'set the address' idea, and I can now do this, but I've only managed 1x BYTE at a particular address, not an array, as s2m(35).

If I check a SLAVE prog with the sim, I can see the addresses where the array is stored. Can I simply read that first address in the SLAVE and add it into the MASTER SPI READ, then increment through the 35?

Am I correct that if the SLAVE prog is changed, so may the address where the S2M array is stored?
C
 
Last edited:

Ian Rogers

Joined Dec 12, 2012
1,136
That was my worry... But it matters not. Say you send send "0x0" from the master, you can send send "S2M(0)" on the next run.

Master sends 0x0 receives dummy.
Master sends 0x1 receives S2M(0).
Master sends 0x2 receives S2M(1).
.
.
Master sends 0x23 receives S2M(0x22)... Done.

so use the address to send the correct array element.
 
Top