SPI MSLS (chip select)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Hello,

I work with SPI on a XMC4200. As there is only one SELO line per usic channel connected and I need several chip select lines, I handle it by myself.

There is the internal MSLS signal, which I activate for generartion. I enable my chip select. Then I write my data to FIFO or wait if FIFO is full until all data is transmitted. Now I need to wait for data to be transmitted. Then I disable my chip select.

I use the following to wait for everything to be transmitted:

while (SPI_GetFlagStatus(Handle, SPI_MSLS_STATUS_FLAG) == true) {}

I replaced the SPI_SET etc with bool in this case. This works fine for one transfer, or two transfers with some delay in between. But If I call my function twice with no delay, the second transfer has a wrong chip select signal, which is only active for a short period, before transmission even starts.

What can I do?

Kind regards,
Christian
0 Likes
10 Replies
Not applicable
Hi Christian,

My understanding are as followings, pls correct me if i am wrong.
1) Only one SELO (chip select line) is used control several slaves;
2) Use MSLS signal to control the slave selection;
3) Function for data transfer: enable chip select --> write data to FIFO --> wait for data to be transmitted (check for SPI001_MSLS_STATUS_FLAG) --> disable chip select;
4) One transfer is referring to a function call for one slave which will complete transmission of one data frame;
5) Some delays are added in between the two transfers/function calls/data frames;

I don't know the exact implementation. Perhaps you can explain a bit more?!
Since you are using only one SELO to control several slaves, maybe you can try to use the max. leading/trailing/next-frame delay among all slaves.

Best regards,
Sophia
0 Likes
Not applicable
Hi Sophia,

point 2-5 is correct. Point 1 is a little bit different. The XMC4200 has only connected 1 SELO Output per channel, one might also have two SELO. As I need 6, I use some GPIOs. To get the right signaligin on the GPIOs to behave like chip select i generate the signal based on the internal MSLS.

I could fix the problem. I do not wait for end of transmission with SPI_GetFlagStatus but I enabled an interrupt for MSLS event. Here I disable my chip select and set a flag for transfer routine. There I wait for this flag. This code works fine in any situation. Strange that the other solution without interrupts made troubles.

And some more info: There is a SPI transfer function. You give it a number of bits a send and a receive buffer and a pin to use as chip select. The function is blocking, enables chip select, writes data to FIFO and reads if new one is available. Then it waits for finish of transfer, disables slave select and reads rest of data from receive FIFO.

As I need completly variable lenght of frames, I use TCI to control the length. This way I can send any number of bits, with as many chip selects as I want (limited by GPU

King regards,
Christian
0 Likes
Not applicable
Hi Christian,

The other solution without interrupt which does not work, it is by polling the MSLS flag?
If yes, did you manually cleared the flag every time it had set?
For your info, the flag does not cleared by hardware and requires user application to clear it.
As the flag does not influence the interrupt generation, perhaps that's the reason why the transfer is working fine when using interrupt approach.

For your additional info, I'm not quite understand. Do you mean that you are unable to use the TCI features on the SPI?
Basically, by pushing your data into different TxFIFO (IN00 - IN31), the hardware will generates the TCI that will be used for the word length control.
0 Likes
Not applicable
Hi Jackson,

I tried both:
SPI_MSLS_STATUS_FLAG -> which is the status of internal slave select, so I waited until it is low. In my mind this should be cleared by hardware.
SPI_MSLS_EVENT_FLAG -> which is the event of a change of internal MSLS, it is an event, can generate an interrupt and needs to be cleared by software.

No, I can use the TCI on SPI and it works fine. I use it to control the word length. This way I can transmit any number of bits.

Which flag should I use to detect the end of transmission? As my SPI function to do the transfer I would be glad to deal without the interrupt

// EDIT: If anything is still not clear to you, feel free to ask.
0 Likes
Not applicable
Hi Christian,

Your approached seems correct and shouldn't have any issue.
Do you mind to share your project?
Perhaps I can have a look and see what's went wrong.
0 Likes
lock attach
Attachments are accessible only for community members.
Not applicable
Attached you will find my own SPI module, based on Dave code but rewritten to fullfill my need and init is more readable in my mind.

Instead of while (SPI_ChipSelectInt.Finished == false) {}
I used while (SPI_GetFlagStatus(Handle, SPI_MSLS_STATUS_FLAG) == true) {}
but this did not work if I called my SPI_Transfer function within a loop without any delay. Only the first iteration got a correct chip select signal.

My GPIO module is not included in the source but is very basic. Please, tell me if you need it.

Kind regards,
Christian

// EDIT: I uploaded the gpio module, so you can use the code.
0 Likes
Not applicable
There is one more thing:

I once had troubles with hardware port control in SPI half duplex mode. Can you give me any hints. As I currently do not use it, I did no spent much time on it.
To test it I simply used SPI_STANDARD_HPC_INPUTMODE but also applied a tx buffer with some data not zero in it. In this situation the data appeared on the output. In my mind with input mode this should never occure.

// EDIT: Btw, I discovered a bug that makes the SPI code only useable on USIC module 0 because of the fixed interrupt handler and NVIC calls, but I fixed it and it should not affect debugging of the issue itself.
0 Likes
Not applicable
The code also had some troubles with the FIFO partioning, now this is solved in a unified way.

You find the code here: http://www.infineonforums.com/threads/687-I2C-problem-with-FIFO

It contains modules to operate the USIC as UART, SPI master, I2C master and a GPIO module that is basis for pin configs in all modes.
0 Likes
Not applicable
Hey I am having a quite simular problem with the MSLS on a XMC4800. I want to use some GPIOs as my slave selects. My example code looks like this:

while(1U)
{
XMC_GPIO_SetOutputLow(SOFT_CS);
XMC_SPI_CH_EnableSlaveSelect(SPI2_CH1, XMC_SPI_CH_SLAVE_SELECT_0);

XMC_SPI_CH_Transmit(SPI2_CH1, 'A', XMC_SPI_CH_MODE_STANDARD);
while((XMC_SPI_CH_GetStatusFlag(SPI2_CH1) & XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION) == 0U);
XMC_SPI_CH_ClearStatusFlag(SPI2_CH1, XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION);

XMC_SPI_CH_DisableSlaveSelect(SPI2_CH1);

// Wait till MSLS disabled
while((XMC_SPI_CH_GetStatusFlag(SPI2_CH1) & XMC_SPI_CH_STATUS_FLAG_MSLS) == 1U);


XMC_GPIO_SetOutputHigh(SOFT_CS);
}


My problem is that my SOFT_CS is way faster then the Hardware CS. I also have attached a Screenshot of the measurment. First Channel is the hardware slave select and second chanel is the gpio slave select.2532.attach
0 Likes
jferreira
Employee
Employee
10 sign-ins 5 sign-ins First like received
0 Likes