SPI slave ISR not responding

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.
SaGa_4641021
Level 5
Level 5
50 questions asked 50 replies posted 100 sign-ins
Hi

I am trying to build a basic SPI code. I included 2 SPI's in the M4, one as master, the second as slave and wired them together using jumper wires. Both run using High-Level API.

Master sends data properly to Slave, then Slave will echo back data to Maser and show on UART.

Master runs properly, but the slave ISR does not run when Master sends on SPI. I inserted delay and LED blink inside the slave ISR to confirm that the slave ISR is not being called.

I attached the code, any help how to resolve that the slave ISR is not getting called ?

thanks

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi @SaGa_4641021 ,

There are two issues in the code. Correcting them resolved the issue at me end.

1. You need to set up the TX and RX buffer of the SPI slave block before the master initiates the transaction using Cy_SCB_SPI_Transfer() if you want to use High Level SPI transfer. For example, in your spi_send(), modify the code as follows:

mspi_bufferTx[0] = data;

/* Setup the Tx and Rx buffer of the SPI slave before sending. This is what configures the RX and TX interrupt */
Cy_SCB_SPI_Transfer(sSPI_HW, sspi_bufferTx, sspi_bufferRx, sizeof(sspi_bufferTx), &sSPI_context);
mspi_error_status = Cy_SCB_SPI_Transfer(mSPI_HW, mspi_bufferTx, mspi_bufferRx, sizeof(mspi_bufferTx), &mSPI_context);
if(mspi_error_status == CY_SCB_SPI_SUCCESS)
{

// same as your code

}

 

2.  Implementation of mspi_send_done flag is incorrect. This flag should be set before the return statements. Statements that are present after the return statement will not be executed. 

Correction:

if(mspi_error_status == CY_SCB_SPI_SUCCESS)
{
do
{
mspi_status = Cy_SCB_SPI_GetTransferStatus(mSPI_HW, &mSPI_context);
Cy_SysLib_Delay(CY_SCB_WAIT_1_UNIT);
} while (0UL != (mspi_status & CY_SCB_SPI_TRANSFER_ACTIVE));
mspi_send_done = true;
return mspi_bufferRx[0];
}

3. Do not call CyDelay() in the ISR. This will delay ISR execution and will cause timing issues.

Please let me know if this works for you. Attached project for your reference.

Regards,
Bragadeesh

View solution in original post

7 Replies
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi @SaGa_4641021 ,

1. Can you please share your complete PSoC Creator project. We would like to review the component settings and the top design as well.

2. To debug the issue at your end, please probe the SPI lines and check if there are any issues in the SPI transaction.

3. How did you confirm that the SPI master does not have any issue?

4. In spi_send(),  mspi_send_done = true is set after the "return" statements and hence there are chances that this statement may not be executed at all. You need to set this flag to true before the statement return mspi_bufferRx[0]

Reference code example for High Level SPI Slave:

https://www.cypress.com/documentation/code-examples/ce221121-psoc-6-mcu-spi-slave

 

Regards,
Bragadeesh
0 Likes
lock attach
Attachments are accessible only for community members.

Hi.

Points 2, 3: I used logic analyzer to monitor the SPI bus, the Master runs as expected. I also wrote another code to loop the Master MISO and MOSI to make sure its is working fine, and it is. So, the Master code is ok.

Debugging results: I divided this single program into 2 separate ones using 2 separate PSoCs, one for SPI Master and the other for SPI Slave, and connected Master and Slave using wires. This setup works (I attached for reference and for other  users to access).

My observation is: In the Code_with_Issue; code lines included in the SPI Slave ISR "sspi_isr()" do not run. Yet, the Slave responds and executes Cy_SCB_SPI_Transfer(). So, I wrote a short test ISR with a line to turn on the LEDs, and those lines do not run. I included that test ISR the code below. How does the SPI Slave ISR run ? does it only execute the Cy_SCB_SPI_Interrupt() method ? and ignores everything else ?

void sspi_isr(void)
{
LED_Red_on; LED_Green_on; CyDelay(500);
Cy_SCB_SPI_Interrupt(sSPI_HW, &sSPI_context);
}

