ATMEGA 644 won´t work with WIZNET5100 WIZ812MJ

Well, maybe not WAY out of spec, but certainly somewhat out of spec:

Way out of spec with respect to the current that the 3.3V pin on duemilanove is supposed to be able to provide (50mA) compared with the current that the Wiznet Module is supposed to use (130mA+)

The WIZ812MJ did work with the Atmega 328P in the duemilanove borad on the 3.3V . But I see, I had more luck than brain, that my devices don´t die.

I have to confess that the power LED on the WIZ812MJ died while the tests.
This configuration with the duemilanove borad is my testing area. In the end I put the Atmega 644 and the WIZ812MJ device on a other board with a extra powerregulation (LM 317) for the WIZ812MJ.

But thanks for washing my head. I hope my duemilanove borad isn´t to angry about it :wink:

Sig644:
@ WanaGo

I have the option to use the 644P instead of the 644, or better said I ordered it already for testing. I used the Sanguino bootloader first so I can change back (I have the Atmel AVRISP MK2 to burn the bootloader).
Would it be possible for you to post your modifed files for the 644P or to send it by email ?

Hey sorry for the delay in reply.
I didnt create any modified files - I only tested it using the standard SPI library. As mentioned above, I have only done enough work with the software to prove that it works and can be used in the hardware design. I havent gone into detail of making software that I will actually use as a final product yet.

I too used the Wiznet with the Duemilanove 3.3V and it worked ok. No doubt out of spec like mentioned but it did work for the few minutes I needed it for. The 130mA or whatnot stated in the spec may be the case at full speed, but since the Arduino cant transmit over Ethernet at the full speed, maybe it doesnt end up using the full power requirement? Just guessing and I am probably totally wrong, but does sort of make sense to me that if the Wiznet isnt having to switch its output flat out then maybe it wont use the full power as per the spec. Either way, it worked for a few minutes for me.

Hopefully you can get yours working on the 644(P) etc.

Regards
WanaGo

Did you have any luck with this in the end?

I have just received the prototype boards back from the printer and have populated them, and am now just attempting to get some test code working for the Wiznet module.

I dont have the exact computer setup I had when I did my first test, so I have started again with IDE 22.
I have downloaded the arduino-extras zip file that Mark S produced on his website (www.avr-developers.com) as that has the core files for the 644P.
I compared them against the Sanguino files and there are decrepencies. I couldnt even get the Sanguino core files to compile the Ethernet library.

I then looked in the pins_arduino.h (and .c) files, and found there was no reference to the MISO, MOSI, CSK, SS for the 644P configuration, as it looks like the SPI library uses these variable declarations.

here are some examples:

In the SPI library, it has the following code:

