Controlling Multi-Slaves with LPC54618 SPI Master

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Controlling Multi-Slaves with LPC54618 SPI Master

跳至解决方案
1,049 次查看
Seunghyup
Contributor I

Hi

I am using LPC54618 and MCUXpresso IDE

and configuring various peripherals and freertos using MCUXpresso Configurater.

I am currently configuring SPI based on Freertos and have the following question.

I have 3 targets to communicate with and need 3 CS lines.

These lines are mapped to FLEXCOMM3 SSEL0/SSEL1/SSEL2.

I am using FLEXCOMM3 configured in MCUXpresso Configurater

but the FLEXCOMM3 Slave selection number in Configurater is only selectable for one selection.

I would like to ask how the user can change this selection number

and access 3 SPI devices.

If I set the FLEXCOMM3 Slave selection number in Configurater to Slave0 and generate the code

the Slave selection number is fixed to .sselNum = kSPI_Ssel0 in spi_master_config_t.

This is used as an argument in SPI_RTOS_Init and then again as an argument in SPI_MasterInit inside SPI_RTOS_Init to finally create a handle.

Is there a way to access the Slave select of the created handle?

If it is difficult to change SSEL, should I change the CS line to GPIO and control it manually?

Please check.

Thank you.

 

Seunghyup_0-1725501069876.png

 

spi_rtos_handle_t FC3_SPI_VM_rtosHandle;

const spi_master_config_t FC3_SPI_VM_config = {

.enableLoopback = false,

.enableMaster = true,

.polarity = kSPI_ClockPolarityActiveHigh,

.phase = kSPI_ClockPhaseFirstEdge,

.direction = kSPI_MsbFirst,

.baudRate_Bps = 500000UL,

.dataWidth = kSPI_Data8Bits,

.sselNum = kSPI_Ssel0,

.sselPol = (spi_spol_t)(kSPI_Spol0ActiveHigh | kSPI_Spol1ActiveHigh | kSPI_Spol2ActiveHigh),

.txWatermark = kSPI_TxFifo0,

.rxWatermark = kSPI_RxFifo1,

.delayConfig = {

.preDelay = 0U,

.postDelay = 0U,

.frameDelay = 0U,

.transferDelay = 0U

}

};

 

static void FC3_SPI_VM_init(void) {

/* Initialization function */

SPI_RTOS_Init(&FC3_SPI_VM_rtosHandle, FC3_SPI_VM_PERIPHERAL, &FC3_SPI_VM_config, FC3_SPI_VM_CLOCK_SOURCE);

/* Interrupt vector FLEXCOMM3_IRQn priority settings in the NVIC. */

NVIC_SetPriority(FC3_SPI_VM_FLEXCOMM_IRQN, FC3_SPI_VM_FLEXCOMM_IRQ_PRIORITY);

}

 

 

0 项奖励
回复
1 解答
978 次查看
Harry_Zhang
NXP Employee
NXP Employee

Hi @Seunghyup 

Can you try another way?

Manual Control of CS Lines via GPIO 

Since the configurator locks the CS lines to a single selection, a practical approach would be to control the CS lines (SSEL0, SSEL1, SSEL2) manually using GPIO pins, which will allow you to dynamically select the appropriate slave device in your code.

Steps:

1. Set up SSEL0, SSEL1, and SSEL2 as GPIO outputs:
• Instead of configuring these lines as hardware-controlled CS lines, configure them as regular GPIO pins.
2. Manually control CS lines:
• Before each SPI transfer, manually assert the desired GPIO pin corresponding to the target slave device (set it low).
• Perform the SPI transfer.
• After the transfer, deassert the GPIO pin (set it high).

Example Code:

GPIO_PinWrite(GPIO, portX, SSEL0_PIN, 0); // Assert CS for device 1
SPI_RTOS_Transfer(...); // Perform SPI transfer
GPIO_PinWrite(GPIO, portX, SSEL0_PIN, 1); // Deassert CS for device 1