thanks

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,

From your source code, LED_Green =  P7_1, LED_Reg = P6_3,

CY8CPROTO-063-BLE was the only board I have and which has LEDs on these port.

So, although I have purchased this board while ago, this is the first time I use it.

(Thank you for giving me the chance 😉

So I created a project and debugged your main.c

and I noticed that mspi_send_done was not set in mspi_isr().

So I changed mspi_isr() as below

====================

void mspi_isr(void)
{
Cy_SCB_SPI_Interrupt(mSPI_HW, &mSPI_context);
mspi_send_done = true ;
}

====================

Now sspi_isr() was called, but still "SPI Data in:" was not showing something reasonable,

so I modified if (mspi_read_to_send) {} block as below

====================

if(mspi_ready_to_send)
{
mspi_data_in = spi_send(serial_data_in);
Cy_SCB_UART_PutArray(UART_HW, message3, sizeof(message3));
// UART_Put(mspi_data_in);
if(mspi_send_done)
{
do
{
sspi_status = Cy_SCB_SPI_GetTransferStatus(sSPI_HW, &sSPI_context);
}while ((0UL != (sspi_status & CY_SCB_SPI_TRANSFER_ACTIVE)));

sspi_bufferTx[0] = sspi_bufferRx[0];
Cy_SCB_SPI_Transfer(sSPI_HW, sspi_bufferTx, sspi_bufferRx, sizeof(sspi_bufferTx), &sSPI_context);

UART_Put(sspi_bufferRx[0]) ;
mspi_send_done = false;
}
mspi_ready_to_send = false;
}

====================

Now the TeraTerm output shows as below

002-TeraTerm-log2.JPG

moto

 

 

Hi @MotooTanaka , Thank you for taking your time to create the project 🙂 . When using High level APIs in PSoC 6, setting the mspi_send_done in the ISR doesn't guarantee that the transaction is complete. We need to check (poll) for the status of the transaction using Cy_SCB_SPI_GetTransferStatus and check if the ACTIVE flag is cleared. We also have an option to register callbacks (interrupt method) using  Cy_SCB_SPI_RegisterCallback() and then we can check for callback events such as CY_SCB_SPI_TRANSFER_CMPLT_EVENT

Regards,
Bragadeesh

Thank you for your feedback, I will implement your modifications. all the best

lock attach
Attachments are accessible only for community members.
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi @SaGa_4641021 ,

There are two issues in the code. Correcting them resolved the issue at me end.

1. You need to set up the TX and RX buffer of the SPI slave block before the master initiates the transaction using Cy_SCB_SPI_Transfer() if you want to use High Level SPI transfer. For example, in your spi_send(), modify the code as follows:

mspi_bufferTx[0] = data;

/* Setup the Tx and Rx buffer of the SPI slave before sending. This is what configures the RX and TX interrupt */
Cy_SCB_SPI_Transfer(sSPI_HW, sspi_bufferTx, sspi_bufferRx, sizeof(sspi_bufferTx), &sSPI_context);
mspi_error_status = Cy_SCB_SPI_Transfer(mSPI_HW, mspi_bufferTx, mspi_bufferRx, sizeof(mspi_bufferTx), &mSPI_context);
if(mspi_error_status == CY_SCB_SPI_SUCCESS)
{

// same as your code

}

 

2.  Implementation of mspi_send_done flag is incorrect. This flag should be set before the return statements. Statements that are present after the return statement will not be executed. 

Correction:

if(mspi_error_status == CY_SCB_SPI_SUCCESS)
{
do
{
mspi_status = Cy_SCB_SPI_GetTransferStatus(mSPI_HW, &mSPI_context);
Cy_SysLib_Delay(CY_SCB_WAIT_1_UNIT);
} while (0UL != (mspi_status & CY_SCB_SPI_TRANSFER_ACTIVE));
mspi_send_done = true;
return mspi_bufferRx[0];
}

3. Do not call CyDelay() in the ISR. This will delay ISR execution and will cause timing issues.

Please let me know if this works for you. Attached project for your reference.

Regards,
Bragadeesh

Thanks a lot for your help, I will correct my code accordingly