XMC4500 SPI half-duplex receiving problem

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

cross mob
Not applicable
Hello!

I have tried to use Infineon SPI Master APP to create a half-duplex communication link. As this operation mode is less documented (I couldn't find any example for half-duplex links) I have tried some simple tests before connecting the microcontroller board to the slave device (an Infineon angle sensor).

My simple test setup looked like this: I have connected a 100k ohms pull-up resistor to the MOSI/MISO pin (in a half-duplex configuration the MOSI and MISO are the same) and monitored this pin with the help of an oscilloscope. From the APP GUI I configured it in the half-duplex mode with interrupt based transmission and reception. I chose the default speed (19.2kb) and in the generated code I added a function call to transmit a string (the transmitted string was "Hello") and a function call to receive a character.

When transmitting I could observe both the clock signal and the transmitted data on my oscilloscope. When receiving, I could observe the clock signal and the MISO line pulled up to logic '1'. Based on these observations I concluded that the transmit/receive pin switches correctly from being driven (by the transmit output buffer) to the high impedance (input) mode.

To my surprise though, instead of receiving an all-ones byte (decimal 255 or binary 11111111), the receive function call returned the last transmitted character.

So my question is the following: is this behavior intended or did I discover a bug in the SPI Master APP? In my opinion, if this behavior is intended, it is an awkward intention and should be changed to the expected behavior: return the actual received information, not some buffered information.

I have to mention that I observed the same behavior with and without enabling receive queues.

Thank you!
0 Likes
6 Replies
Not applicable
Hi,

We tried the setup and it works fine on my setup. The sequence used is as follows:
1. Transmit test data byte.
2. Wait for transmission to finish(SPI_MASTER_IsTxBusy)
3. Receive 1 test byte
4. Wait for reception to finish(SPI_MASTER_IsRxBusy)

Following this sequence is important because, in half duplex mode, the peripheral would be sampling the level of same pin that is transmitting.
Therefore, whenever we transmit data, the same data will be received in the peripheral buffer. The APP takes care of flushing the buffer before starting a new reception.
In the above sequence, after transmission(step1), we are waiting for the driver to finish transmission(step2).
Then the reception is started(step3). In the step of receiving, we transmit dummy data (255).
After this we wait for receiving 1 byte in the buffer(step4).
The received data in the buffer is 255 since no slave is connected.

Are you skipping step 2 or doing step 3, before executing step 1?

Regards,
Daryl
0 Likes
lock attach
Attachments are accessible only for community members.
Not applicable
I have actually followed all your steps in my tests, but still I get a wrong reading. I attach my project which I ran on an XMC4500 Relax Lite Kit.
0 Likes
Raj
Employee
Employee
The MOSI/MISO pin is configured in the Pin Settings tab as Push Pull. Half duplex mode requires Open Drain configuration.
0 Likes
Not applicable
I see (the APP should be corrected to not allow selecting Push Pull in half-duplex mode). I made the change: set Open Drain for the MOSI/MISO pin, still the result is the same: I get a correct reading only at the second attempt.

You can easily verify this by commenting the second SPI_MASTER_Receive. In this case after a hardware reset (pressing the RESET button on the board) the led no longer turns on.

By un-commenting the second SPI_MASTER_Receive after a hardware reset the led turns on every time.

Could you please confirm that for the same setup the code actually works for you?
0 Likes
Not applicable
HI,

The issue that you have seen (last byte of data remains in the shift register) when using the function SPI_MASTER_IsTxBusy(&SPI_MASTER_0) returns false
This happens when calling the receive API (SPI_MASTER_Receive(&SPI_MASTER_0, &byte, 1);) immediately following this above condition; the last byte from the earlier transmission will be received.

To solve the issue that the APP does not know if the shift register is idle, we can use the slave select signal status(MSLS flag) for the channel idle status. This is an internal signal and has nothing to do with the number of slave selects used.

When the frame end mode is enabled, the internal slave select signal(MSLS) will not change when the channel is idle. This (MSLS) signal is enabled when the frame end mode is not selected, as shown below.

Please change the sequence as follows,
SPI_MASTER_Transmit(&SPI_MASTER_0, "He", 2); //data that the user transmits
while(SPI_MASTER_GetFlagStatus(&SPI_MASTER_0, XMC_SPI_CH_STATUS_FLAG_MSLS)); //loop until MSLS is low; this means that data is not available
SPI_MASTER_Receive(&SPI_MASTER_0, &byte, 1); //in receive mode, device give clock to receive data
while (SPI_MASTER_IsRxBusy(&SPI_MASTER_0)); //wait for data to be available
// SPI_MASTER_Receive(&SPI_MASTER_0, &byte, 1);


Also, I have submitted an eTicket: #943172977 http://www.infineonforums.com/support/dave3/index.php?option=com_maqmahelpdesk&Itemid=0&id_workgroup... for your request of a half duplex operation to fix the pin configurations to Open-Drain.

Regards,
Daryl
0 Likes
Not applicable
Hi,

I have checked with the APP developer. He recommends no change to APP as current implementation allows us to achieve higher transmission speed as it is possible to change the direction of the pin configuration when using push-pull mode at runtime to achieve higher transmission speed.

Regards,
Daryl
0 Likes