KL27 SPI1 FIFO using interrupt with non blocking write transfer and SDK 2.0

cancel
Showing results for 
Search instead for 
Did you mean: 

KL27 SPI1 FIFO using interrupt with non blocking write transfer and SDK 2.0

Jump to solution
455 Views
benhouston
Contributor III

I have beating my head against the keyboard for the last couple of days on this.  Has anyone had success implementing the SPI1 FIFO on a KL2x series using the SDK 2.0???

 

I can get a non blocking write to work all day with SPI0, using the spi_interrupt.c example code provided with SDK 2.0, but have had no luck using SPI1.  For a write of 2 bytes, on the oscope, I see both bytes leaving and the Rx FIFO filled from the MOSI, but it hangs in the program.  The CSn goes low and high for both byte transfers and the clock looks good.

 

Stepping through the debugger in IAR indicates that the callback is never called and I hang in an infinite while loop waiting for the isMasterFinished to be set to true by the call back.

 

Here are my code snippets:

Defines:

#include "clock_config.h"

#include "fsl_spi.h"

#include "fsl_gpio.h"

/*******************************************************************************

* Definitions

******************************************************************************/

#define SPI_MASTER SPI1

#define SPI_MASTER_SOURCE_CLOCK kCLOCK_CoreSysClk

#define SPI_MASTER_IRQ SPI1_IRQn

#define SPI_MASTER_IRQHandler SPI1_IRQHandler

 

Initialization:

---snipit---

CLOCK_EnableClock(kCLOCK_PortD);

PORT_SetPinMux(PORTD, 4U, kPORT_MuxAlt2); /* PCS0 J1-9  */

PORT_SetPinMux(PORTD, 5U, kPORT_MuxAlt2); /* SCK  J1-11 */

PORT_SetPinMux(PORTD, 6U, kPORT_MuxAlt2); /* MOSI J2_18 */

PORT_SetPinMux(PORTD, 7U, kPORT_MuxAlt2); /* MISO J2-20 */

-------------

 

---snipit---

SPI_MasterGetDefaultConfig(&masterConfig);

SPI_MasterInit(SPI_MASTER, &masterConfig, CLOCK_GetFreq(SPI_MASTER_SOURCE_CLOCK));

SPI_MasterTransferCreateHandle(SPI_MASTER, &spiHandle, SPI_UserCallback, NULL);

 

Where:

void SPI_UserCallback(SPI_Type *base, spi_master_handle_t *handle, status_t status, void *userData)

{

    isMasterFinished = true;

}

-------------   

 

Implementation:

xfer.txData = spiAddr;

xfer.rxData = receiveBuff;

xfer.dataSize = spiTxDataLength;

// Send out.

SPI_MasterTransferNonBlocking(SPI_MASTER, &spiHandle, &xfer);

// Wait send finished.

while (!isMasterFinished)

{

     // Program Hangs here when using SPI1.  For SPI0, this worked fine.

}

 

Any insight or encouraging words would be much appreciated.

Labels (1)
Tags (1)
0 Kudos
1 Solution
202 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Ben,

For the KL27, there are two SPI modules:SPI0 and SPI1, the SPI0 does not support FIFO mode, the SPI1 support FIFO mode, that is why there is difference when you run the same code for the SPI0 and SPI1.

I have checked your code, I think your code itself has issue, because of FIFO, the SPI1 interrupt can not occur after you call the function.

SPI_MasterTransferNonBlocking(EXAMPLE_SPI_MASTER, &masterHandle, &xfer);

which leads to the masterCallback() can not be called, the code keep to the line  while (!isMasterFinished)

If you use FIFO, I suggest you use the following code in the main() while deleting the SPI_WriteByteSingle(). In this way, after all the BUFFER_SIZE number bytes has transfered, the callback function masterCallback() is called, this will improve the efficiency.

uint8_t dataAccess[] = { spiAddr, spiData };

    xfer.txData = dataAccess;

    xfer.rxData = receiveBuff;

    xfer.dataSize = 2*BUFFER_SIZE;

    // Send out.

    SPI_MasterTransferNonBlocking(EXAMPLE_SPI_MASTER, &masterHandle, &xfer);

    // Wait send finished.

    while (!isMasterFinished)

    {

        ///todo: add timeout

        __asm("nop");

        ///Log event

        ///break from loop

    }

