SPI Bus

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
niprc_3742601
Level 4
Level 4
5 likes given First like received First like given

Hello,

I have two PSoC4 L-Series Pioneer Kits that I need to make talking to each other via SPI Bus.  So I started with the CE224339_PSoC4_SPI_Master_DMA01 and CE224463_PSoC4_SPI_Slave_DMA01 examples.  They seem to work fine: slave's LED repeatedly going through the colors.  Then I created my own Master and Slave projects that are very similar to the examples with slight modifications.  The code appears NOT to work at all: don't see LED lit blue, green or red.  When the code starts it tests all three LEDs and they appear to respond.  I put the design and source code files for master and slave bellow.

I desperately need help with this!

Thanks!

P.S.

The workspace is attached.  The projects that I am working on named StellarMasterTest and StellarSlaveTest.

tmpm.png

tmps.png

#include "project.h"

#define LED_ON              0

#define LED_OFF             1

#define DESCR0              0

#define CMD_END             (0x07Fu)

#define PKT_LEN             (13+1)  //  to fit 100 bits + CMD_END

//  master buffers

static int8 mTxBuf[ PKT_LEN ] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, CMD_END };

static int8 mRxBuf[ PKT_LEN ] = { 0 };

static int8 sTxBuf[ PKT_LEN ] = { 12u, 11u, 10u, 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u, CMD_END };

int main(void)

{

    //CyGlobalIntEnable; /* Enable global interrupts. */

    SPIM_Start();

    RxDmaM_Start( (void *)SPIM_RX_FIFO_RD_PTR, (void *)mRxBuf );

    TxDmaM_Start( (void *)mTxBuf, (void *)SPIM_TX_FIFO_WR_PTR );

    DATA_RX_Write   ( LED_ON );  CyDelay( 1000 ); DATA_RX_Write   ( LED_OFF );

    DATA_OK_Write   ( LED_ON );  CyDelay( 1000 ); DATA_OK_Write   ( LED_OFF );

    DATA_ERROR_Write( LED_ON );  CyDelay( 1000 ); DATA_ERROR_Write( LED_OFF );

   

    memset( (void *) mRxBuf, 0, PKT_LEN );

    for(;;)

    {

        if( mRxBuf[ PKT_LEN - 1 ] == CMD_END )

        {

            DATA_RX_Write( LED_ON );

        }

       

       

       

        if( 0u == (CyDmaGetInterruptSourceMasked() ^ (RxDmaM_CHANNEL_MASK) ) )

        {

            // Clears the interrupt source for the next data to be sent

            CyDmaClearInterruptSource( RxDmaM_CHANNEL_MASK );  //  mocking the sample

            DATA_RX_Write( LED_ON );  //  because we received something

           

            if( 0u == memcmp( mRxBuf, sTxBuf, PKT_LEN ) )

            {

                DATA_OK_Write( LED_ON );  //  wow, it actually worked!              

            }

            else

            {

                DATA_ERROR_Write( LED_ON );  //  now what?

            }

           

            memset( mRxBuf, 0, PKT_LEN );

           

            //CyDelay( 1000/*msecs*/ );  //  let the LED shine

            DATA_RX_Write( LED_OFF );

           

            TxDmaM_ValidateDescriptor( DESCR0 );  //  mocking the sample codesamples

            TxDmaM_ChEnable();  //  send again

            CyDelayUs(20/*µsec*/);

        }

       

        //DATA_RX_Write( LED_OFF );

    }  //  for(;;)

}

#include "project.h"

#define LED_ON              0

#define LED_OFF             1

#define DESCR0              0

#define CMD_END             0xFF

#define PKT_LEN             (13+1)  //  to fit 100 bits + CMD_END

//  master buffers

static int8 mTxBuf[ PKT_LEN ] = { 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, CMD_END };

static int8 sTxBuf[ PKT_LEN ] = { 12u, 11u, 10u, 9u, 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u, 0u, CMD_END };

static int8 sRxBuf[ PKT_LEN ];

int main(void)

