2017-01-10 09:10 AM
Hello,
For the past month I have been developing a device that has multiple features on an STM32F103ZG, with the intentions of basically replacing the chip and migrating the code with an STM32F427ZI when I was closer to completion.
The devices are mostly pin compatible with very small alteration to the ADC power, but my issue is with SPI.
The device is set as an SPI2 slave on receive only with hardware NSS signal. The associated pins are MOSI (PB15), SCK(PB13) and NSS (PB12). The SCK waveform is pretty consistent with slight random and intermittent delays, but the entire structure is fine and not really any different from another other SPI waveform I’ve seen using a Logic Analyzer.
On the STM32F103 it works great and everything goes as intended. I am using DMA to load incoming SPI data into an array. On the STM32F427 it does not work properly. It constantly misses bits which forces it out of alignment. Once out of alignment it will repeat the behaviour for a while until it either kicks back into alignment from missing another set of bits, or it will kick into another random alignment all together.
The STM32 is running at 3V, and the incoming signal is 5V. I didn’t want to rely on if the respective pins were 5V Tolerant between the chipsets, so I decided to level shift the input with a 4050 non-inverting hex buffer. This setup works perfectly on the STM32F103, but not so on the STM32F427. After thinking about it for a while, I wasn’t confident that the 4050 wasn’t creating an issue for the STM32F427. I decided to use a resistor voltage divider on each pin instead of the 4050 to get the voltage to 3V but the result was the same on the STM32F427. It was constantly getting out of sync. I didn’t test that setup on the STM32F103, but a few years ago I created a device with an identical incoming SPI signal to an STM32F103CB and resistor voltage divider network and it worked then.
In STM32CubeMX, the SPI2 Clock Prescaler is accessible on the STM32F103 but not on the STM32F427. The prescaler that I use on the STM32F103 is 256, resulting in a 140.625 Kbit/s baud rate. I have always wondered why that was put in place for slave devices as the speed of communication is dictated by the speed of the SCK on the Master device, so when I noticed it missing from the STM32F427 it seemed natural for it to be that way. I’m thinking now that it’s as if it was necessary and I didn’t notice the complete purpose for having that as a Slave device.
I’m not sure what I’m missing now. Does anyone have any suggestions?
Thanks,
Patrick
2017-01-10 09:55 AM
Compare the CPHA/CPOL settings of both chips? Best reading out the SPI registers.
[EDIT] on hardware front make sure there are no ringings/reflections on the clock. Is the connection long? Has it adequate ground? If you can influence the master's slew rate, try to.
JW
2017-01-10 11:59 AM
CPOL and CPAH are identical between the two. CPOL off, CPAH on
The set of registers were configured differently, but I made them identical in debug to see how it would perform and it still does the same thing. Below is the state that is configured for each chip directly from STM32CubeMX as taken from Debug mode
STM32F103
CR1: 0x479
BIDIMODE: 0
BIDIOE: 0
CRCEN: 0
CRCNEXT: 0
DFF: 0
RXONLY: 1
SSM: 0
SSI: 0
LSBFIRST: 0
SPE: 1
BR: 0x07
MSTR: 0
CPOL: 0
CPAH: 1
CR2: 0x01TXEIE: 0
RXNEIE: 0
ERRIE: 0
SSOE: 0
TXDMAEN: 0
RXDMAEN: 1
SR: 0x02
BSY: 0
OVR: 0
MODF: 0
CRCERR: 0
UDR: 0
CHSIDE: 0
TXE: 1
RXNE: 0
STM32F427
CR1: 0x441
BIDIMODE: 0
BIDIOE: 0
CRCEN: 0
CRCNEXT: 0
DFF: 0
RXONLY: 1
SSM: 0
SSI: 0
LSBFIRST: 0
SPE: 1
BR: 0x00
MSTR: 0
CPOL: 0
CPAH: 1
CR2: 0x21
TXEIE: 0
RXNEIE: 0
ERRIE: 1
FRF: 0
SSOE: 0
TXDMAEN: 0
RXDMAEN: 1
SR: 0x02
TIFRFR: 0
BSY: 0
OVR: 0
MODF: 0
CRCERR: 0
UDR: 0
CHSIDE: 0
TXE: 1
RXNE: 0
2017-01-10 12:17 PM
In SPI slave mode, try with minimum prescale value. The way to set alternate function is slightly different, make sure no sw incurred glitches happen during the communication. Using 5v tolerant io as input for both clock and data without shifter may work fine. Voltage divider would degrade signals quality, however speed is low here. Oscilloscope is a handy tool vs logic analyser for debugging MCU applications.
Check the alternate function table and dma stream table to make sure all is fine. When the data look corrupted, does it look like bit or byte corruption?
2017-01-10 02:03 PM
The SPI prescaler is not accessible via STM32CubeMX on the STM32F427. That is part of the problem. It is accessible and seems to be of importance on the STM32F103, but it is not on the STM32F427. When I manually adjust it in Debug mode to the lowest setting it doesn’t improve anything at all. I have confirmed that these pins are 5V Tolerant on the Datasheet so I’m just about to take out the 4050 and put the SPI directly to the chip.
There are no glitches on the SPI bus. It works perfectly on the STM32F103 and literally all I do is remove the STM32F103 from the circuit and place the STM32F427 in to which it no longer works as intended.
I have used an oscilloscope on this circuit with the STM32F427 in and it looks identical to when the STM32F103 is in there.
The data is bit corrupted. I am receiving 3 bytes of data between CS pulses, and the data gets shifted between 1 bit and what seems like up to as much as 8 bits in either direction as if there is a sync issue. I am investigating the CS line right now, but again, it doesn’t explain why the same circuit works perfectly on the STM32F103 but doesn’t work correctly on the STM32F427
2017-01-11 12:01 AM
The data is bit corrupted. I am receiving 3 bytes of data between CS pulses, and the data gets shifted between 1 bit and what seems like up to as much as 8 bits in either direction as if there is a sync issue.
Please post examples.
You could also try to use bidirectional mode and transmit distinguishable data to definitively exclude issues with SCK.
JW
2017-01-11 05:50 PM
So I switched the three lines, MOSI, SCK and NSS to a direct connection as you recommended. No voltage divider and no 4050 in there. Just straight 5V lines on the inputs. That made no difference to what it was doing.
I'm not exactly sure what you mean by examples, and unfortunately I can't switch the incoming data at all. It is fixed so I must read what is sent to me.
So I came up with a solution last night that seems to be working properly after a few hours of testing, but it does nothing to sort out the root issue that I presented here. I decided to go a different direction and rather than mess around with SPI2, I decided to try and input to SPI1 instead and it now works perfectly. It still doesn't explain why it works properly on SPI2 with the STM32F103, but doesn't work properly on the STM32F427 on SPI2. I can only imagine it has something to do with how the how the board is laid out and how the STM32F103 responds to noise on the SPI lines vs how the STM32F427 does.
So that puts a temporary end to my struggles. I won't be investigating further on why it doesn't work correctly on the SPI2, I will just be using it on SPI1 for Slave receive in this application from this point out.Thank you for all the attempted help.