void SPIClass::begin() {
  // Set direction register for SCK and MOSI pin.
  // MISO pin automatically overrides to INPUT.
  // When the SS pin is set as OUTPUT, it can be used as
  // a general purpose output port (it doesn't influence
  // SPI operations).
 
  pinMode(SCK, OUTPUT);
  pinMode(MOSI, OUTPUT);
  pinMode(SS, OUTPUT);
  
  digitalWrite(SCK, LOW);
  digitalWrite(MOSI, LOW);
  digitalWrite(SS, HIGH);

It refers to the SCK, MOSI and SS variables.
I then looked in the pins_arduino files in the modified core files from Mark S, and found this entry in the pins_arduino.h file:

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
const static uint8_t SS   = 53;
const static uint8_t MOSI = 51;
const static uint8_t MISO = 50;
const static uint8_t SCK  = 52;
#else
const static uint8_t SS   = 10;
const static uint8_t MOSI = 11;
const static uint8_t MISO = 12;
const static uint8_t SCK  = 13;
#endif

It didn't have any listing for the 644P.
I added in this part, however still no joy:

#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__)
const static uint8_t SS   = 30;
const static uint8_t MOSI = 5;
const static uint8_t MISO = 6;
const static uint8_t SCK  = 7;

SS = 30 above is how I have the Ethernet Board wired in my setup. Very crude way to do it, as all SPI devices would therefore use this, however I dont see the SPI library as being very accomidating for this anyway, as the SS is hardcoded inside the library. I am not experienced enough to know the best method to make the SPI library suitable for using multiple SPI devices at once.
Either way, I have hard coded my SS to be 30 at the moment, so I am guessing that the SPI library will therefore use this value of 30.

But as mentioned, still no joy yet.

I really cannot recall how I got it working when I did my first testing, and am now actually starting to doubt if I did infact carry out this testing on the 644P...
My memory is quite poor.

If anyone has any input I would love to hear.
I have already emailed Mark to see if he can assist.

Thanks

I have had a bit more of a look, trying to understand how this works.

In the Ethernet Library, there is the W5100 files that refer to the SPI.h file. So I am assuming this is the link that joins the Ethernet library to the SPI library.

Inside this file, near the bottom are the following lines, and I think these may be related to the problem, if not the cause (additional to the already mentioned).

private:
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  inline static void initSS()    { DDRB  |=  _BV(4); };
  inline static void setSS()     { PORTB &= ~_BV(4); };
  inline static void resetSS()   { PORTB |=  _BV(4); };
#else
  inline static void initSS()    { DDRB  |=  _BV(2); };
  inline static void setSS()     { PORTB &= ~_BV(2); };
  inline static void resetSS()   { PORTB |=  _BV(2); };
#endif

I am not yet sure what to put here for the 644 and 644P, however I will give it some thought. I think its currently trying to do something incorrect with the SS bit, so a new number needs to be inserted instead of 2 or 4 above in a new #elif statement. I am not sure what that is at this point though, not code that I have had to try and interpret before.

Actually, I think the value in your case should be 16.
In my case, because I am not using a standard SS pin (using Digital 30, or PA1), mine should be 2 - but of PortA.
16 in Binary when mapped to Port B, is PB4 which is the SS pin.
2 in Binary when mapped to Port A, is PA1 which is my custom SS pin.

INCORRECT ABOVE SO EDITED:

Digital 30 for me is PA1, which is _BV(1), not 2 as mentioned above.
PB4 for you, which is _BV(4), not 16 as mentioned above.

I will test this once I have given my son his bath etc - :slight_smile: Hopefully this is all that is required.

So you maybe need to do this:

EDITED BELOW TOO

private:
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  inline static void initSS()    { DDRB  |=  _BV(4); };
  inline static void setSS()     { PORTB &= ~_BV(4); };
  inline static void resetSS()   { PORTB |=  _BV(4); };
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__)
  inline static void initSS()    { DDRB  |=  _BV(4); };
  inline static void setSS()     { PORTB &= ~_BV(4); };
  inline static void resetSS()   { PORTB |=  _BV(4); };
#else
  inline static void initSS()    { DDRB  |=  _BV(2); };
  inline static void setSS()     { PORTB &= ~_BV(2); };
  inline static void resetSS()   { PORTB |=  _BV(2); };
#endif

and I need to try this:

private:
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  inline static void initSS()    { DDRB  |=  _BV(4); };
  inline static void setSS()     { PORTB &= ~_BV(4); };
  inline static void resetSS()   { PORTB |=  _BV(4); };
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__)
  inline static void initSS()    { DDRA  |=  _BV(1); };
  inline static void setSS()     { PORTA &= ~_BV(1); };
  inline static void resetSS()   { PORTA |=  _BV(1); };
#else
  inline static void initSS()    { DDRB  |=  _BV(2); };
  inline static void setSS()     { PORTB &= ~_BV(2); };
  inline static void resetSS()   { PORTB |=  _BV(2); };
#endif

Time will tell

Cheers
James

Ok no that didnt work.

I think the value in your case should be 16.

The _BV(n) syntax converts a "bit number" to a binary value, and since the AVR is an 8 bit architecture, it won't ever be more than 7 for accessing bits in an IO port. The actual definition is:#define _BV(n) (1<<(n))

So for PB4 (which is a bit number as well), you should try:inline static void initSS()    { DDRB  |=  _BV(PB4); };
and for PA1 you can use inline static void initSS()    { DDRA  |=  _BV(PA1); };

Thanks Westfw,
I will try that, but I am not that hopeful to be honest.

It does make sense what you said, however I think the value for mine will still end up as 2, correct? PA1 is the 2nd bit in the port. EDITED - Should be 1
And that didnt seem to work (for 2 above).

It is strange how this library doesnt actually use the defined SS pin mapping that is found in the pins_arduino file, it does it all over again here with those direct methods. The SPI library utilises the pins_arduino mapping, and this library uses the SPI library but doesnt utilise them. I really dont know what I am talking about though, this is all quite new to me, I am amazed I have gotten this far.

