wiznet 820i on Teensy 3.1 getMACaddress()?

Status
Not open for further replies.

mortonkopf

Well-known member
Hello all, having got the CC3000 up and running, I find that data streaming is patchy and want get my Ethernet module up and running. Trying to get my wiznet 820i module going, but seem to be having difficulty with the MAC address. The module did not come with any indication of address, and I can't find a getMACaddress() or setMACaddress() for the 5200. Is there something I am missing here? I thought that I could not just assign an Address, but have no idea of how to go about.

thanks for any pointer
mortonkopf
 
I think the '5200 chip is the same as the '5100 in terms of MAC addresses. Wiznet does not assign a MAC address (they assume the OEM owns a block of OUIs).
Part of the chip initialization in the user or library code is to derive a MAC address and push it into the chip before doing any packet I/O. This would then be used for ARPs.

See this thread on using the CPU chip ID and/or the USB unique ID. Either could be used to derive the low 30 bits of the 5100/5200 MAC address for the ethernet.
http://forum.pjrc.com/threads/18605-Does-Teensy-have-a-processor-ID?highlight=SIM_UIDH post #5

I recommend that the 5100/5200 library do this (or perhaps it does something similar, using the USB controller's ID):
Derive a MAC address by taking the Freescale CPU chip's serial number (retrievable in code, 128 bits, more than needed for the ethernet MAC). Merge that with the high order bits in the MAC address that define a "locally administered MAC address", i.e., not a registered OUI, and not one cloned from some other NIC. This local MAC is OK to use on a LAN.
Per the Freescale specs, the 128 bit unique ID registers are
SIM_UIDH high 32 bits
SIM_UIDMH next 32 bits
SIM_UIDML next 32 bits
SIM_UIDL low 32 bits


A locally administered MAC has one certain high order bit set to 1 as seen in
http://en.wikipedia.org/wiki/MAC_address
So 30 bits from the unique ID are needed to go along with the highest two bits being x1... where x is 1 if the frame is multicast per the standards.
Here's an example real ID:
SIM_UIDH: FFFFFFFF highest 32 bits
SIM_UIDMH:FFFF0008
SIM_UIDML:003C6008
SIM_UIDL: 24354E45 lowest 32 bits


It could be that the high 64 bits are a constant for the chip family.

I used the locally administered coding on a project with dozens of 5100 chip based products because of the customer's desire to not go to the OUI/IEEE to register for just 100 units.

Hard-coding a MAC is not practical when there are 2+ units on the LAN.
 
Last edited:
Here's an example

#define PRINTF Serial.printf
// more code

PRINTF("CPU ID:%08X %08X %08X %08X\n", SIM_UIDH, SIM_UIDMH, SIM_UIDML, SIM_UIDL);
 
thanks for the pointer. seems reasonably straight forward now that it has been explained. I need to do some further reading, as I missed that ID forum post.
 
I started, but didn't finish, looking at the Arduino Wiznet Ethernet library source... they pull a MAC address out of "firmware ID". I don't know what that is. I read that Freescale puts a chip-unique 128 bit number in flash somewhere. It's not "burned" into the silicon as I read it.

I also noted that the Library sets the MAC address and does a DHCP when Ethernet.Begin() is called. There are 6 or so variations of calls to .begin - some pass a MAC address, some pass an IP, etc. One call to .begin has no params.
The library is used for AVRs and Teensy alike.
It doesn't use interrupts, e.g., to indicate packet-received; polling is used. Probably due to its AVR legacy.
 
Regarding the library, I am sure that I came across a setmacaddress(), possibly in the dchp file and that would tie in with polling. More reading.
 
Thanks headroom. that does look interesting, will follow that up when at home. Yet another example of so much useful info on this forum that I can't seem to use the correct search terms to find...
 
What exactly do you mean with "return message" in respect to the mac address >

Edit:I saw your other post post in another thread. The answer will be obvious when youfollow the thread that I linked to in my reply to mortonkopf. the Teesy 3.x boards have a unique factory assigned Ethernet media address burned in.
Essentially you are reading it from the Teesny and assign it as the mac Address to the WIZ820io.
 
Last edited:
sorry, i used the code in the teensy 3 mac address thread that u linked to above but i have no idea how to see/find what it prints??
the code THT posted
 
What exactly do you mean with "return message" in respect to the mac address >

Edit:I saw your other post post in another thread. The answer will be obvious when youfollow the thread that I linked to in my reply to mortonkopf. the Teesy 3.x boards have a unique factory assigned Ethernet media address burned in.
Essentially you are reading it from the Teesny and assign it as the mac Address to the WIZ820io.

Dear all,

It looks like we are working on the same problem. If somebody already solved it properly please share. That said:

I looked in the Ethernet.h library and I see that the w5100.h library is grayed out at least in my code. Would anyone know if there is any particular reason?

decommenting the ethernet.h library and using setMACAddress (teensyAddress) did not work yet (I have to understand that syntax first). Anyone any further pointers?

Best, Hans.
 
Here is some source code that should help explaining how to read the mac address of a teensy 3.x :

Code:
char mac_string[20];		 //string to hold MAC address for Bonjour name

// Everything on the network needs a unique MAC
// Each Teensy3 has a unique MAC burned in
static byte mac[6];
char mac_string[20];		 //string to hold MAC address for Bonjour name
void read(uint8_t word, uint8_t *mac, uint8_t offset) {
  FTFL_FCCOB0 = 0x41;             // Selects the READONCE command
  FTFL_FCCOB1 = word;             // read the given word of read once area

// launch command and wait until complete
  FTFL_FSTAT = FTFL_FSTAT_CCIF;
  while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF));

  *(mac+offset) =   FTFL_FCCOB5;       // collect only the top three bytes,
  *(mac+offset+1) = FTFL_FCCOB6;       // in the right orientation (big endian).
  *(mac+offset+2) = FTFL_FCCOB7;       // Skip FTFL_FCCOB4 as it's always 0.
}
void read_mac() {
  read(0xe,mac,0);
  read(0xf,mac,3);
}

