XMC4500 SPI - switch Chip-Selection,

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

cross mob
Not applicable
Hi,

Now I'm already working for a while with the XMC and would like to set the chip select line(s) in the SPI module.
The set of the CS lines I have already found out.
For a better understanding of my program: I (we) write to all needed hardware XMC modules classes where methods for configuration and actions are provided.

The SPI-Module is configured as:
- Mode: SPI001_STANDARD_FULLDUPLEX;
- BaudRate = 40000
- FrameLen: 16
- WordLen: 16
- HBMode: SPI001_MSB
- ClkPol: SPI001_CLK_POL1
- ClkPh: SPI001_CLK_PHASE0v
- LeadTrailDela: SPI001_ONE_SCLK_PERIOD
- NextFrameDelay: SPI001_ONE_SCLK_PERIOD;
- Transmit/Receive FIFO ... Size: 16 Bit; Trigger limit: 1
- CSPol: inverted (Active-Low)


My Idea is to change the CS-Pattern before I want to transmit a message.
This means:
if FIFO is not full
If CS-Pattern has changed
wait until fifo is emty
change cs patterm
send message


In the method for sending the SPI messages, I have to select the CS line following code:
// if chip-select pattern has changed since last run
// first part: set the SELO Register to 0x00
USICRegs->PCR_SSCMode &= ~USIC_CH_PCR_SSCMode_SELO_Msk;
// second part: write the cspattern into SELO-Register
USICRegs->PCR_SSCMode |= (cspattern << USIC_CH_PCR_SSCMode_SELO_Pos)
& USIC_CH_PCR_SSCMode_SELO_Msk;
// store current cs pattern for next run



Now i found out ...
SPI001_TRANS_SHIFT_IND_FLAG --> TSIF (transmit event happened)
SPI001_FIFO_STD_TRANSMIT_BUF_FLAG --> STBI (transmit buffer event happened)
SPI001_FIFO_TRANSMIT_BUF_ERR_FLAG --> TBERI (transmit buffer error happened)

And i wanted to solve my problem as followed. Meanwhile, we do not consider: "if FIFO is not full"

while((SPI001_GetFlagStatus(p->handle, SPI001_TRANS_SHIFT_IND_FLAG))!=SPI001_SET);	
//alternatively also: while((SPI001_GetFlagStatus(p->handle, SPI001_FIFO_STD_TRANSMIT_BUF_FLAG))!=SPI001_SET);
SPI001_ClearFlag(p->handle,SPI001_TRANS_SHIFT_IND_FLAG);
//alternatively also: SPI001_ClearFlag(p->handle,SPI001_FIFO_STD_TRANSMIT_BUF_FLAG);

EnableStartOfFrame((*p->handle)); // removing/adding did non bring a improvement
SPI001_WriteData(p->handle, &data, SPI001_STANDARD); // send Data
EnableEndOfFrame((*p->handle)); // removing/adding did non bring a improvement


==> At sending more messages the CS-Pattern get changed immediately (all messages gets sended with configuration for last message) and the messages get transferred in FIFO Buffer.
When a sufficient number of messages (>~20), the CS pattern get changed sometime ...


I also observed the TSIF, STBI and TBERI
TSIF ... every run one
STBI ... every two one except the first run (why)
TBERI ... every run one

Now my question to you .... how can I reach my "wish" to change the CD Pattern before sending the message / every message.
But wait directly after sending the message up to the time when the FIFO Buffer is empty is no option for me.

Best regards and Thank for your help!
Gerald
0 Likes
6 Replies
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
In master mode, a master slave select signal MSLS is generated by the internal slave select generator. In order to address different external slave devices independently, the internal MSLS
signal is made available externally via up to 8 SELOx output signals that can be configured by the block SELCFG (select configuration).

The control of the SELCFG block is based on protocol specific bits and bit fields in the protocol control register PCR. For the generation of the MSLS signal please refer to
Section 17.4.3.2.
• PCR.SELCTR to chose between direct and coded select mode
• PCR.SELINV to invert the SELOx outputs
• PCR.SELO[7:0] as individual value for each SELOx line
0 Likes
User6412
Level 4
Level 4
My contribution to this discussion:

the SELCTR flag allowes us to choose between direct and coded select mode. At least in XMC4500 stepping AB this flag is ignored and the only coded mode is available at any time (there is nothing to find about this error in errata!).
0 Likes
Not applicable
Hi

I found a solution to manage the SPI-Handling:
At first i configured additional to the configuration above the Limit of the FIFO Buffer to 2.