Is anyone please able to assist in getting this to work? Its not just the 644 and 644P that are suffering, it will be all 'non arduino' processors that havent had the code tailored to suit. If we can figure out what is required, then it will no doubt help a number of people.

Thanks

It is strange how this library doesnt actually use the defined SS pin mapping that is found in the pins_arduino file, it does it all over again here with those direct methods.

The definition of "SS" in pins_arduino.h didn't happen until version 0019, which is probably well after the library was written.

This is true.

I will do some more testing in about an hour.

Thanks

D:\Arduino\arduino-0022\libraries\Ethernet\utility/w5100.h:316: error: 'PA1' was not declared in this scope

Gaa - just spotted an error I made above.

PA1 is the 2nd bit, therefore is 1, not 2. Starts at 0. My bad.

Spotted that when looking at the pins_arduino code that Mark wrote.

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] =
{
	_BV(0), /* 0, port B */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6),
	_BV(7),
	_BV(0), /* 8, port D */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6),
	_BV(7),
	_BV(0), /* 16, port C */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6),
	_BV(7),
	_BV(7), /* 24, port A */
	_BV(6),
	_BV(5),
	_BV(4),
	_BV(3),
	_BV(2),
	_BV(1),
	_BV(0)
};

I will try this tonight.
Edited posts above and used strike through so old text can still be read so they still flow.

Gaa didnt work... but I think I still have the BV value wrong.

Looked down the file a bit and saw I had it wrong.

	....
	NOT_ON_TIMER,   /* 24 - PA0 */
	NOT_ON_TIMER,   /* 25 - PA1 */
	NOT_ON_TIMER,   /* 26 - PA2 */
	NOT_ON_TIMER,   /* 27 - PA3 */
	NOT_ON_TIMER,   /* 28 - PA4 */
	NOT_ON_TIMER,   /* 29 - PA5 */
	NOT_ON_TIMER,   /* 30 - PA6 */
	NOT_ON_TIMER   /* 31 - PA7 */

So PA1 is therefore _BV(6)...

But sadly it didnt work.... =(

Still stuck on this if anyone has any desire to assist...

Thanks

So PA1 is therefore _BV(6)...

How are you getting THAT?

Px1 should always be _BV(1); the file you were quoting has info on mapping the Arduino "pin numbers" to ports and bits, which is entirely different... The general process for "direct port IO" is:

  1. figure out which arduino/whatever "pin" you want to use.
  2. Look at pins_arduino.* to figure out which "port" and "bit" (or "mask") you need to use.
  3. if necessary, convert the "bit number" to a "mask" by using _BV()

Your "not on timer" array that says (in the comment) that pin 30 is PA6 does not match the digital_pin_to_bit_mask that says (in CODE) that pin 30 is PA1. When in doubt, trust the code.

Hi Westfw,

You are right, what I posted was confusing.

I am basing all this stuff on the pins_arduino file from Mark S's core files. the pins_arduino file references a pins_duino644.cxx extension file specific for the 644(P).

Basically those arrays are what I am getting the BV value from. Not the content so much, but I assume the order of the 3 arrays are sequentially the same as each other.

When I look at all three of them:

const uint8_t PROGMEM digital_pin_to_port_PGM[] =
{
	PB, /* 0 */
	PB,
	PB,
	PB,
	PB,
	PB,
	PB,
	PB,
	PD, /* 8 */
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PC, /* 16 */
	PC,
	PC,
	PC,
	PC,
	PC,
   	PC,
	PC,
	PA, /* 24 */
	PA,
	PA,
	PA,
	PA,
	PA,
	PA,
	PA  /* 31 */
};

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] =
{
	_BV(0), /* 0, port B */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6),
	_BV(7),
	_BV(0), /* 8, port D */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6),
	_BV(7),
	_BV(0), /* 16, port C */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6),
	_BV(7),
	_BV(7), /* 24, port A */
	_BV(6),
	_BV(5),
	_BV(4),
	_BV(3),
	_BV(2),
	_BV(1),
	_BV(0)
};