void print_mac()  {
  size_t count = 0;
  for(uint8_t i = 0; i < 6; ++i) {
    if (i!=0) count += Serial.print(":");
    count += Serial.print((*(mac+i) & 0xF0) >> 4, 16);
    count += Serial.print(*(mac+i) & 0x0F, 16);
  }
  sprintf(mac_string, "%02X:%02X:%02X:%02X:%02X:%02X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
  Serial.println();
}


void setup()
{
// Add your initialization code here

 

  Serial.begin(9600); 
  Serial.println("Reading MAC from hardware...");
  read_mac();
  Serial.print("MAC: ");
  print_mac();
  Serial.println();

 // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }

// print your local IP address:
  Serial.print("Local IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(".");
  }
  Serial.println();
}

void loop()
{
.
.
.
.
}
 
Here is some source code that should help explaining how to read the mac address of a teensy 3.x :

Code:
char mac_string[20];		 //string to hold MAC address for Bonjour name

// Everything on the network needs a unique MAC
// Each Teensy3 has a unique MAC burned in
static byte mac[6];
char mac_string[20];		 //string to hold MAC address for Bonjour name
void read(uint8_t word, uint8_t *mac, uint8_t offset) {
  FTFL_FCCOB0 = 0x41;             // Selects the READONCE command
  FTFL_FCCOB1 = word;             // read the given word of read once area

// launch command and wait until complete
  FTFL_FSTAT = FTFL_FSTAT_CCIF;
  while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF));

  *(mac+offset) =   FTFL_FCCOB5;       // collect only the top three bytes,
  *(mac+offset+1) = FTFL_FCCOB6;       // in the right orientation (big endian).
  *(mac+offset+2) = FTFL_FCCOB7;       // Skip FTFL_FCCOB4 as it's always 0.
}
void read_mac() {
  read(0xe,mac,0);
  read(0xf,mac,3);
}

void print_mac()  {
  size_t count = 0;
  for(uint8_t i = 0; i < 6; ++i) {
    if (i!=0) count += Serial.print(":");
    count += Serial.print((*(mac+i) & 0xF0) >> 4, 16);
    count += Serial.print(*(mac+i) & 0x0F, 16);
  }
  sprintf(mac_string, "%02X:%02X:%02X:%02X:%02X:%02X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
  Serial.println();
}


void setup()
{
// Add your initialization code here

 

  Serial.begin(9600); 
  Serial.println("Reading MAC from hardware...");
  read_mac();
  Serial.print("MAC: ");
  print_mac();
  Serial.println();

 // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }

// print your local IP address:
  Serial.print("Local IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(".");
  }
  Serial.println();
}

void loop()
{
.
.
.
.
}

Thanks but that is not the problem. I have the MAC code of the teensy already but using that MAC code I do not get the expected result (the IP address) from DhcpAddressPrinter. I suspect that I need the MAC code of the WIZ820io itself for that to work unless people say other wise. Should I look at the teensy WIZ module as one entity with one IP-address and MAC address? As stated before. I don't see the WIZ in my network and I cannot address it from the teensy either. I think the module works though since the orange light burns permanently and the green light semi permanent (with a few flickers once in a few seconds).

Best, Hans.
 
The WIZ820io (or the older WIZ812MJ for that matter) have no burned in MAC address. Only the newest member of that product family using the W5500 chip have that. That's why the teensy 3.x mac address came in so handy. Ethernet is exactly the reason that it exists if I remember Paul's comments in previous threads correctly.

Please post what hardware you are using, how everthing is wired up (is PWDN connected to GND ?) and post your Sketch.

The sketch segment I posted works in my Sketches on my own Teensy3 WIZ820io adapter board and I have no problem to receive an IP address per DHCP, ping it, send receive UDP messages or register a Bonjour service on my network!
 
/*
DHCP-based IP printer

This sketch uses the DHCP extensions to the Ethernet library
to get an IP address via DHCP and print the address obtained.
using an Arduino Wiznet Ethernet shield.

Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13

created 12 April 2011
modified 9 Apr 2012
by Tom Igoe

*/

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
0x04, 0xE9, 0xE5, 0x00, 0x41, 0xE2 }; // This is my teensy's MAC address maybe it should be the MAC address of the WIZnet module but I con't find that...

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
// this check is only needed on the Leonardo:
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}

// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
for(;;)
;
}
// print your local IP address:
Serial.print("My IP address: ");
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");
}
Serial.println();
}

void loop() {

}

I use this standard code to get the IP address. The MAC address is the teensy address.
 
Sketch looks OK at first sight. What hardware are you using ?
Or more specific, how is the WIZ820io connected to the Teensy 3 ?
 
I tried to upload some pictures and hope I succeeded. I have it hooked up just like it is done in the tutorial on the wizwiki: http://wizwiki.net/intro-to-the-wiz820io-module-by-ben-roberts/
The only thing that I changed is that I put the reset on 3.3V (since I don't have a pin on the teensy on the reset) and I connected PWDN to GND.

IMG_0720.jpg
IMG_0721.jpg
 
You need to connect the RESET in of the WIZ820io to pin 9 on the Teensy 3.x.

It is used during the initialization of the WIZ820io. See this code out of the Ethernet library in /utility/W5100.cpp:

Code:
...

#define W5200_RESET_PIN  9
#define W5200_SS_PIN    10

...

uint8_t W5100Class::isW5200(void)
{
  uint8_t mr;
  chip = 52;
  //Serial.println("W5100 detect W5200 chip");
#ifdef W5200_RESET_PIN
  pinMode(W5200_RESET_PIN, OUTPUT);
  digitalWrite(W5200_RESET_PIN, LOW);
  delay(1);
  digitalWrite(W5200_RESET_PIN, HIGH);
  delay(150);
#endif
  reset();
  writeMR(0x08);
  mr = readMR();
  //Serial.print("mr=");
  //Serial.println(mr, HEX);
  if (mr != 0x08) return 0;
  writeMR(0x10);
  mr = readMR();
  //Serial.print("mr=");
  //Serial.println(mr, HEX);
  if (mr != 0x10) return 0;
  writeMR(0x00);
  mr = readMR();
  //Serial.print("mr=");
  //Serial.println(mr, HEX);
  if (mr != 0x00) return 0;
  //Serial.println("chip is W5200");
  return 1;
}
 
Dear Headroom,

First of all thanks for your time. I really appreciate this but I am afraid the problem is still not solved when connecting 9 and reset. I did not replace the W5100 files in the first place since I suspect the ethernet library to be updated and seeing the W5200 in the code. Do you also use the standard ethernet library as part of the Arduino IDE? I went to the WIZNET page and went to that link to the W5200 replacement of the W5100 chip. Having that library installed I got error codes. There was something else there though:

3. Note: libraries/Ethernet/Ethernet.h needs the following at line 10 instead of #define MAX_SOCK_NUM 4, since it doesn't #include "w5100.h" anymore:
Thanks "Matthew Lange"

#ifdef W5200
#define MAX_SOCK_NUM 8
#else
#define MAX_SOCK_NUM 4
#endif

Did you change that in your library?

Best, Hans.
 
The Ethernet library that comes with Teensyduino 1.18 contains a few enhancements that make it more powerful than the "standard" Ethernet library that comes with the normal Arduino IDE.
These are specifically useful for the WIZ820io:

1. It allows to use higher SPI frequency to increase the data rate
2. It uses SPI FIFO to increase the data rate
3. It contains code that auto detects which Ethernet chip is used, whether it's the W5200 used in the WIZ820io or the W5100 used in Ethernet shield or the WIZ812MJ. The #defines in your code segment are not necessary anymore since Teensyduino 1.17.

Make sure you have the newest Arduino 1.0.5 IDE installed and then download and install Teensyduino 1.18
The code segment I posted is from Teensyduino 1.18.
 
That is exactly what I did...

This seems a strange problem. I tested with another teensy (3.1) and got exactly the same result.

Tomorrow further...

Best and thanks, Hans.
 
I put the wiznet 820 on the breadboard to take a photo of a working wiring setup, and this setup does work:
wiznet820i.jpg
 
Dear Mortonkopf, I appreciate your effort but my hardware configuration is exactly the same...

I think I should run diagnostics on my ethernet port. Having tested two modules, three ethernet cables and three teensy's and an Arduino the problem is still elusive to me. I think I will test with another computer.

Best and thanks, Hans.
 
Just for clarification . The Ethernet cable from the WIZ 820io needs to be plugged into a router, not into a computer.
 
Status
Not open for further replies.
Back
Top