- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
#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
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
(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 😉
Attached are my trial with CY8CKIT-044s.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
(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 😉
Attached are my trial with CY8CKIT-044s.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much! I am going to try this.