If you do want to call the SPI_WriteByteSingle() as you did, I do not suggest you use FIFO mode, you can disable FIFO mode by the code #define FSL_FEATURE_SPI_HAS_FIFO (0) in *_features.h

void SPI_WriteByteSingle(uint8_t spiAddr, uint8_t spiData){

    uint8_t dataAccess[] = { spiAddr, spiData };

    xfer.txData = dataAccess;

    xfer.rxData = receiveBuff;

    xfer.dataSize = 2;

    // Send out.

    SPI_MasterTransferNonBlocking(EXAMPLE_SPI_MASTER, &masterHandle, &xfer);

    // Wait send finished.

    while (!isMasterFinished)

    {

        ///todo: add timeout

        __asm("nop");

        ///Log event

        ///break from loop

    }

    return;

}

Hope it can help you.

BR

XiangJun Rong

View solution in original post

0 Kudos
6 Replies
202 Views
benhouston
Contributor III

Here is the sample program.  It covers the SPI1 FIFO with interrupt using a non blocking transfer.

The results are the same as my proprietary firmware.  When observing the oscope, I can see the transfer of the first two bytes, 0x00 and 0x06, as expected.

The program hangs after this and is waiting for the master to finish.

0 Kudos
202 Views
benhouston
Contributor III

Forgot to add that I am developing on a Freedom KL27 board, using IAR EWARM.

0 Kudos
203 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Ben,

For the KL27, there are two SPI modules:SPI0 and SPI1, the SPI0 does not support FIFO mode, the SPI1 support FIFO mode, that is why there is difference when you run the same code for the SPI0 and SPI1.

I have checked your code, I think your code itself has issue, because of FIFO, the SPI1 interrupt can not occur after you call the function.

SPI_MasterTransferNonBlocking(EXAMPLE_SPI_MASTER, &masterHandle, &xfer);

which leads to the masterCallback() can not be called, the code keep to the line  while (!isMasterFinished)

If you use FIFO, I suggest you use the following code in the main() while deleting the SPI_WriteByteSingle(). In this way, after all the BUFFER_SIZE number bytes has transfered, the callback function masterCallback() is called, this will improve the efficiency.

uint8_t dataAccess[] = { spiAddr, spiData };

    xfer.txData = dataAccess;

    xfer.rxData = receiveBuff;

    xfer.dataSize = 2*BUFFER_SIZE;

    // Send out.

    SPI_MasterTransferNonBlocking(EXAMPLE_SPI_MASTER, &masterHandle, &xfer);

    // Wait send finished.

    while (!isMasterFinished)

    {

        ///todo: add timeout

        __asm("nop");

        ///Log event

        ///break from loop

    }

If you do want to call the SPI_WriteByteSingle() as you did, I do not suggest you use FIFO mode, you can disable FIFO mode by the code #define FSL_FEATURE_SPI_HAS_FIFO (0) in *_features.h

void SPI_WriteByteSingle(uint8_t spiAddr, uint8_t spiData){

    uint8_t dataAccess[] = { spiAddr, spiData };

    xfer.txData = dataAccess;

    xfer.rxData = receiveBuff;

    xfer.dataSize = 2;

    // Send out.

    SPI_MasterTransferNonBlocking(EXAMPLE_SPI_MASTER, &masterHandle, &xfer);

    // Wait send finished.

    while (!isMasterFinished)

    {

        ///todo: add timeout

        __asm("nop");

        ///Log event

        ///break from loop

    }

    return;

}

Hope it can help you.

BR

XiangJun Rong

View solution in original post

0 Kudos
202 Views
benhouston
Contributor III

Thanks XiangJun Rong.  I'll give this a try and report back if any issues.

0 Kudos
202 Views
benhouston
Contributor III

Working on a sample project for you. Stand by.

0 Kudos
202 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Ben,

Can you develop a simple project which can only duplicate your issue if you project is  complicated or confidential so that we can debug it. Pls tell us the the tools you are using for example KDS, IAR..

BR

Xiangjun Rong

0 Kudos