GPIO_PinWrite(GPIO, portX, SSEL1_PIN, 0); // Assert CS for device 2
SPI_RTOS_Transfer(...); // Perform SPI transfer
GPIO_PinWrite(GPIO, portX, SSEL1_PIN, 1); // Deassert CS for device 2

This method gives you complete flexibility in controlling the CS lines without needing to modify the SPI initialization for each transfer.

BR

Hang

在原帖中查看解决方案

0 项奖励
回复
3 回复数
1,006 次查看
Harry_Zhang
NXP Employee
NXP Employee

Hi @Seunghyup 

The MCUXpresso Config Tool allows only one Slave Select (SSEL) line to be chosen in the configuration. In your case, you’re trying to communicate with 3 targets (each requiring a separate CS line) and the configuration locks the sselNum to one value (e.g., kSPI_Ssel0).

You can modify sselNum Dynamically in the Code:

After initializing the SPI interface using the SPI_RTOS_Init function, you can dynamically change the sselNum field within the spi_master_config_t structure or in the transfer function as needed for each transfer. However, the MCUXpresso Configurator locks this field, so you’d need to modify the configuration in the application code itself rather than relying on the generated code.
Steps:
• Initialize SPI with kSPI_Ssel0 (or any default value).
• Modify the sselNum field of the spi_transfer_t structure before each transaction.
• For each transfer, update the SSEL to kSPI_Ssel0, kSPI_Ssel1, or kSPI_Ssel2.
Example:
spi_transfer_t transfer;
transfer.sselNum = kSPI_Ssel1; // Change the slave select for this transfer
SPI_RTOS_Transfer(...); // Perform the SPI transfer

BR

Hang

0 项奖励
回复
1,002 次查看
Seunghyup
Contributor I
I would like to change CS dynamically as you suggested.

I looked at your solution but I can't apply the part where you apply CS change.

Your example applies CS change to the sender argument that is applied to SPI_RTOS_Transfer(...), but the prototype of the argument, spi_transfer_t, does not have .sselNum.

The spi_transfer_t structure in fsl_spi.h is as follows:

typedef struct _spi_transfer
{
uint8_t *txData; /*!< Send buffer */
uint8_t *rxData; /*!< Receive buffer */
uint32_t configFlags; /*!< Additional option to control transfer, @ref spi_xfer_option_t. */
size_t dataSize; /*!< Transfer bytes */
} spi_transfer_t;


Is it possible to control CS in uint32_t configFlags?
0 项奖励
回复
979 次查看
Harry_Zhang
NXP Employee
NXP Employee

Hi @Seunghyup 

Can you try another way?

Manual Control of CS Lines via GPIO 

Since the configurator locks the CS lines to a single selection, a practical approach would be to control the CS lines (SSEL0, SSEL1, SSEL2) manually using GPIO pins, which will allow you to dynamically select the appropriate slave device in your code.

Steps:

1. Set up SSEL0, SSEL1, and SSEL2 as GPIO outputs:
• Instead of configuring these lines as hardware-controlled CS lines, configure them as regular GPIO pins.
2. Manually control CS lines:
• Before each SPI transfer, manually assert the desired GPIO pin corresponding to the target slave device (set it low).
• Perform the SPI transfer.
• After the transfer, deassert the GPIO pin (set it high).

Example Code:

GPIO_PinWrite(GPIO, portX, SSEL0_PIN, 0); // Assert CS for device 1
SPI_RTOS_Transfer(...); // Perform SPI transfer
GPIO_PinWrite(GPIO, portX, SSEL0_PIN, 1); // Deassert CS for device 1

GPIO_PinWrite(GPIO, portX, SSEL1_PIN, 0); // Assert CS for device 2
SPI_RTOS_Transfer(...); // Perform SPI transfer
GPIO_PinWrite(GPIO, portX, SSEL1_PIN, 1); // Deassert CS for device 2

This method gives you complete flexibility in controlling the CS lines without needing to modify the SPI initialization for each transfer.

BR

Hang

0 项奖励
回复