4 Replies Latest reply on Oct 5, 2018 5:12 AM by npruss_3742601

    SPI Bus

    npruss_3742601

      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

        • 1. Re: SPI Bus
          bob.marlowe

          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

          • 2. Re: SPI Bus
            npruss_3742601

            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

            • 3. Re: SPI Bus
              user_13463998

              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

              1 of 1 people found this helpful
              • 4. Re: SPI Bus
                npruss_3742601

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