The Netduino forums have been replaced by new forums at community.wildernesslabs.co.
This site has been preserved for archival purposes only
and the ability to make new accounts or posts has been turned off.
A new user here. I have experience with native embedded, mostly AVR/MSP430/PIC, some ARM M3. Now exploring NetMF waters somewhat cautiously :-).
I am glad to see SPI timing fixes in 4.2.2, which helps immenselly. However I am still seeing CPOL issue. I am unable to use SPI modes 0 and 1, because CPOL appears to be 1, regardless of Clock_IdleState parameter of SPI.Configuration.
Here is my code:
public class SPIMain{ private static byte[] sendBuffer; private static byte[] receiveBuffer; public static void Main() { SPI.Configuration spiConfiguration = new SPI.Configuration( Pins.GPIO_PIN_D10, false, // CS active low 2, // CS setup time (2us) 2, // CS hold time (2us) false, // clock state during idle true, // sample of which edge 500, // clock rate in kHz SPI_Devices.SPI1); SPI spi = new SPI(spiConfiguration); sendBuffer = new byte[10]; receiveBuffer = new byte[10]; sendBuffer[0] = 0xAA; sendBuffer[1] = 0x55; while (true) { DoubleSend(spi); } } private static void DoubleSend(SPI spi) { spi.WriteRead(sendBuffer, 0, 2, receiveBuffer, 0, 2, 0); spi.WriteRead(sendBuffer, 0, 2, receiveBuffer, 0, 2, 0); }}
Hi rcross,
Curious. For diagnostics here...if you set the clock idle state to true, does that reverse things properly? If you swap the clock idle edge?
I see that the STM32 core in NETMF toggles CPHA, but it ties CPOL directly to the clock idle state.
Chris
thanks for speedy reply. I think your description makes sense from ARM core perspective - NetMF docs would imply that Clock_IdleState determines CPOL, and that CPHA is determined by Clock_Edge. In NetMF definition the two are independent, while SPI spec says that CPHA is relative to CPOL, but I could live with the independt values. However I suspect some layer above ARM core is keeping some residual state when setting these up.
For the sake of experiment I tried all four combinations. BTW, the reason I do double transaction in the experiment, is that I see different behavior depending on what the state of SCK line was prior to /CS transition.
1. Clock_IdleState = true, Clock_Edge = false. According to NetMF docs this should be mode 2 - CPOL=1, CPHA=0. What I am seeing is mode 1 - CPOL=0, CPHA=1. Also, notice extraneous MOSI pulse while setting first bit for the first transaction:
2. Clock_IdleState = true, Clock_Edge = true. According to docs this should be mode 3 - CPOL=1, CPHA=1. What I am seeing is two different behaviors - on first transaction the SCK drops to low just before /CS transition, and it is totally messed up transaction - there are 17 SCK positive edges within /CS assertion window (MOSI is sampled on pos edge). Then it leaves SCK in high state (as Clock_IdleState instructs) and subsequent send is mode 3 CPOL=1, CPHA=1:
3. Clock_IdleState = false, Clock_Edge = false. According to docs this should be mode 1 - CPOL=0, CPHA=1. What I am seeing is more or less mode 1 - CPOL=0, CPHA=1. There is inexplicable pulsing of MOSI after /CS before first SCK pulse, but it is valid from SPI perspective, yet it smells fishy:
4. Clock_IdleState = false, Clock_Edge = true. According to docs this should be mode 0 - CPOL=0, CPHA=0. What I am seeing is different behavior during first transaction than second. For the first transaction mode is 0 - CPOL=0, CPHA=0, but there is short pulsing of MOSI during setup of the first bit (which is valid, but suspicious), then on the second transaction mode is 3 - CPOL=1, CPHA=1:
Hi rcross,
Thank you very much for the additional data.
Just to clarify: you are now able to invert the clock idle signal--but there are some SPI CPOL/CPHA modes you'd like to be able to represent in NETMF?
BTW, the extra signaling seem to be setup-related. We've seen those while working on the SPI code. Some of them are related to how NETMF uses SPI generally, and some of them are related to how the STM32 core behaves. In all cases that we've studied, the extra signaling is benign as it happens when the SPI clock is disabled and therefore is not interpreted by the attached device.
I think the best thing to do is to bring the current NETMF implementation more in line with the traditional SPI CPOL/CPHA standard. We want to avoid breaking backwards-compatibility with existing NETMF code, but we would prefer to err on the side of technical correctness wherever possible.
Chris
Yes, I was able to invert the clock. My remaining concerns are twofold -
a ) I am not able to implement mode 0 reliably;
b ) incorrect and unstable behavior when switching modes (see case 2 in the post above).
I will run experiments with FEZ Panda II to see if it has the same issue. Also, it would be interesting to see what Netduino or Netduino Plus do in this case.
I am pondering netMF/Netduino SDK fixes, but I do not have RVDS license and reading the forums I get the impression that GCC toolchain is not a good path due to size of resulting binaries.
Do you think GCC toolchain (yagarto or coocox) is a viable option, as in, not just for trying it out, but for compiling the production final firmware?
Thus it appears that mapping Clock_IdleSate and Clock_Edge to CPOL and CPHA is a Netduino platform issue and not NetMF issue.
On PandaII am also seeing the effect of previous CPOL when changing CPOL for the new mode - the previous CPOL will be the state of SCK when /CS is asserted, but will snap to the new CPOL when /CS is deasserted. I am not sure whether this is desired behavior - on one hand it is doing what it is told to do, on the other hand it would require extra SCK transition to do what it is told to do. I think I could live with this.
Couple more things to note:
1. USBizi is much slower chip, thus byte boundaries are more distinct.
2. Even being a slower chip it is closer to the specified 500kHz frequency at ~450kHz than NP2, which runs ~350kHz.
3. For the USBizi the whole SPI transaction looks so much cleaner in the LA/scope than NP2. I know it has nothing to do with reliability, but still, it inspires confidence, when observed behavior matches specified behavior.
So how about that encouraging nudge towards GCC toolchain?
So how about that encouraging nudge towards GCC toolchain?
AFAIK Netduino 2 firmware can be compiled with any of the recent GNU-based toolchains, but it requires some changes. For Netduino firmware you'd need size-optimized C RunTime libraries - the latest release of GNU Tools for ARM Embedded Processors has introduced newlib-nano, the resulting image size is very similar to RVCT (used to build the official firmware).
Also, there is free 30-days limited RVDS edition available on ARM website...
Do you know an entry point in the Netduino wiki for the GCC toolchain? I am still searching through various threads and external resources trying to piece the strategy.
Do you know an entry point in the Netduino wiki for the GCC toolchain? I am still searching through various threads and external resources trying to piece the strategy.
Hm, I don't think there is any
Unfortunately, I have not had a chance yet to play with Netduino Plus 2 source code, so I don't know exactly what needs to be changed in order to get GCC-built firmware working, but you could have a look at my NetduinoGoFirmware repository and there is also patch for GHI's Cerberus (it also uses STM32 micro).
If you are interested, there are a few hints:
Flash memory layout file (aka "scatterfile") is usually correct only for the compiler used to produce the official firmware, i.e. RVDS in case of Secret Labs. Keil MDK uses the same compiler/linker, so scatterfile can be created by simply copying RVDS one. Scatter file for GCC is almost always completely wrong. In all likelihood you will not be able to use NetduinoGo GCC scatterfile directly, but it should not be too hard to modify it (I think Netduino Plus 2 uses additional bootloader section or such),
There were a few assembly routines incorrectly generating ARM instructions, which caused fault on Cortex-M4. It was needed to add ".thumb_func" directive there, but I think this was fixed in .NET MF 4.2. The other problem was that the default build configuration forces use of ARM libraries, these linker settings has to be changed so correct Thumb libraries are used (the path can vary depending on the toolchain used),
Yagarto does not have longlong support by default, which was causing some problems with string formatting. I solved that by compiling a custom version. But I also noticed there was a fix related to number formatting in .NET MF 4.2, so it could be related.
Nonetheless, I switched to different toolchain (GNU Tools for ARM Embedded).
That's a great write up ziggurat29! I have yet to try compiling my own Netduino firmware as it did not seem like a task for just mere mortals. Your tutorial is well written and has removed much of the mystery and confusion. Now I just need to find the time to give it a shot, though one shouldn't expect any radical firmware enhancements from me at anytime in the near future. Probably just a bunch of noob questions
I tried to replicate what you were seeing, using the same code as the sample you provided. It would appear that I am getting different results than you. I too am using the latest firmware, 4.2.2.0 on the Netduino Plus 2.
Mode 2 - this is where things start to get wonky. I've tried playing with the ChipSelect_SetupTime and ChipSelect_HoldTime but haven't been able to find the proper combination, if that's even a possible solution.
My knowledge of SPI is limited at best, but I'm hoping to gain a better understanding while I work through some of these issues. Any input you and the rest of the braniacs in this thread can provide would be greatly appreciated.
So this is looking a lot better. The timing issues with CPOL and CPHA seem to have been fixed with the latest firmware updates, version 4.2.2.1. 0/
Here are some screen shots of the various modes, now correctly being interpretted by the Logic's SPI analyzer. There does seem to be an inconsistent blip on the MISO and sometimes the MOSI lines, however they don't affect anything in the transmission.
BTW, the blips seem to be the STM32's way of getting into the proper state (mindset?) for its operations. They should not affect SPI communication in any way since they're outside of the sampling edge.