AnsweredAssumed Answered

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

Question asked by Carlos Diaz on May 25, 2017
Latest reply on May 31, 2017 by Carlos Diaz

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

Attachments

Outcomes