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.
It is in line 325, 331 and 334 of TCP.cs. Also see the attached screenshot.
Then the code has changes since I downloaded and compiled it. In my TCP.cs the calls to UTF8.GetChars(.) are on different line numbers and the code is different all together.
The code I compiled passes Utility.ExtractRangeFromArray (.) to the UTF8.GetChars(.) like so:
/// <summary>
/// A New Http Request
/// </summary>
/// <param name="tcpContent">The data content of the TCP packet</param>
/// <param name="socket"></param>
internal HttpRequest(byte[] tcpContent, ConnectionStatus socket)
{
// Parse the packet into the various properties...
_con = socket;
Headers = new Hashtable();
var delimiterLocation = Extensions.Locate(tcpContent, HeaderDelimiter);
var firstLineLocation = Extensions.Locate(tcpContent, CrLf);
var firstLine = new string(Encoding.UTF8.GetChars(Utility.ExtractRangeFromArray(tcpContent, 0, firstLineLocation)));
RequestType = firstLine.Split(' ')[0].Trim();
Path = HttpUtility.UrlDecode(firstLine.Split(' ')[1].Trim());
// Parse all the header keys and values
foreach (var aLine in new string(Encoding.UTF8.GetChars(Utility.ExtractRangeFromArray(tcpContent, firstLineLocation, (delimiterLocation - firstLineLocation)))).Split('\r', '\n'))
if (aLine.IndexOf(':') > 0) Headers.Add(aLine.Split(':')[0], aLine.Split(':')[1]);
Content = new string(Encoding.UTF8.GetChars(Utility.ExtractRangeFromArray(tcpContent, delimiterLocation+4, tcpContent.Length - (delimiterLocation+4))));
Protocol = firstLine.Split(' ')[2];
if (Headers.Contains("Host")) this.Host = (Headers["Host"] as string).Trim();
}
So the code has in fact changed since I compiled it. As a quick fix while waiting for an updated version of mIP (probably has been already), I guess you could simply tuck in the calls to ExtractRangeFromArray.
Then the code has changes since I downloaded and compiled it. In my TCP.cs the calls to UTF8.GetChars(.) are on different line numbers and the code is different all together.
The code I compiled passes Utility.ExtractRangeFromArray (.) to the UTF8.GetChars(.) like so:
/// <summary>
/// A New Http Request
/// </summary>
/// <param name="tcpContent">The data content of the TCP packet</param>
/// <param name="socket"></param>
internal HttpRequest(byte[] tcpContent, ConnectionStatus socket)
{
// Parse the packet into the various properties...
_con = socket;
Headers = new Hashtable();
var delimiterLocation = Extensions.Locate(tcpContent, HeaderDelimiter);
var firstLineLocation = Extensions.Locate(tcpContent, CrLf);
var firstLine = new string(Encoding.UTF8.GetChars(Utility.ExtractRangeFromArray(tcpContent, 0, firstLineLocation)));
RequestType = firstLine.Split(' ')[0].Trim();
Path = HttpUtility.UrlDecode(firstLine.Split(' ')[1].Trim());
// Parse all the header keys and values
foreach (var aLine in new string(Encoding.UTF8.GetChars(Utility.ExtractRangeFromArray(tcpContent, firstLineLocation, (delimiterLocation - firstLineLocation)))).Split('\r', '\n'))
if (aLine.IndexOf(':') > 0) Headers.Add(aLine.Split(':')[0], aLine.Split(':')[1]);
Content = new string(Encoding.UTF8.GetChars(Utility.ExtractRangeFromArray(tcpContent, delimiterLocation+4, tcpContent.Length - (delimiterLocation+4))));
Protocol = firstLine.Split(' ')[2];
if (Headers.Contains("Host")) this.Host = (Headers["Host"] as string).Trim();
}
So the code has in fact changed since I compiled it. As a quick fix while waiting for an updated version of mIP (probably has been already), I guess you could simply tuck in the calls to ExtractRangeFromArray.
The attached program blinks an external LED and the onboard LED, but now I would like to incorporate mIP.
While I am waiting for my ENC28J60 module, I thought I would hookup a Saleae Logic to the SPI port.
However, I am having a bit of trouble knowing what to modify in Networking.cs of mIP.
The attached ZIP has two files, CPU.cs and HardwareProvider.cs (from the Porting Kit on my machine:
C:\MicroFrameworkPK_v4_2\DeviceCode\Targets\Native\STM32\ManagedCode\Hardware\CPU.cs).
Hardware Provider shows this for SPI:
override public void GetSpiPins( SPI.SPI_module spi_mod, out Cpu.Pin msk, out Cpu.Pin miso, out Cpu.Pin mosi )
{
switch (spi_mod)
{
case SPI.SPI_module.SPI1:
msk = Pins.GPIO_PIN_A_5;
miso = Pins.GPIO_PIN_A_6;
mosi = Pins.GPIO_PIN_A_7;
break;
and CPU.cs shows
/// <summary>
/// GPIO port A bit 5
/// </summary>
public const Cpu.Pin GPIO_PIN_A_5 = (Cpu.Pin)5;
/// <summary>
/// GPIO port A bit 6
/// </summary>
public const Cpu.Pin GPIO_PIN_A_6 = (Cpu.Pin)6;
/// <summary>
/// GPIO port A bit 7
/// </summary>
public const Cpu.Pin GPIO_PIN_A_7 = (Cpu.Pin)7;
I think I need to modify start and InterfaceProfile in Networking.cs and also, I can't find where chipSelectPin is set. Any hints would be appreciated.
Baxter
P.S. Thank you for providing this wonderful functionality.
I'm not sure at all about this, but according to the GHI pinmapping chart (see below) for their Cerberus board (same uC), it seems you should use PB3 - PB5 for SCK, MISO, MOSI and the CS pin is available on PC15.
675px-FEZCerberusSocketPinLayout.png293.95KB8 downloads
I'm not sure how this correlates to pin names in the SM32F4 context but maybe it could help you.
it seems you should use PB3 - PB5 for SCK, MISO, MOSI and the CS pin is available on PC15.
Just FYI...each pin on STM32F4 has a half dozen or more different possible features. Each board can map a SPI channel to one of several different pre-defined locations.
On Netduino Plus, that's pins D11-D13.
The best bet with custom boards is to look at the source code for the BSP to determine which pins are assigned for SPI. One can also search them out via a logic analyzer, but that's not so much fun.
Just FYI...each pin on STM32F4 has a half dozen or more different possible features. Each board can map a SPI channel to one of several different pre-defined locations.
Yes, I can imagine there are lots of different possible pin mappings but it could be worth looking at.
Anyway, I found this link about running .NETMF on the Discovery board and there's a little section dedicated to the ENC28J6: http://wiki.tinyclr....re_On_Discovery
You need to connect the SPI pins (e.g. miso, mosi, clk, !cs), !int and of course vdd and gnd. I beleive the !reset pin to be optional.
I used this board from Sure Electronics:
Even though your board probably looks different, it should have those same pins.
Oh, about the profile, you can either change one of the existing ones or add your own, its only a matter of reflecting which Netduino pins you are actually using.
I don't have the code at hand right now but the last two arguments of the Start method are likely the chip select and interrupt pins respectively.
The numbers are just the numerical representations of the corresponing pin constants/enums and so, in your case, you should be able to simply replace those with D10 and D8.
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
A first chance exception of type 'System.ArgumentException' occurred in Microsoft.SPOT.Hardware.dll
An unhandled exception of type 'System.ArgumentException' occurred in Microsoft.SPOT.Hardware.dll
This occurs when using the dnslookup example with my new profile for netduino1 as per the above.
The error occurs on line:
irq = new InterruptPort(irqPin, true, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeLevelLow);
From:
/// <summary>
/// Creates a new ENC28J60 driver object instance, the chip will be held
/// in reset until the Start method is called
/// </summary>
/// <param name="irqPin">Host pin to use for interrupt request</param>
/// <param name="csPin">Host pin to use for SPI chip select</param>
/// <param name="spiModule">Host SPI module to use</param>
public ENC28J60Driver(Cpu.Pin irqPin, Cpu.Pin csPin, SPI.SPI_module spiModule)
{
irq = new InterruptPort(irqPin, true, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeLevelLow);
irq.OnInterrupt += new NativeEventHandler(irq_OnInterrupt);
// http://www.mikroe.com/forum/viewtopic.php?f=91&p=192252
var cfg = new SPI.Configuration(csPin, false, 0, 0, false, true, 8000, spiModule);
spi = new MultiSPI(cfg);
}
Not sure what is wrong with Microsoft.SPOT.Hardware?
My netduino is running 4.2 and I am targeting the 4.2 framework?
Are you sure you want InterruptMode.InterruptEdgeLevelLow (i.e. repeat the interrupt repeatedly as long as the level remains low), and not InterruptMode.InterruptEdgeLow (i.e. interrupt when level goes low)?
I don't believe that LevelLow is supported by the STM32 CSP, although it's something we could add via software in an update to 4.3.1 if community members need it. EdgeBoth and EdgeLow are the typical use cases.
Oh wait, are you using this on Netduino Plus 1? There are no internal pull-down resistors in Netduino Plus 1's SAM7X micro...so that part of the configuration won't work...
Andy, just skip internal pulldown (change the parameter) and put an external resistor instead of some 10k - 100k from the IRQ pin to ground. Could even be, there's already one fitted on your ENC28J60 board.
Also, double check to make sure the IRQ and CS pins are not swapped, parameter-wise that is.
Ok, that seemed to get me a little further but now I get the following exception in the Start() method:
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
A first chance exception of type 'System.Exception' occurred in NetworkingService.dll
An unhandled exception of type 'System.Exception' occurred in NetworkingService.dll
Additional information: Unable to Communicate to the Ethernet Controller. Check the InterfaceProfile in your Adapter.Start()
Which breaks on line:
if (loopMax <= 0) throw new Exception("Unable to Communicate to the Ethernet Controller. Check the InterfaceProfile in your Adapter.Start()");
From the code:
/// <summary>
/// Starts up the driver and establishes a link
/// </summary>
public void Start()
{
byte i;
var loopMax = 100; // about 10 seconds with a 100 ms sleep
// Wait for CLKRDY to become set.
// Bit 3 in ESTAT is an unimplemented bit. If it reads out as '1' that
// means the part is in RESET or there is something wrong with the SPI
// connection. This loop makes sure that we can communicate with the
// ENC28J60 before proceeding.
// 2.2 -- After a Power-on Reset, or the ENC28J60 is removed from Power-Down mode, the
// CLKRDY bit must be polled before transmitting packets
do
{
i = ReadCommonReg(ESTAT);
loopMax--;
Thread.Sleep(100);
} while(((i & 0x08) != 0 || (~i & ESTAT_CLKRDY) != 0) && loopMax > 0);
if (Adapter.VerboseDebugging) Debug.WriteLine("ESTAT: " + ReadCommonReg(ESTAT).ToString());
if (loopMax <= 0) throw new Exception("Unable to Communicate to the Ethernet Controller. Check the InterfaceProfile in your Adapter.Start()");
regCheckTimer = new Timer(new TimerCallback(CheckRegisters), null, checkDelay, checkDelay);
watchdog = new Timer(new TimerCallback(WatchDogCheck), null, 10000, 3000);
Restart();
//Init();
}