{

    //CyGlobalIntEnable; /* Enable global interrupts. */

    SPIS_Start();

    RxDmaS_Start( (void *)SPIS_RX_FIFO_RD_PTR, (void *)sRxBuf );

    TxDmaS_Start( (void *)sTxBuf, (void *)SPIS_TX_FIFO_WR_PTR );

    TxDmaS_ChDisable();

    DATA_RX_Write   ( LED_ON );  CyDelay( 1000 ); DATA_RX_Write   ( LED_OFF );

    DATA_OK_Write   ( LED_ON );  CyDelay( 1000 ); DATA_OK_Write   ( LED_OFF );

    DATA_ERROR_Write( LED_ON );  CyDelay( 1000 ); DATA_ERROR_Write( LED_OFF );

   

    memset( (void *) sRxBuf, 0, PKT_LEN );   

    for(;;)

    {

        DATA_RX_Write( LED_OFF );

       

        /* wait for command to be received */

        while (0u == (RxDmaS_CHANNEL_MASK & CyDmaGetInterruptSourceMasked()));

        CyDmaClearInterruptSource(RxDmaS_CHANNEL_MASK);

       

        DATA_RX_Write( LED_ON );

       

        /* Data transfered using the DMA, clear the buffer */

        SPIS_SpiUartClearRxBuffer();

       

        if( 0u == memcmp( sRxBuf, mTxBuf, PKT_LEN ) )

        {

            DATA_OK_Write   ( LED_ON );

        }

        else

        {

            DATA_ERROR_Write( LED_ON );

        }

       

        //memset( sRxBuf, 0, PKT_LEN );

       

        /* Load the Tx FIFO with the first byte */

        SPIS_SpiUartWriteTxData( (uint32)sTxBuf[ 0 ] );

        TxDmaS_ChEnable();

       

        /* Recieves dummy data in order to send response */

        while (0u == (RxDmaS_CHANNEL_MASK & CyDmaGetInterruptSourceMasked()));

        CyDmaClearInterruptSource(RxDmaS_CHANNEL_MASK);

       

        /* Disable the tx DMA and clear out the RX buffer */

        TxDmaS_ChDisable();

        SPIS_SpiUartClearRxBuffer();

       

   

   

    }  //  for(;;)

}

/* [] END OF FILE */

Message was edited by: Nikolay Pruss

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

It was a fun problem to study!

I noticed following things

(1) DMA Element size were 3, although you were trying to send 14, so I changed them.

000-RxDma-Size.JPG

000-TxDmaM-Size.JPG

(2) From Slave you were sending only a single byte, so I changed it to whole buffer.

> SPIS_SpiUartWriteTxData( (uint32)sTxBuf[ 0 ] );

< SPIS_SpiUartPutArray((const uint8 *)sTxBuf, PKT_LEN);

(3) In Master CMD_END is 0x7F but in Slave CMD_END is 0xFF so when receiving the reply

    Master never detect, CMD_END.

   Meantime, every other transaction Master receives garbage data whose later half is usually filled with 0xFF,

   which is CMD_END. So you need to dummy read every other lines. (I did not do this, though)

#define CMD_END             (0x07Fu)

#define RX_CMD_END       (0x0FFu)

> if( mRxBuf[ PKT_LEN - 1 ] == CMD_END )

< if( mRxBuf[ PKT_LEN - 1 ] == RX_CMD_END )

Anyway, with modifications above, the program(s) seem to be able to communicate.

But as I don't know how far I should go, so I stopped here 😉

001-Master.JPG

002-Slave.JPG

Attached are my trial with CY8CKIT-044s.

moto

View solution in original post

4 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Will be much easier for us when you post your complete project so that we all can have a look at all of your settings. To do so, use

Creator->File->Create Workspace Bundle (minimal)

and attach the resulting file.

Bob

0 Likes

Hi Bob,

Thanks for the advice!  I attached the Workspace Bundle (minimal) to the original post.  The projects names that I am trying to fix are StellarMasterTest and StellarSlaveTest.

Thanks!

Nikolay

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

It was a fun problem to study!

I noticed following things

(1) DMA Element size were 3, although you were trying to send 14, so I changed them.

000-RxDma-Size.JPG

000-TxDmaM-Size.JPG

(2) From Slave you were sending only a single byte, so I changed it to whole buffer.

> SPIS_SpiUartWriteTxData( (uint32)sTxBuf[ 0 ] );

< SPIS_SpiUartPutArray((const uint8 *)sTxBuf, PKT_LEN);

(3) In Master CMD_END is 0x7F but in Slave CMD_END is 0xFF so when receiving the reply

    Master never detect, CMD_END.

   Meantime, every other transaction Master receives garbage data whose later half is usually filled with 0xFF,

   which is CMD_END. So you need to dummy read every other lines. (I did not do this, though)

#define CMD_END             (0x07Fu)

#define RX_CMD_END       (0x0FFu)

> if( mRxBuf[ PKT_LEN - 1 ] == CMD_END )

< if( mRxBuf[ PKT_LEN - 1 ] == RX_CMD_END )

Anyway, with modifications above, the program(s) seem to be able to communicate.

But as I don't know how far I should go, so I stopped here 😉

001-Master.JPG

002-Slave.JPG

Attached are my trial with CY8CKIT-044s.

moto

Thank you very much!  I am going to try this.

0 Likes