cancel
Showing results for 
Search instead for 
Did you mean: 

Code Examples

niprc_3742601
New Contributor II

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

0 Likes
1 Solution
MotooTanaka
Esteemed Contributor

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

001-Master-log.JPG

Slave TeraTerm log

000-Slave_log.JPG

Best Regards,

11-Oct-2018

Motoo Tanaka

View solution in original post

9 Replies
MotooTanaka
Esteemed Contributor

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

000-master-miso.JPG

001-master-mosi.JPG

002-master-sclk.JPG

003-master-ss.JPG

Slave pins

000_slave_mosi.JPG

001-slave-sclk.JPG

002-slave-ss.JPG

003-slave-miso.JPG

modified slave's main.c

004-slave-main.JPG

modified master's main.c

004-master_main.JPG

Oscilloscope wave mosi, miso, sclk, ss

IMG_2801.JPG

moto

niprc_3742601
New Contributor II

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

0 Likes
MotooTanaka
Esteemed Contributor

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

0 Likes
MotooTanaka
Esteemed Contributor

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

001-Master-log.JPG

Slave TeraTerm log

000-Slave_log.JPG

Best Regards,

11-Oct-2018

Motoo Tanaka

View solution in original post

niprc_3742601
New Contributor II

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.

pastedImage_0.png

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.

pastedImage_10.png

What I find interesting is that if I don't use SPIS_WriteTxDataZero() with sFillBuffer then I seem to eliminate the shift problem.

pastedImage_0.png

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

0 Likes
MotooTanaka
Esteemed Contributor

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

MotooTanaka
Esteemed Contributor

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)

000-Slave.JPG

Master's TeraTerm Log (Working correctly wrong as you omitted the SPIS_WriteTxDataZero() function.)

001-Master.JPG

So I reactivated the SPIS_WriteTxDataZero() function.

Slave's TeraTerm log

002-Slave.JPG

Master's TeraTerm log

003-Master.JPG

I attached the main.c for the slave.

Best Regards,

12-Oct-2018

Motoo Tanaka

niprc_3742601
New Contributor II

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

0 Likes
MotooTanaka
Esteemed Contributor

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)

Maze, my first demo binary

0 Likes