[FRDM-KL25Z | MCUXpresso | Blocking SPI] SPI transfer only works on the first function call.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[FRDM-KL25Z | MCUXpresso | Blocking SPI] SPI transfer only works on the first function call.

Jump to solution
1,221 Views
carlos47diaz
Contributor I

Hi,

I'm getting started with MCUXpresso (SDK 2) using a KL25Z Freedom board.

I'm trying to use the SPI0 of the microcontroller, i had to control the /SS pin with software configuring it as GPIO to be able to sending multiple bytes while keeping the /SS pin active (logic low).

The problem i have is the transfer only happens once (after i reset the board), after this no transfer is done (see first main function below), to make it "work" i ended up "filling" the spi_transfer_t xfer variable every time after each call of SPI_MasterTransferBlocking function (see second main function below).

Is this the desired behavior? i couldn't find anything about this on the SDK reference manual and the example projects using the Blocking transfers only do the transfer once, so it doesn't show the problem i have.

Any way to have successful transfers without having to fill xfer variable again and again? maybe i'm missing something.

Below is the pin configuration on the pin_mux.c file:

#define SPI_SS_IDX    0
#define SPI_SCLK_IDX  1
#define SPI_MISO_IDX  2
#define SPI_MOSI_IDX  3

// Enable clock on SPI pins
CLOCK_EnableClock(kCLOCK_PortD);

// SS as gpio
gpio_pin_config_t ss;
ss.outputLogic = 1;
ss.pinDirection = kGPIO_DigitalOutput;

PORT_SetPinMux(PORTD, SPI_SS_IDX, kPORT_MuxAsGpio);
GPIO_PinInit(GPIOD, SPI_SS_IDX, &ss);

// SCLK, MOSI and MISO
PORT_SetPinMux(PORTD, SPI_SCLK_IDX, kPORT_MuxAlt2);
PORT_SetPinMux(PORTD, SPI_MOSI_IDX, kPORT_MuxAlt2);
PORT_SetPinMux(PORTD, SPI_MISO_IDX, kPORT_MuxAlt2);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

With this code the transfer only happens once after reset the board, after the first transfer nothing is transfered (see fail_transfer picture attached).

int main(void)
{
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitDebugConsole();

    status_t xferStatus = kStatus_Success;

// SPI Master Configuration, using SPI0 instance
    spi_master_config_t masterConfig = { 0 };
    masterConfig.baudRate_Bps = 5000000U;
    masterConfig.direction = kSPI_MsbFirst;
    masterConfig.enableMaster = true;
    masterConfig.enableStopInWaitMode = false;
    masterConfig.outputMode = kSPI_SlaveSelectAsGpio; // configure /SS as GPIO
    masterConfig.phase = kSPI_ClockPhaseFirstEdge;
    masterConfig.polarity = kSPI_ClockPolarityActiveHigh;
    masterConfig.pinMode = kSPI_PinModeNormal;
    SPI_MasterInit(SPI0, &masterConfig, CLOCK_GetFreq(kCLOCK_BusClk));

// Transfer configuration
    const uint8_t srcArray[5] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE };
    spi_transfer_t xfer = { 0 };

    xfer.txData = srcArray;
    xfer.rxData = NULL;
    xfer.dataSize = sizeof(srcArray) / sizeof(srcArray[0]);
    // xfer.flags; useless for SPI

    while(1)
    {

         GPIO_ClearPinsOutput(GPIOD, 1 << 0); // SS low
         xferStatus = SPI_MasterTransferBlocking(SPI0, &xfer);
         GPIO_SetPinsOutput(GPIOD, 1 << 0); // SS high

         if( kStatus_Success == xferStatus )
         {
              GPIO_TogglePinsOutput(GPIOB, 1 << 18);
         }

         for(uint32_t i = 100000; i != 0; i--);

    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This is the second main function, with it i get transfers every time i call the SPI_MasterTransferBlocking function (see success_transfer picture attached).:

int main(void)
{
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitDebugConsole();

    // SPI Master test
    status_t xferStatus = kStatus_Success;


// SPI Master Configuration
    spi_master_config_t masterConfig = { 0 };
    masterConfig.baudRate_Bps = 5000000U;
    masterConfig.direction = kSPI_MsbFirst;
    masterConfig.enableMaster = true;
    masterConfig.enableStopInWaitMode = false;
    masterConfig.outputMode = kSPI_SlaveSelectAsGpio;
    masterConfig.phase = kSPI_ClockPhaseFirstEdge;
    masterConfig.polarity = kSPI_ClockPolarityActiveHigh;
    masterConfig.pinMode = kSPI_PinModeNormal;
    SPI_MasterInit(SPI0, &masterConfig, CLOCK_GetFreq(kCLOCK_BusClk));

// Transfer configuration
    spi_transfer_t xfer = { 0 };
    const uint8_t srcArray[5] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE };
    xfer.txData = srcArray;
    xfer.rxData = NULL;
    xfer.dataSize = sizeof(srcArray) / sizeof(srcArray[0]);
    // xfer.flags; useless for SPI

    while(1)
    {

         GPIO_ClearPinsOutput(GPIOD, 1 << 0); // SS low
         xferStatus = SPI_MasterTransferBlocking(SPI0, &xfer);
         GPIO_SetPinsOutput(GPIOD, 1 << 0); // SS high

         if( kStatus_Success == xferStatus )
         {
              GPIO_TogglePinsOutput(GPIOB, 1 << 18);
         }

         // Filling xfer again to be able to transfer data on the next SPI_MasterTransferBlocking call
         xfer.txData = srcArray;
         xfer.rxData = NULL;
         xfer.dataSize = sizeof(srcArray) / sizeof(srcArray[0]);

         for(uint32_t i = 100000; i != 0; i--);

    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Thanks in advance.

Carlos

Tags (3)
0 Kudos
Reply
1 Solution
885 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

In the function SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer) , xfer->txData is changed. So next time you call this function without refill xfer, wrong data(maybe 0) will be sent. That is to say, you pass the address of a variable to a subfunction. Any change to this variable is real.

Regards

Pan Jing

View solution in original post

0 Kudos
Reply
2 Replies
886 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

In the function SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer) , xfer->txData is changed. So next time you call this function without refill xfer, wrong data(maybe 0) will be sent. That is to say, you pass the address of a variable to a subfunction. Any change to this variable is real.

Regards

Pan Jing

0 Kudos
Reply
885 Views
carlos47diaz
Contributor I

Hi,

Thanks for the reply, i didn't saw that xfer->txData was changed on the function. Now everything is clear.

Regards

Carlos

0 Kudos
Reply