[SCB SPI] "Corrupted" SPI transfers

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.
cadi_1014291
Level 6
Level 6
25 likes received 10 likes received 10 likes given

Hi,

   

I'm still trying to finish a custom component for the nRF24 radios [1], i wanted to use the component on all the possible PSoCs, so i had to made it work with UDB and SCB blocks.

   

To test the component i did three projects (attached):

   

* using PSoC5LP (kit CY8CKIT-059) and SPI based on UDB blocks

   

* using PSoC4 (kit CY8CKIT-043) and SPI based on UDB blocks

   

* using PSoC4 (kit CY8CKIT-043) and SPI based on SCB blocks

   

 

   

So far i have no problems with the UDB projects (see nrf_udb image attached), but i'm having troubles with the SCB implementation (see nrf_scb attached image) the /SS line asserts between transfers.

   

I'm writing 2 bytes, the first byte contains the COMMAND + REGISTER and the second byte contains the DATA i want to write to the nRF REGISTER.

   

Here is the function i use to write to the nRF registers, on the top you can see the UDB version and below the SCB implementation:

   

void nRF24_WriteRegister(const NRF_REGISTER_t reg, const uint8_t data)
{
#if !defined(CY_SCB_SPI_H) // UDB Block
    
    SPI_ClearRxBuffer();
    SPI_ClearTxBuffer();
    
    SS_Write(0);
    SPI_WriteTxData(NRF_W_REGISTER_CMD | reg);
    SPI_WriteTxData(data);
    
    while(0 == (SPI_ReadTxStatus() & SPI_STS_SPI_IDLE));
    SS_Write(1);
    
#else // SCB Block
    
    SPI_SpiUartClearRxBuffer();
    SPI_SpiUartClearTxBuffer();
    
    SPI_SpiSetActiveSlaveSelect(0);
    SPI_SpiUartWriteTxData(NRF_W_REGISTER_CMD | reg);
    SPI_SpiUartWriteTxData(data);
       
    while( SPI_SpiIsBusBusy() );
    
#endif
}

   

 

   

In the example projects both SPI peripherals have a 32 byte TX-FIFO, i'm not familiar enough with the SPI based on the PSoC4 SCB blocks so maybe i'm missing something very obvious, feel free to look into the code and let me know if i'm doing something silly 😕 .

   

 

   

Thanks in advance

   

Carlos

   

 

   

PD: If you want to check the most up to date implementation you can find it here:

   

[1] github.com/C47D/nRF24_Component

0 Likes
5 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

To remove the SS-line troubles I always remove the component's SS-line and use a seperate pin. At begin of a transaction i pull it low and at the end I release it to high state using Pin_Write() API. Works perfectly.

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
cadi_1014291
Level 6
Level 6
25 likes received 10 likes received 10 likes given

Hi,

   

I will try it that way and report back here, thanks for the tip 😉

   

 

   

EDIT:

   

Below is the new function:

   

void nRF24_WriteRegister(const NRF_REGISTER_t reg, const uint8_t data)
{
#if !defined(CY_SCB_SPI_H) // UDB Block
    
    SPI_ClearRxBuffer();
    SPI_ClearTxBuffer();
    
    SS_Write(0);
    SPI_WriteTxData(NRF_W_REGISTER_CMD | reg);
    SPI_WriteTxData(data);
    
    while(0 == (SPI_ReadTxStatus() & SPI_STS_SPI_IDLE));
    SS_Write(1);
    
#else // SCB Block
    
    SPI_SpiUartClearRxBuffer();
    SPI_SpiUartClearTxBuffer();
    
    SS_Write(0); 
    SPI_SpiUartWriteTxData(NRF_W_REGISTER_CMD | reg);
    SPI_SpiUartWriteTxData(data);
       
    while( SPI_SpiIsBusBusy() );
    SS_Write(1); 
#endif
}

   

 

   

The SCB datasheet says that the SPI_SpiIsBusBusy() function works based on the /SS line (now absent) so i can't rely on it (see attached image), maybe now i can use the SCB_SpiUartGetRxBufferSize function and wait until the RxBuffer have 2 byte on it, something like this:

   

    SS_Write(0); 
    SPI_SpiUartWriteTxData(NRF_W_REGISTER_CMD | reg);
    SPI_SpiUartWriteTxData(data);
       
    while( SPI_SpiUartGetRxBufferSize() != 2 );
    SS_Write(1); 

   

What do you think? hehe

   

 

   

 

   

Carlos

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

On attached scope you see that the ss-line toggles every byte, that is not ok. Usually caused by too slow feeding with data.

   

Your approach using _GetRxBufferSize() will work.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Hello Bob ,

i'am facing an issue regrading data sent over SCB SPI .

i have attached link for conversation with member of cypress forum .

Please go though it and help me .

Data write issue with SCB SPI of CY8C4247_LQI-483

0 Likes
lock attach
Attachments are accessible only for community members.
cadi_1014291
Level 6
Level 6
25 likes received 10 likes received 10 likes given

Hi,

   

It seems like it worked (see attached image), here's the new function:

   

void nRF24_WriteRegister(const NRF_REGISTER_t reg, const uint8_t data)
{
#if !defined(CY_SCB_SPI_H) // UDB Block
    
    SPI_ClearRxBuffer();
    SPI_ClearTxBuffer();
    
    SS_Write(0);
    SPI_WriteTxData(NRF_W_REGISTER_CMD | reg);
    SPI_WriteTxData(data);
    
    while(0 == (SPI_ReadTxStatus() & SPI_STS_SPI_IDLE));
    SS_Write(1);
    
#else // SCB Block
    
    SPI_SpiUartClearRxBuffer();
    SPI_SpiUartClearTxBuffer();
   
    SS_Write(0);
    SPI_SpiUartWriteTxData(NRF_W_REGISTER_CMD | reg);
    SPI_SpiUartWriteTxData(data);

   


    while( SPI_SpiUartGetRxBufferSize() != 2 );
    SS_Write(1);
    
#endif
}

   

 

   

Maybe i should take the same approach on the UDB block, but for now i will leave it like that, thanks for the help 🙂

   

 

   

Carlos

0 Likes