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.
I have a similar problem with my N+2. I have a custom shield with a lot on it including 2 hc595's and 2 hc165 IC's. just the same as in stefan's original bit shift shizzel. (totally love the toolbox he made, Thanks again) I've been running in a bread board with my N+1 till my first prototypes turned up same day as my N+2. YEA!!.........Noooooooo!!!.
I installed the latest SDK, and latest firmware. opened a new N+2 project and bassicly copied the code over except the using statements of course. Made reference to the latest version off the micro toolbox and thought it would work. But allas no luck. I thought i'd poured a small fortune down the drain with the boards. but to my amazment. the good old N+1 went strait from the bread board and worked on the new PCB. Yea.
However, i've had zero luck getting it work with the SPI my N+2. sort of. it seams the first chips in the chains work but not the second. and guess what. they just blink and dance around a bit. I'm not sure where the problem lies. Just hope i can save these super shields.
Below is a copy of each of the Codes. It's a bit embassing but I'm still at proof of concept. And if any one can help me clean it up a little I'd really apreciate it.
They are the same except for the top of each, where creating a new N+2 Application, it added more default "using" statements.
code on N+1 - 4.2.0.0
using System;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;using Toolbox.NETMF.Hardware;namespace Multiplexing_Test{ public class Program { public static OutputPort onBoardLed = new OutputPort(Pins.ONBOARD_LED, false); public static OutputPort resetchain = new OutputPort(Pins.GPIO_PIN_D4, true); public static IIRQPort[] Buttons = new IIRQPort[8]; public static IGPOPort[] Led = new IGPOPort[16]; public static IGPOPort[] LCD = new IGPOPort[8]; public static IGPOPort Pin; public static AnalogInput pot1 = new AnalogInput(AnalogChannels.ANALOG_PIN_A5); public static int pot1Value = 0; public static IGPOPort backlight; public static void Main() { Ic74hc595 OutChain = new Ic74hc595(SPI_Devices.SPI1, Pins.GPIO_PIN_D7, 2); Ic74hc165 InChain = new Ic74hc165(SPI_Devices.SPI1, Pins.GPIO_PIN_D8, 2); LCD[1] = OutChain.Pins[2]; LCD[3] = OutChain.Pins[0]; LCD[4] = OutChain.Pins[3]; LCD[5] = OutChain.Pins[4]; LCD[6] = OutChain.Pins[5]; LCD[7] = OutChain.Pins[6]; backlight = OutChain.Pins[7]; resetchain.Write(false); backlight.Write(true); Hd44780Lcd Display = new Hd44780Lcd( Data4: LCD[4], Data5: LCD[5], Data6: LCD[6], Data7: LCD[7], ClockEnablePin: LCD[1], RegisterSelectPin: LCD[3] ); Led[0] = OutChain.Pins[15]; Led[1] = OutChain.Pins[8]; Led[2] = OutChain.Pins[9]; Led[3] = OutChain.Pins[10]; Led[4] = OutChain.Pins[11]; Led[5] = OutChain.Pins[12]; Led[6] = OutChain.Pins[13]; Led[7] = OutChain.Pins[14]; InChain.EnableInterrupts(); Buttons[0] = InChain.Pins[0]; Buttons[0].OnStateChange += new StateChange(Program_OnStateChange); Buttons[1] = InChain.Pins[1]; Buttons[1].OnStateChange += new StateChange(Program_OnStateChange2); int x = 0; while (x < 5) { onBoardLed.Write(true); Thread.Sleep(200); onBoardLed.Write(false); Thread.Sleep(200); x++; } Thread.Sleep(5000); Display.ClearDisplay(); Display.Write("Hello World!"); Thread.Sleep(2000); Display.ChangePosition(1, 0); Thread.Sleep(500); Display.Write("Greetings!"); InterruptPort button3 = new InterruptPort(Pins.GPIO_PIN_D3, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeHigh); button3.OnInterrupt += new NativeEventHandler(button3_OnInterrupt); Thread.Sleep(Timeout.Infinite); } static void Program_OnStateChange(IIRQPort Object, bool State, DateTime Time) { if (State == true) { int y = 400; while (y > 1) { int x = 0; onBoardLed.Write(true); while (x < 8) { Led[x].Write(true); Thread.Sleep(y); Led[x].Write(false); x++; } x = 0; y -= 25; } } if (State == false) { onBoardLed.Write(false); Led[0].Write(false); Led[1].Write(false); Led[2].Write(false); Led[3].Write(false); Led[4].Write(false); Led[5].Write(false); Led[6].Write(false); Led[7].Write(false); } } static void Program_OnStateChange2(IIRQPort Object, bool State, DateTime Time) { if (State == true) { int y = 1; while (y < 100) { int x = 0; onBoardLed.Write(true); while (x < 8) { Led[x].Write(true); Thread.Sleep(y); Led[x].Write(false); x++; } x = 0; y += 10; } } if (State == false) { onBoardLed.Write(false); Led[0].Write(false); Led[1].Write(false); Led[2].Write(false); Led[3].Write(false); Led[4].Write(false); Led[5].Write(false); Led[6].Write(false); Led[7].Write(false); } } static void button3_OnInterrupt(uint data1, uint data2, DateTime time) { pot1Value = ((int)pot1.ReadRaw() - 1024) * -1; int x = 0; while (x < 5) { onBoardLed.Write(true); Thread.Sleep(200); onBoardLed.Write(false); Thread.Sleep(200); x++; } Hd44780Lcd Display = new Hd44780Lcd( Data4: LCD[4], Data5: LCD[5], Data6: LCD[6], Data7: LCD[7], ClockEnablePin: LCD[1], RegisterSelectPin: LCD[3] ); Display.ClearDisplay(); Display.Write("You Pushed My Button Baby, YEAH!" + pot1Value.ToString()); } }}
Code on N+2 - 4.2.1.2
using System;using System.Net;using System.Net.Sockets;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;using Toolbox.NETMF.Hardware;namespace Multiplexing_Test{ public class Program { public static OutputPort onBoardLed = new OutputPort(Pins.ONBOARD_LED, false); public static OutputPort resetchain = new OutputPort(Pins.GPIO_PIN_D4, true); public static IIRQPort[] Buttons = new IIRQPort[8]; public static IGPOPort[] Led = new IGPOPort[16]; public static IGPOPort[] LCD = new IGPOPort[8]; public static IGPOPort Pin; public static AnalogInput pot1 = new AnalogInput(AnalogChannels.ANALOG_PIN_A5); public static int pot1Value = 0; public static IGPOPort backlight; public static void Main() { Ic74hc595 OutChain = new Ic74hc595(SPI_Devices.SPI1, Pins.GPIO_PIN_D7, 2); Ic74hc165 InChain = new Ic74hc165(SPI_Devices.SPI1, Pins.GPIO_PIN_D8, 2); LCD[1] = OutChain.Pins[2]; LCD[3] = OutChain.Pins[0]; LCD[4] = OutChain.Pins[3]; LCD[5] = OutChain.Pins[4]; LCD[6] = OutChain.Pins[5]; LCD[7] = OutChain.Pins[6]; backlight = OutChain.Pins[7]; resetchain.Write(false); backlight.Write(true); Hd44780Lcd Display = new Hd44780Lcd( Data4: LCD[4], Data5: LCD[5], Data6: LCD[6], Data7: LCD[7], ClockEnablePin: LCD[1], RegisterSelectPin: LCD[3] ); Led[0] = OutChain.Pins[15]; Led[1] = OutChain.Pins[8]; Led[2] = OutChain.Pins[9]; Led[3] = OutChain.Pins[10]; Led[4] = OutChain.Pins[11]; Led[5] = OutChain.Pins[12]; Led[6] = OutChain.Pins[13]; Led[7] = OutChain.Pins[14]; InChain.EnableInterrupts(); Buttons[0] = InChain.Pins[0]; Buttons[0].OnStateChange += new StateChange(Program_OnStateChange); Buttons[1] = InChain.Pins[1]; Buttons[1].OnStateChange += new StateChange(Program_OnStateChange2); int x = 0; while (x < 5) { onBoardLed.Write(true); Thread.Sleep(200); onBoardLed.Write(false); Thread.Sleep(200); x++; } Thread.Sleep(5000); Display.ClearDisplay(); Display.Write("Hello World!"); Thread.Sleep(2000); Display.ChangePosition(1, 0); Thread.Sleep(500); Display.Write("Greetings!"); InterruptPort button3 = new InterruptPort(Pins.GPIO_PIN_D3, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeHigh); button3.OnInterrupt += new NativeEventHandler(button3_OnInterrupt); Thread.Sleep(Timeout.Infinite); } static void Program_OnStateChange(IIRQPort Object, bool State, DateTime Time) { if (State == true) { int y = 400; while (y > 1) { int x = 0; onBoardLed.Write(true); while (x < 8) { Led[x].Write(true); Thread.Sleep(y); Led[x].Write(false); x++; } x = 0; y -= 25; } } if (State == false) { onBoardLed.Write(false); Led[0].Write(false); Led[1].Write(false); Led[2].Write(false); Led[3].Write(false); Led[4].Write(false); Led[5].Write(false); Led[6].Write(false); Led[7].Write(false); } } static void Program_OnStateChange2(IIRQPort Object, bool State, DateTime Time) { if (State == true) { int y = 1; while (y < 100) { int x = 0; onBoardLed.Write(true); while (x < 8) { Led[x].Write(true); Thread.Sleep(y); Led[x].Write(false); x++; } x = 0; y += 10; } } if (State == false) { onBoardLed.Write(false); Led[0].Write(false); Led[1].Write(false); Led[2].Write(false); Led[3].Write(false); Led[4].Write(false); Led[5].Write(false); Led[6].Write(false); Led[7].Write(false); } } static void button3_OnInterrupt(uint data1, uint data2, DateTime time) { pot1Value = ((int)pot1.ReadRaw() - 1024) * -1; int x = 0; while (x < 5) { onBoardLed.Write(true); Thread.Sleep(200); onBoardLed.Write(false); Thread.Sleep(200); x++; } Hd44780Lcd Display = new Hd44780Lcd( Data4: LCD[4], Data5: LCD[5], Data6: LCD[6], Data7: LCD[7], ClockEnablePin: LCD[1], RegisterSelectPin: LCD[3] ); Display.ClearDisplay(); Display.Write("You Pushed My Button Baby, YEAH!" + pot1Value.ToString()); } }}
As allways I can't thank you guys enough.
(BTW, goldphoenixpcb.biz, have done a pretty good job from what i can tell, and were really good to deal with. I didn't do much shopping for price because i was in a hurry, but i think it was reasonable for a 5 day turn around)
Interesting, I've used it last weekend, without problems. I only didn't included the 165 during that test.
if you leave out the 165s, does it work then?
Thanks for the reply.
just figured something else out as well. the pins are held low on bootup. the opposite to netduino plus 1. is it surposed to be like this for the new standard? If so. my shields are pretty worthless. I only ran 10 instead of 100. still expensive though. or maybe my n+2 is funky. I was using D4 to hold pins 13 high on the 575's on boot. this disabled the outputs so all the channels weren't held high on boot.
Thanks
It's beyond my area of expertise, but I believe pin D4 was actually bugged on the NP1, maybe it's related somehow.
Are you building a shield for commercial purpose? If so, what should I do to get one? Would love to help you out on that, software-wise
i took the 165's out of the code. but i didn't phisicly unsolder them. that's a bit painfull for 1am. It didn't fix it though. I'm going to try and go back to bed for the second time and sleep. I'll post a video of the delema tomorrow. i'm sure i can fix the pin problem with a pull up. just hoping i can make it forward/back compatible.
Stefan, If you wan't one of the boards and you love soldering, I can send you one for christmas(free). but it would be mostly naked of chips and stuff. i don't have much stock at the moment to spare but i'd send what i could. if you can wait till later in production i can send one then finished off. or both if you wan't. Just PM me your address.
Grant.
Thanks, So much.
I've been crawling through the forums looking for answers and have found similar problems with spi but not the same. I'm going to start referring people here that might be similar.
Maybe we're onto something bigger....
Grant--the STM32 starts up with pins in high-z mode (input, no pull-up). The Atmel chips generally boot with pull-ups enabled.
Stefan--just got your repro. Thank you!
Chris
Wow!!! Stefan and Chris looking into a problem for me. All we need is Mario to chime in and it would be like the three musketeer's. Seriously! I feel like, special or powerful, or something.
Don't feel to much pressure though. It is that time of year.
You wont get an angry post out of me. I'm so grateful for the knowledge you guys openly share.
I can keep developing software on my N+1 for now until it's resolved or worked around.
Merry Christmas Everyone.
In case you've all been stuck in your projects like me and forgotten.
I've been going crazy trying to drive a 8x8 RGB LED matrix for a week using some 75HC595's and I'm guessing it's due to an SPI bug. Fortunately I got a logic analyzer for Chrismas and can see that the data I'm writing out to SPI gets hosed. Here I'm tring to write out values, 1, 2, 3 but the logic analyzer is only seeing 3, 2, 3 as shown in my attachment. Any chance this could get fixed in the next firmware?
I've been going crazy trying to drive a 8x8 RGB LED matrix for a week using some 75HC595's and I'm guessing it's due to an SPI bug. Fortunately I got a logic analyzer for Chrismas and can see that the data I'm writing out to SPI gets hosed. Here I'm tring to write out values, 1, 2, 3 but the logic analyzer is only seeing 3, 2, 3 as shown in my attachment. Any chance this could get fixed in the next firmware?
This is a typical case where a logic analyzer does not help at all, but an oscilloscope does.
The SPI is not buggy: I tested two different small programs right now, and one is the above program. The CS timings are correct, as the SCK and the MOSI signals are.
Instead, the problem is related to the different design choice about the I/Os in the ST: this has been already described by Chris, few posts above. While Atmel (old Netduino) chose for ensuring a pull-up, ST chose for leave an input floating. This time I prefer the Atmel engineers choice, other the Italian-ST solution.
However, leaving an I/O floating leads to an unpredictable behavior when that I/O is connected to an HCMOS input. Let's say that while the Atmel guys offered an internal pull-up, ST team tells that you must provide your own pull-whatever...okay, just viewpoints: it's much like guessing the gender of the angels.
The logic analyzer does not understand half-a-way levels, and shows only boolean states. Since the actual voltage is raising/falling smoothly, the LA (as the chips) reads it as a "delay", but it is not related to any bug.
How to solve it?
The simplest yet best way to solve the problem is...adding a pull-up to *any* I/O that might turn to a floating state. I'd place a 5-10k resistor to +5V (or +3.3V) to SCK, MOSI, MISO, and any CS. That's for HC595 chips.
Note that there's NO a general rule for choosing between a pull-up or a pull-down: it depends on the external logic, and to the desired behavior.
This is a typical case where a logic analyzer does not help at all, but an oscilloscope does.
The SPI is not buggy: I tested two different small programs right now, and one is the above program. The CS timings are correct, as the SCK and the MOSI signals are.
Instead, the problem is related to the different design choice about the I/Os in the ST: this has been already described by Chris, few posts above. While Atmel (old Netduino) chose for ensuring a pull-up, ST chose for leave an input floating. This time I prefer the Atmel engineers choice, other the Italian-ST solution.
However, leaving an I/O floating leads to an unpredictable behavior when that I/O is connected to an HCMOS input. Let's say that while the Atmel guys offered an internal pull-up, ST team tells that you must provide your own pull-whatever...okay, just viewpoints: it's much like guessing the gender of the angels.
The logic analyzer does not understand half-a-way levels, and shows only boolean states. Since the actual voltage is raising/falling smoothly, the LA (as the chips) reads it as a "delay", but it is not related to any bug.
How to solve it?
The simplest yet best way to solve the problem is...adding a pull-up to *any* I/O that might turn to a floating state. I'd place a 5-10k resistor to +5V (or +3.3V) to SCK, MOSI, MISO, and any CS. That's for HC595 chips.
Note that there's NO a general rule for choosing between a pull-up or a pull-down: it depends on the external logic, and to the desired behavior.
Hope it helps.
Cheers
Thank you Mario, this is an excellent explanation of what people are seeing with their logic analyzers.
I'm having a similar problem and you can find the discussion over thin the SPI Clock thread.
I have tried Mario's suggestion regarding the pull-up resistors and also took some readings on the scope and not the LA. Both the data and the clock lines have signals on them before CS is dropped.
Forum member qc2012 found the same problem but found that running the clock at 1250 KHz gave the expected output. I have tried adjusting the clock and found that for me, clock frequencies of 1500 KHz or above give the expected output.
The SPI gets wrong. Similarly to the first snapshot, it issues only 22 falling edges (the 23rd is a 100ns spurious pulse at the beginning) and the first byte is wrong.
Upon the above tests, it is not the SS delayed, but the SCK anticipated, plus some other problem related to the SPI native driver.
At this point, yes, me too would expect a patch for those severe bugs.
Cheers
Biggest fault of Netduino? It runs by electricity.
Arghhh... I just spent three hours trying to figure out why my SPI code wasn't working. I'm glad I finally found this. I changed the parameters from (copied from working NP code):
true, // The idle state of the clock
false, // The sampling clock edge
1000, // The SPI clock rate in KHz
to (for my new NP2):
false, // The idle state of the clock
true, // The sampling clock edge
2000, // The SPI clock rate in KHz
Now my code works again. I assumed it was me, because I hadn't wired up a 74hc595 in several months, and figured I was doing something wrong. The three hours weren't totally wasted... it was a great SPI refresher .
Hopefully this gets patched so others won't have the same pain.