- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I have two PSoC4 L-Series Pioneer Kits (CY8CKIT-046) that I need to make talking to each other on a SPI bus. I found good sample code CE224339_PSoC4_SPI_Master_Polling01
and
CE224463_PSoC4_SPI_Slave_Polling01
that seem pretty simple and actually work. (They are located in the samples/SPI_polling folder in the workspace bundle that is attached to this discussion.)
Then I changed the code a bit to send more data (13 bytes). If data transmission is successful and sent data matches the received data then I lit the blue LEDs on the master and slave boards (in the niko_proj/SPI_polling_scb folder). All of this seems to work fine.
However, I need to use non SCB SPI components. So I mimicked the projects from niko_proj/SPI_polling_scb into niko_proj/SPI_polling_non_scb folder, and used non SCB components with their API calls in main.c. Everything builds fine, but the slave doesn't receive anything from master now.
Please help!
The workspace bundle is attached.
Thanks!
Nikolay
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nikolay-san,
With the help of user_78878863-san, I could figure out what the problem was.
For SPIS_PutArray(), we needed to do
SPIS_WriteTxDataZero(buffer[0]) ;
SPIS_PutArray( &buffer[1], size_of_buffer - 1 );
This was described in the datasheet of SPIS, which I failed to find.
========================
void SPIS_WriteTxDataZero(uint8/uint16 txData)
Description:
Places a byte/word directly into the shift register for transmission.
This byte/word will be sent to the master device during the next clock phase.
Parameters:
uint8/uint16: txData: The data value to send across the SPI
Side Effects:
Required for modes where CPHA == 0 where data must be in the shift register before the first clock edge.
Firmware must control this if there is already data being shifted out and if there is more
========================
Meantime, during the debugging I organized names of some buffers
as my memory can not put up with the maze of tmp, dummy... etc.
So I name buffers for SPI_Master as mTxBuffer, mRxBuffer, mFillBuffer
and buffers SPI_Slave sTxBuffer, sRxBuffer, sFillBuffer.
Master TeraTerm log
Slave TeraTerm log
Best Regards,
11-Oct-2018
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
As I don't have CY8CKIT-046, I tried with CY8CKIT-044,
First I noticed that you set the input pin types High impedance digit,
so I changed it to either resistive pull down or up depending on the condition(s) of pins.
Then I noticed that the API of non-scb SPI modules are using interrupts,
so I enabled global interrupt at the beginning of both main.c.
And now it seems to be working.
Master pins
Slave pins
modified slave's main.c
modified master's main.c
Oscilloscope wave mosi, miso, sclk, ss
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Thanks again for your help! I am sorry that I have to bug you with this. I was assigned to do this at work and I have zero experience doing anything like this: I am not an electrical engineer and don't have any experience writing embedded code. So I am desperate for any help that I can get. Thank you so much for doing this for me!
I made the changes that you recommended and they helped. Now it looks like master and slave receive data from each other. The first transmission from master to slave looks good: all bytes received and they matched to what was sent by the master. Then I noticed the function that received data SPIS_WaitForCommand() would stuck and never return. Declaring tmpBuffer static seems fixed the problem for some reason.
Also, other than the very first transmission from master to slave, the rest do not look good: data are received by slave, but it doesn't match to what master sends. Same problem for master: received data doesn't match to the slave's TX buffer.
Do you have any idea's why the data is corrupt after the very first transmission?
Thanks you!
Nikolay
P.S.
I re-attached my workspace to the latest version in the original post
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nikolay-san,
I tried this by myself and found that SPIS_PutArray() is generating
data off by 1. So I created a question/discussion below.
Strange behavior of SPIS_PutArray()
Hopefully someone can teach/help us how to fix/workaround this problem.
Best Regards,
10-Oct-2018
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nikolay-san,
With the help of user_78878863-san, I could figure out what the problem was.
For SPIS_PutArray(), we needed to do
SPIS_WriteTxDataZero(buffer[0]) ;
SPIS_PutArray( &buffer[1], size_of_buffer - 1 );
This was described in the datasheet of SPIS, which I failed to find.
========================
void SPIS_WriteTxDataZero(uint8/uint16 txData)
Description:
Places a byte/word directly into the shift register for transmission.
This byte/word will be sent to the master device during the next clock phase.
Parameters:
uint8/uint16: txData: The data value to send across the SPI
Side Effects:
Required for modes where CPHA == 0 where data must be in the shift register before the first clock edge.
Firmware must control this if there is already data being shifted out and if there is more
========================
Meantime, during the debugging I organized names of some buffers
as my memory can not put up with the maze of tmp, dummy... etc.
So I name buffers for SPI_Master as mTxBuffer, mRxBuffer, mFillBuffer
and buffers SPI_Slave sTxBuffer, sRxBuffer, sFillBuffer.
Master TeraTerm log
Slave TeraTerm log
Best Regards,
11-Oct-2018
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
thank you very much! It looks like I've made some good progress.
The changes that I made were
1. use of SPIS_WriteTxDataZero() before each SPIS_PutArray()
2. reading the "fill" buffers with SPIS_ReadRxData() (before I did it only when expected meaningful (not fill) data) and this seems to make a lot of difference.
However I still see some problems on the master side:
Master receives sTxBuffer data from slave in sendCmd(). I expect to receive sFillBuffer data here. However readStatus()receives sFillBuffer while I expect to receive the sTxBuffer data here. Also, as you can see bellow, the received data is somehow shifted to the right by one byte.
What I find interesting is that if I don't use SPIS_WriteTxDataZero() with sFillBuffer then I seem to eliminate the shift problem.
Another strange thing that I noticed is that master doesn't print "SPI master is running" and "iteration 1" when it starts.
I attached my current updated workspace bundle in the top post of this discussion.
Thanks again for your help!
Nikolay Pruss
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nikolay-san,
You can attach your file to a Reply message by using "Use advanced editor" in the right top of reply pane.
So please don't replace the original binary, otherwise those who read the question later won't understand the problem
nor none one can trace the changes made during the discussion.
Best Regards,
12-Oct-2018
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nikolay-san,
I read and tested your new code.
(It is good that we can use same main.c for both CY8CKIT-046 and CY8CKIT-044 ^_^)
First thing I noticed was that Slave is waiting 200us at the end of SPIS_WaitForCommand()
on the other hand Master is waiting for salve to prepare only 50us!
So I commented out the CyDelay( 200 ) ; at the line 98 of Slave's main.c
Then the out come was
Slave's TeraTerm Log (seems working fine)
Master's TeraTerm Log (Working correctly wrong as you omitted the SPIS_WriteTxDataZero() function.)
So I reactivated the SPIS_WriteTxDataZero() function.
Slave's TeraTerm log
Master's TeraTerm log
I attached the main.c for the slave.
Best Regards,
12-Oct-2018
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Motoo Tanaka,
the code seems to work correctly now. Thank you so much for all your time and effort to help me solving this problem!
If you don't mind, I'd like to ask you two quick questions.
1. If I need to run a multiple of SPI buses on a same device, then do I just copy the components with their code and add new pins or is there more to it than that?
2. I've noticed that it lets me adding additional CS lines only with the SPI SCB component. Does it mean that that SPI non SCB handles only one chip select line?
Thank you so much!
Nikolay Pruss
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nikolay-san,
1. If I need to run a multiple of SPI buses on a same device,
then do I just copy the components with their code and add new pins or is there more to it than that?
We must assign a unique name to each instance of the component,
this means the code must be modified to reflect the name, too.
Note: Depending on the device there are some maximum number of same components we can add.
2. I've noticed that it lets me adding additional CS lines only with the SPI SCB component.
Does it mean that that SPI non SCB handles only one chip select line?
We don't have to use component's CS line for chip select.
We can allocate GPIOs to do the work, and we assert a CS before calling a SPI function
then de-assert the CS or we can keep a CS asserted as far as SPI functions to the same
device are being called, then de-assert the CS line.
Best Regards,
12-Oct-2018
Motoo Tanaka
P.S. In my sample project below, I was using GPIO CS for TFT as TFT_CS.
Refer to the source file TFT.c (Not quite an elegant sample, though)