//-> pretend to send half messages if > 16 Bit SPI message
// set TRBSR->LIMIT to 2 -> Sending of whole 32 Bit Message is every time possible.
WR_REG(spiHandle->USICRegs->TBCTR, USIC_CH_TBCTR_LIMIT_Msk, USIC_CH_TBCTR_LIMIT_Pos, 0x2);


Then I have wrote two functions:

inline static void waitUntillTrxFinished(SPI001_HandleType *spiHandle) {
// wait until transmission buffer empty
// Transmit/Receive Buffer Status Register (TRBSR) -> Filling level shows how many elements are in FIFO Buffer
while (RD_REG(spiHandle->USICRegs->TRBSR, USIC_CH_TRBSR_TBFLVL_Msk, USIC_CH_TRBSR_TBFLVL_Pos));
// wait until transmission finished
while (SPI001_GetFlagStatus(spiHandle, SPI001_MSLS_STATUS_FLAG) == SPI001_SET);
}

int seloPattern = 0; // global declatration only for demonstrating

inline static void setCSPattern(SPI001_HandleType *spiHandle, u16 cspattern) {
if (seloPattern != cspattern) { // chip-select pattern has changed
waitUntillTrxFinished(p);
// write the cspattern into SELO-Register
WR_REG(spiHandle->USICRegs->PCR_SSCMode, USIC_CH_PCR_SSCMode_SELO_Msk, USIC_CH_PCR_SSCMode_SELO_Pos, cspattern);
seloPattern = cspattern; // store current cs pattern for next run
}
}


Sending/Receiving a Message:
Call id blocking sending is needed:

waitUntillTrxFinished(p); // before sending: wait until current Transmission has finished


Call a function for sending which includes the following code:

[...]
u16 trxfifoLevel = RD_REG(spiHandle->USICRegs->TRBSR, USIC_CH_TRBSR_TBFLVL_Msk, USIC_CH_TRBSR_TBFLVL_Pos); // Transmit/Receive Buffer Status Register TRBSR->TBFLVL shows Transmit FIFO Level
u16 trxfifoSize = 2 << (spiHandle->TxFifoSize - 1); // implement 2^x as shift; 16 Bit result is enough (TxFifoSize 0b001...0b110)
if (config.FrameLen > 16 && (trxfifoLevel + 2) <= trxfifoSize) { // more than 16 Bit of Data to transmit -> two messages
// and in fifo has to be enough storage for two messages
u16 hi_trx_data = (trx_data & 0xFFFF0000) >> 16;
u16 lo_trx_data = trx_data & 0xFFFF;
SPI001_ReadData(spiHandle, &hi_rcv_data); // receive higher 16 Bit
SPI001_ReadData(spiHandle, &lo_rcv_data); // receive lower 16 Bit
SPI001_WriteData(spiHandle, &hi_trx_data, SPI001_STANDARD); // transmit higher 16 Bit
SPI001_WriteData(spiHandle, &lo_trx_data, SPI001_STANDARD); // transmit lower 16 Bit
} else if (pconfig.FrameLen <= 16 && trxfifoLevel < trxfifoSize) { // 16 Bit or less to transmit
// and in fifo has to be enough storage for one messages
u16 lo_trx_data = trx_data & 0xFFFF;
SPI001_ReadData(spiHandle, &lo_rcv_data); // read Data from register (received at last sending)
SPI001_WriteData(spiHandle, &lo_trx_data, SPI001_STANDARD); // transmit 16 Bit message
} else {
// error: not enough space in buffer for message
[...]
}
*rcv_data = lo_rcv_data | (hi_rcv_data << 16); // Build up received Message consisting of higher and lower 16 Bit
[...]


I hope this will help somebody here 🙂

Best Regards,
Gerald
0 Likes
Not applicable
Hi Gerald,

Is it possible to share your whole project? I'm trying to do the same, but I'm a bit stuck at the moment.

Thanks in advice
0 Likes
Not applicable
Hi,

I wanted to implement an SPI transferByte API for which I configured Frame length & Wordlength as 8 only, and before transmitting data I am clearing the ALTERNATE RECIEVE Flag, I am able to see DATA On MOSI PIN. For reading the response, I am sending dummy data but there is nothing change on MISO line.(CS is working fine).
So what further configuration we need to do for reading a Byte ? and for Transmitting and Receiving a Byte, do we just need to monitor ALTERNATE RECIEVE flag only?
0 Likes
chismo
Employee
Employee
First like received
Hi Irfan,

I think this is the same question as the new thread that you created so I have directly replied to that thread.
http://www.infineonforums.com/threads/3493-SPI-Transmit-and-Receive-Flag.
I will leave this thread as it is then.

Regards,
Min Wei
0 Likes