1284p Enlightenment

This is a major update of a post I wrote a year ago.

In a previous post I wrote about the article in which Manicbug talks of the 1284p and Optiboot. It’s been a long learning curve since then, blowing bootloaders into the 1284p chip and then attempting to blow programs (sketches) only to find the programming process unreliable. Various solutions abound – and I’d previously adopted the one involving a series resistor and cap into RX0 in order to round off serial signals going into the chip (for programming) because of some mysterious bug.

Well, enlightenment took some time but here it is. The cap and resistor are not at all necessary. The issues lies in a problem with some – perhaps all 1284 chips – the TX input is right next to the crystal and it is possible for high speed serial data to cause “noise” affecting the crystal – and hence bring the whole programming experience to a grinding halt – somewhat intermittently – some get it – some don’t – some just get it part of the time.

The ANSWER lies in the FUSES. The Optiboot setup – which is in the BOARDS.TXT file – but not your MAIN boards.txt file – but the one as described in the Manicbug article i.e. in your “my documents/arduino/hardware/boards.txt” file. It’s a simple text file readable with Notepad++ etc. – in there you’ll find a line that refers to “.low_fuses” – do a search… and you’ll likely find the fuse set to 0xff.

That was how my file was configured. You see the process of adding a bootloader via the IDE ALSO sets the fuses for the chip – i.e. crystal frequency etc.  The “FF” sets the oscillator into a low power mode – and that’s fine – we all like to save power – but it makes for a VERY WEAK oscillator signal. Changing that value to 0xF7 and then saving the file, powering up your IDE and blowing a new bootloader will make all the problem simply fade away.

Another simple way to do it is if you have something like the Dragon if you happen to have one – simply read the fuses – change the low fuse value from FF to F7 and program… Bob’s your uncle.  But don’t do as I did, waste several hours wondering why your Dragon processor won’t talk to the chip…. if the chip is already set to use an external crystal – and you’ve put a DIP socket on your Dragon – where’s it going to get it’s oscillator from!!! Took me ages to twig to that – simply stick a crystal in the socket with the chip!

So now, I have a bunch of 1284p chips which need no special attention to program beautifully.

Why would I bother with these chips? Well, they’re the largest that Atmel do in the range that are still DIP – i.e. easy to use for hobby/casual use. Not only do they have 128k of FLASH which is 4* that of the venerable 328, but FAR more importantly – they have 16K of RAM – and when you’re looking at large programs, SD memory, Ethernet etc., RAM is always the issue. No more with these chips so it’s worth the effort to learn how to use them properly.

However, support for these is still patchy and even the latest 1.57 BETA release of Arduino has not made matters any better. Firstly AT LEAST the Ethernet library still doesn’t support the chip… well it didn’t until now… implement this fix:

In your arduino/ethernet/utility/w5100.h file you will see this..

#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_ATmega32U4__)
inline static void initSS()    { DDRB  |=  _BV(6); };
inline static void setSS()     { PORTB &= ~_BV(6); };
inline static void resetSS()   { PORTB |=  _BV(6); };
#elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__)
inline static void initSS()    { DDRB  |=  _BV(0); };
inline static void setSS()     { PORTB &= ~_BV(0); };
inline static void resetSS()   { PORTB |=  _BV(0); };
inline static void initSS()    { DDRB  |=  _BV(2); };
inline static void setSS()     { PORTB &= ~_BV(2); };
inline static void resetSS()   { PORTB |=  _BV(2); };

See that first line I’ve put in BOLD – esssentially it is saying that if you have a MEGA board – ie one using the 2560 chip – B4 is your SS line otherwise for default Arduinos it’s B2. NOPE it’s not… Change that conditional in bold to this…

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284P__)  || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega644P__)  || defined(__AVR_ATmega644__)

Similarly in the otherwise excellent RADIOHEAD library – the interrupts assume the two interrupts of the 328 – or the many interrupts of the 2560. The 1284 has 3 and they’re not on the same pins as the 328 as you’ll see if you study Manigbug’s line – but fear not – by the time you read this they’ve probably incorporated the fix into their radiohead.h file – if not – here’s my latest fix.

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
// Arduino Mega, Mega ADK, Mega Pro
// 2->0, 3->1, 21->2, 20->3, 19->4, 18->5
#define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : ((p) >= 18 && (p) <= 21 ? 23 – (p) : NOT_AN_INTERRUPT)))

#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
// Arduino 1284 and 1284P – See Manicbug and Optiboot
// 10->0, 11->1, 2->2
#define digitalPinToInterrupt(p) ((p) == 10 ? 0 : ((p) == 11 ? 1 : ((p) == 2 ? 2 : NOT_AN_INTERRUPT)))

The bit in bold is the bit I added and have recommended. This says that on the 1284, the interrupts Digital pins (not physical pins) are 10,11 and 2 for interrupts 0,1 and 2 respectively. In the case for example of using the Si4332 chip which is compatible with the RF22 section, interrupts are used to track incoming data (I only WISH they’d do that with the NRF24L01 chips).  I’ve tested all 3 options with my fix above – works a treat.

Also in the 1.05 Arduino environment, I found that storing the Mighty 1284 board info in the hardware directory of my sketches folder was enough to ensure the chip turned up in the list of chips in the IDE. Not so in the 1.57 release which could not find the chip. I found that by making a folder until that custom hardware folder called AVR and moving the stuff into there – it all worked until it came to compile time and it complained about a missing setup. Turns out a file called platform.txt is needed which I copied straight out of the new arduino/hardware/arduino/avr folder fixes that one – I’m now up and running, compiling for the 1284 on the new beta environment.  Until on the of the new libraries fails due to me forgetting to make changes.

There will be other libraries that need fixing – if you happen to come across any needed fixes – please do let me know.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s