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..

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_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); };
#else
inline static void initSS()    { DDRB  |=  _BV(2); };
inline static void setSS()     { PORTB &= ~_BV(2); };
inline static void resetSS()   { PORTB |=  _BV(2); };
#endif

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.

1284P and SD Cards

Just what is it with the Arduino people – they seem to have it in for the 1284p – one of the best chips out there. WHY is it a good chip? Well, it runs all Arduino projects – but you get 128K of FLASH and 16K of RAM – is that a good enough reason? AND they do a DIP version so it’s a doddle to do prototyping with it – and its’ cheap – and has lots of pins etc.

BUT – some of the libraries pretend the chip doesn’t exist.. SD is one of them –  I just updated the SD library and I happened to try a little test program to put something in SD on the normal Ethernet card… Nothing… I made sure I specified the select line (I chose output 27 – the Ethernet select line is output 4 on these chips normally)…. nothing.. then I remembered I’d updated the library – went on a search and found THIS. See code below – but I suggest ALSO adding for the 1284 – so see latter of the two updates.. this might apply to other libraries if you have any hassle…

Go into this file: C:\Program Files (x86)\arduino-1.0.1\libraries\SD\utility\Sd2PinMap.h
Change this line: #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
to: #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284P__)

Go into this file: C:\Program Files (x86)\arduino-1.0.1\libraries\SD\utility\Sd2PinMap.h
Change this line: #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
to: #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284__)

Home Control Update

1284p main board with LCD panel up front

Just a quick update on the home control… the slaves are about as good as they can get – I’ve added memory for the state of the 3 PWM outputs and ALLOFF and ALLON commands so that one can set the brilliance of, say a 3-colour LED strip – and then turn the lights on and off accordingly. At some point I’ll put a global fader on all 3 colours….

I’ve switched my attention now to the master board. I was using a MEGA, having long since given up on the 328 due to constantly running out of memory. I had a few 1284p chips lying around – in case you don’t know these are the largest Arduino-type chips you can get in DIP format – 40 pins – and they have one great feature – 16K of RAM which means you can forget about penny-pinching RAM.  Accordingly – I’ve added SD logging – and just now for the sake of it, an LCD display. I’m using the new LCD library that lets you use an LCD module with a 74HC595 shift register on the back (on veroboard) to reduce the pins needed to talk to the processor down to 2 (clock and data). 

As you can see above, the LCD is echoing the Ethernet commands as they come in (and quickly too) and over on the left is the micro-SD card plugged into the Ethernet card…. which is also supplying the 3v3 to the radio board. All in all very few components – took me an hour or so to put this lot together and twice as long to remember how to use the various libraries.

All working well, not sure if there’s a REAL use for the LCD – I also have a 4-line version of that… overall current for the board is around 300ma – or 1.3 watts – that won’t break the bank running all the time and it should run off a standard USB plug-in-the-wall.

The next challenge is a box.  I have to say, it’s all working very well – once again for pinouts etc I keep referring back to ManicBug’s various articles.

The Mighty 1284p

The 1284p is the next step up from the ATMega328 chip powering many of the “Arduino” type microcontroller boards and their many clones.

Why another chip? Well, anyone who has used the ATMega328 knows that it’s a great controller chip but the lack of RAM soon gets very tiring. Also if you’re messing with things like Ethernet and maybe you want a Real Time Clock, perhaps access toSD memory, the libraries have a habit of filling your FLASH memory much faster than you’d like.

1284p chipWhy the 1284p? That’s simple – there are only so many of these chips in DIP format – that is the old 0.1” pin format that is easy to use for prototyping – the other upgraded chips are surface mount and a PAIN to solder.

The 328 chip has 32Kbytes of FLASH (for your programs), 1K of EPROM (for storing data permanently) and 2K of RAM (for variables). The likes of the Ethernet code EATS up the RAM in no time. Finally, it’s also quite easy to run out of Interrupts and port bits.

Don’t get me wrong, the 328 is a great general purpose chip but it has it’s limits. A  problem with many other chips is the cost – by the time you’ve finished you may as well have bought a Raspberry Pi and the idea surely is to keep costs low.

Well, the 328 can be as cheap as a couple of pounds or so… and the 1284p can be had for double that. What do you get for your money?

  • 128K Flash (ie 4 times as much)
  • 16K RAM (ie 8 times as much – MOST welcome)
  • 4K EEPROM(4 times as much)
  • 32 pins as against 23
  • 3 interrupts as against 2
  • 8 analog ports as against 6
  • 2 UARTS as against 1

As you can see in the diagram above, putting together a prototype board is a snap (provided you have a TTL-USB converter which I use for all my kits.)

Here is the information you need. If you’re starting from scratch you need the Arduino IDE, the TTL to USB converter (for programming) and a few bits and pieces for your prototype – information for that is all here.

tmp4AFFFollow instructions and you get this on your IDE bottom right when you’ve set the right board..

The standard BLINK test which flashes a LED once a second, when modified to use output 16 – will flash physical pin 22 on and off as per my photo demo above.

Thanks here to Aidan Ruff for pointing me in the right direction and supplying the test chip – which will soon end up in some long-abandoned project (because I ran out of room in the ‘328). Magic.