const uint8_t PROGMEM digital_pin_to_timer_PGM[] =
{
	NOT_ON_TIMER, 	/* 0  - PB0 */
	NOT_ON_TIMER, 	/* 1  - PB1 */
	NOT_ON_TIMER, 	/* 2  - PB2 */
	TIMER0A,     	/* 3  - PB3 */
	TIMER0B, 		/* 4  - PB4 */
	NOT_ON_TIMER, 	/* 5  - PB5 */
	NOT_ON_TIMER, 	/* 6  - PB6 */
	NOT_ON_TIMER,	/* 7  - PB7 */
	NOT_ON_TIMER, 	/* 8  - PD0 */
	NOT_ON_TIMER, 	/* 9  - PD1 */
	NOT_ON_TIMER, 	/* 10 - PD2 */
	NOT_ON_TIMER, 	/* 11 - PD3 */
	TIMER1B,     	/* 12 - PD4 */
	TIMER1A,     	/* 13 - PD5 */
	TIMER2B,     	/* 14 - PD6 */
	TIMER2A,     	/* 15 - PD7 */
	NOT_ON_TIMER, 	/* 16 - PC0 */
	NOT_ON_TIMER,   /* 17 - PC1 */
	NOT_ON_TIMER,   /* 18 - PC2 */
	NOT_ON_TIMER,   /* 19 - PC3 */
	NOT_ON_TIMER,   /* 20 - PC4 */
	NOT_ON_TIMER,   /* 21 - PC5 */
	NOT_ON_TIMER,   /* 22 - PC6 */
	NOT_ON_TIMER,   /* 23 - PC7 */
	NOT_ON_TIMER,   /* 24 - PA0 */
	NOT_ON_TIMER,   /* 25 - PA1 */
	NOT_ON_TIMER,   /* 26 - PA2 */
	NOT_ON_TIMER,   /* 27 - PA3 */
	NOT_ON_TIMER,   /* 28 - PA4 */
	NOT_ON_TIMER,   /* 29 - PA5 */
	NOT_ON_TIMER,   /* 30 - PA6 */
	NOT_ON_TIMER   /* 31 - PA7 */
}

The bottom array set has coments, suggesting PA1 is the 25th (well actually 26th as its starting from 0, but has 25 next to it) item in that list. Looking above in the 2nd array, the 25th item is _BV(6).

That is what I based it on.

Is that a stupid assumption?
I dont understand what the arrays actually do, and how the first array especially works. Anyway, that is detail I most likely dont need to know at this stage.

I have a feeling the issue I am having is with the Ethernet library, rather than the core files, as Mark S has had SPI devices running fine on the 644P.
It is however in the Ethernet library that I utilise the _BV(6), in the w5100.h file.

private:
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  inline static void initSS()    { DDRB  |=  _BV(4); };
  inline static void setSS()     { PORTB &= ~_BV(4); };
  inline static void resetSS()   { PORTB |=  _BV(4); };
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) 
  inline static void initSS()    { DDRA  |=  _BV(6); };
  inline static void setSS()     { PORTA &= ~_BV(6); };
  inline static void resetSS()   { PORTA |=  _BV(6); };
#else
  inline static void initSS()    { DDRB  |=  _BV(2); };
  inline static void setSS()     { PORTB &= ~_BV(2); };
  inline static void resetSS()   { PORTB |=  _BV(2); };
#endif

Any suggestions.
I am not experienced enough to really know what I am doing. Well, I am making guesses, which I dont think is the appropriate way to really resolve this.

Thanks

Before anyone flames me, I know this is an old topic, but wanted to report a working solution for the Atmega644, although it is in conjunction with the Wiznet 5200 ethernet module, not the 5100 the OP was discussing. However, since this affects the SPI bus, that is unlikely to matter.

I'm working on a project using an atmega1284, and am prototyping on a breadboard using a atmega644s as I only have the one 1284 at present. Ethernet was working with the 1284, but wouldn't work with the 644 - verified by swapping MCUs. A couple hours of searching for 1284 vs 644 specific code, I came across this reference in the w5200.h file included in the Ethernet52 library I'm using.

#elif defined(__AVR_ATmega1284P__)
  inline static void initSS()    { DDRB  |=  _BV(4); };
  inline static void setSS()     { cli(); PORTB &= ~_BV(4); };
  inline static void resetSS()   { PORTB |=  _BV(4); sei(); };

This explained why the 1284 works, but the 644 wouldn't with the same code and arduino core.

Changing the conditional compile statement to include the 644 and 644P includes fixed the problem on the spot.

#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)

Hope this helps someone else too :slight_smile:
Peter