SPI: slave select using SDK, e.g., SPI_MasterTransferNonBlocking()?

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

SPI: slave select using SDK, e.g., SPI_MasterTransferNonBlocking()?

1,739 Views
danielholala
Senior Contributor II

Hello everybody,

On my custom LPC55xx based board I'm trying to communicate via a single SPI interface with several slaves (SSEL0 - SSEL2). 

The MCU obviously supports this as the FIFO Write register contains bits to select the slave for a transfer. 

danielholala_0-1645196071221.png

FIFOWR provides the possibility of altering some SPI controls at the same time as
sending new data.

Do the SDK drivers support this and how?

I checked SDK examples but could not find an anwer to my question. Further, SDK documentation is lacking. There's no information about, e.g., SPI_MasterInit() or SPI_MasterTransferNonBlocking() in the SDK doxygen doc.

I gleaned from the source code fsl_spi.h that the slave number is encoded in a struct spi_master_config_t and this struct is used when calling SPI_MasterInit(). According to fsl_spi.h, the slave number is not used when doing a transfer. So it seems it is not possible to easily switch between slaves from one transfer to another. 

Any help is appreciated.

Best regards,
Daniel

 

 

Labels (1)
Tags (2)
0 Kudos
5 Replies

1,706 Views
danielholala
Senior Contributor II

Dear Alice,

Thanks, I appreciate your reply. 

You seem to be confirming that the SDK SPI driver does not support more than one slave per SPI interface.

In that case I'd say that the SDK is utterly lacking as it misses basic functions and that NXP has done a bad job regarding SDK.

I hope that NXP is working on the shortcomings of the SDK (documentation and functionality).

Best regards,
Daniel

 

0 Kudos

1,684 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Daniel,

The SDK SPI driver support multiple slaves. I have reply you on your private case.

 

BR

Alice

0 Kudos

1,667 Views
danielholala
Senior Contributor II

Dear Alice,

I appreciate your reply. However, I have to disagree. I can not find any API functions to select a different slave for each transaction short of calling the init function again (as I mentioned before).

I'm using Peripherals Tool and selected "Universal Driver" for Flexcomm. This generates initialization code based on the CMSIS driver. The CMSIS driver is not using SPI_WriteData() but SPI_MasterTransferNonBlocking() and SPI_TransferHandleIRQInternal() in fsl_spi.c.

The latter includes this piece of code:

 

 

    /* select slave to talk with */
    tx_ctrl |= ((uint32_t)SPI_DEASSERT_ALL & (uint32_t)SPI_ASSERTNUM_SSEL(handle->sselNum));
    /* set width of data */
    tx_ctrl |= SPI_FIFOWR_LEN(handle->dataWidth);

 

 

That is, in each interrupt request, the slave is selected according to handle->sselNum.

 

A quick solution is to add an API call (to fsl_spi_cmsis.c) in order to change sselNum.

 

 

uint8_t SPI3_getSSEL() {
    return SPI3_InterruptDriverState.handle->masterHandle.sselNum;
}

void SPI3_setSSEL(uint8_t slave) {
    SPI3_InterruptDriverState.handle->masterHandle.sselNum = slave;
}

 

 

This sets sselNum of Flexcomm3. Should be called before a call to Transfer().

Further resource locking is recommended.

Best regards,
Daniel

 

0 Kudos

1,729 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello danielholala,

The slave number is used in SPI_WriteData() function:

Alice_Yang_0-1645594664706.png

 

So if you want to use more than one slave, you need change the number for call this data write function.

 

BR

Alice

0 Kudos

1,704 Views
danielholala
Senior Contributor II

Dear Alice,

as you know the Peripherals Tool generates code based on the CMSIS API. I used Peripherals Tool to configure Flexcomm interfaces, e.g., Flexcomm3 for SPI. For the SPI component this code in "peripherals.c" looks like:

static void FLEXCOMM3_init(void) {
  /* Interrupt vector FLEXCOMM3_IRQn priority settings in the NVIC. */
  NVIC_SetPriority(FLEXCOMM3_IRQN, FLEXCOMM3_IRQ_PRIORITY);
  /* Initialize CMSIS SPI */
  FLEXCOMM3_PERIPHERAL.Initialize(SPI_SignalEvent);
  /* Power control of CMSIS SPI */
  FLEXCOMM3_PERIPHERAL.PowerControl(ARM_POWER_FULL);
  /* Control of CMSIS SPI */
  FLEXCOMM3_PERIPHERAL.Control(ARM_SPI_MODE_MASTER | ARM_SPI_CPOL0_CPHA0 | ARM_SPI_DATA_BITS(8) | ARM_SPI_MSB_LSB | ARM_SPI_SS_MASTER_HW_OUTPUT, 500000);
  /* Control of CMSIS SPI */
  FLEXCOMM3_PERIPHERAL.Control(ARM_SPI_SET_DEFAULT_TX_VALUE, 0);
}

Further, I have to add the SPI callback function.

 

With that said and referring to your suggestion to use calls from the standard SDK SPI driver:

how do I continue/move from here (CMSIS based driver code and initialized SPI interface) to the standard SDK driver?

Thanks.

Daniel

 

0 Kudos