How to use the DSPI driver for multiple slaves

Showing results for 
Search instead for 
Did you mean: 

How to use the DSPI driver for multiple slaves

Contributor III

Hi all.

Assume that I've got 2 SPI slaves connected to my Kintetis device, for example one using {CPHA=0,  bitsPerFrame=8} and one using {CPHA=1, bitsPerFrame=16}.

It looks like we need 2 CTARs configured with the different CPHA and FMSZ parameters (as well as the different chip selects, obviously) - is that a valid assumption?

I'm looking at both with and without the FreeRTOS DSPI wrapper...

It doesn't look like the API in fsl_dspi_freertos.c is the right thing to use to setup multiple CTARs:

* calling DSPI_RTOS_Init() using the same handle twice will leak the mutex and event semaphore allocated in the first call.

* calling DSPI_RTOS_Init() with different handles will mean the mutex does not protect us from clashing transfers

I think that the root cause is that DSPI_MasterInit() in fsl_dspi.c mixes together:

* the configuration of the whole-channel (e.g master/slave mode, MCR register etc) and

* the configuration of a single CTAR (e.g. FMSZ and CPHA)

This is fine for a single master/slave configuration but falls apart if you have more than one slave to deal with.

I can't believe that I'm the first to fall over this so what does everyone do? Does everyone rip apart the SDK code for all but the most trivial of applications?

0 Kudos
2 Replies

NXP TechSupport
NXP TechSupport

Hello Stephen Langstaff 


You don't need to modify the API functions, you can configure two different CTARs with DSPI_RTOS_Init() and DSPI_MasterInit().

The struct dspi_master_config_t has one space called whichCtar that allows you to select which CTAR configure.

You can call first DSPI_RTOS_Init() with the first CTAR configuration, this will create the mutex, semaphore and handle, Then call DSPI_MasterInit() to avoid the re-creation of the mutex, semaphore and handle. Before calling DSPI_MasterInit() make sure to change the whichCtar field.


dspi_master_config_t masterConfig;

/*Master config*/

masterConfig.whichCtar                                = kDSPI_Ctar0;

masterConfig.ctarConfig.baudRate                      = TRANSFER_BAUDRATE;

masterConfig.ctarConfig.bitsPerFrame                  = 8;

 masterConfig.ctarConfig.cpol                          = kDSPI_ClockPolarityActiveHigh;

 masterConfig.ctarConfig.cpha                          = kDSPI_ClockPhaseFirstEdge;




status      = DSPI_RTOS_Init(&master_rtos_handle, EXAMPLE_DSPI_MASTER_BASEADDR, &masterConfig, sourceClock);

/**Configure the second ctar*/

masterConfig.whichCtar                                = kDSPI_Ctar1;/***/

masterConfig.ctarConfig.baudRate                      = TRANSFER_BAUDRATE;

masterConfig.ctarConfig.bitsPerFrame                  = 8;

 masterConfig.ctarConfig.cpol                           = kDSPI_ClockPolarityActiveLow

 masterConfig.ctarConfig.cpha                          = kDSPI_ClockPhaseSecondEdge;


To change the ctar when you start a transfer you change the value configFlags of the dspi_transfer_t struct and use the same handle to avoid clashing.



    dspi_transfer_t masterXfer;

    /*Start master transfer*/

    masterXfer.txData      = masterSendBuffer;

    masterXfer.rxData      = masterReceiveBuffer;

    masterXfer.dataSize    = TRANSFER_SIZE;

    masterXfer.configFlags = kDSPI_MasterCtar0 | kDSPI_MasterPcs0 |  kDSPI_MasterPcsContinuous;


    status = DSPI_RTOS_Transfer(&master_rtos_handle, &masterXfer);


Let me know if this is helpful, if you have more questions do not hesitate to ask me.

Best regards,


Contributor III

Hi Omar,

That's very helpful.

I guess I missed it when I was reviewing the available APIs because a) I was mislead by the API name (the channel is already initialised into master mode!) and b) the first few line of code in the function fiddle with the MCR register (I thought that I only wanted to modify the CTAR).



0 Kudos