cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 6 MCU

New Contributor II
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
Reply
1 Solution
Moderator
Moderator

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
Moderator
Moderator

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
Reply
New Contributor II

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
Reply
Esteemed Contributor

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

 

 

Moderator
Moderator

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
New Contributor II

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

Moderator
Moderator

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

New Contributor II

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

Top labels