Tag Archives: arduino

Updated MRF24J40 arduino driver

Thanks to pkarck my changes to improve the C library for Microchip’s MRF24J40 802.15.4 modules has been ported to the Arduino library. I’d written an Arduino library some time ago, but hadn’t been maintaining it as I don’t really deal with Arduino much these days. However, it’s gotten some love :) It’s now easier to use, and has support for the power amplifier on the MRF24J40MB modules, if you’re using those. It also makes some quirks I was dealing with in a mixed xbee/mrf24j40 module environment optional. In general, this collects up some of the various reported issues over the last year or so, and I didn’t have to do anything at all!

This is, “teh awesome”.


Everything that is wrong with Arduino

Everything that is wrong with Arduino can be summed up with this enhancement request: Way to specify number of digits / places when printing hex, octal, and binary numbers.

PetitFatFs SD card bootloader for ATmega2560 / Arduino Mega 2560

ChaN’s PetitFatFs, is a pretty neat plain C library dealing with Fat file systems (like on SD cards) with as little code as possible. It even includes sample bootloader code for AVR, which tries to open a file on an SD card, and if it exists, write it to flash, before booting the user application.

It’s a pretty neat base, though you may/probably will want to add a little bit functionality. The directions that come with the code are pretty good for getting this working. [1] However, for boards based around the ATmega2560, or ATmega2561, which contain >128k program space, a couple of things just don’t work…

First, the code for jumping into the user code:


This is fairly commonly seen pattern, but least with GCC 4.3.3 (WinAVR 20100110) this generates incorrect code. It gets turned into an EICALL, but without setting EIND. This results in the bootloader continually resetting into itself. (And, if the file on the sd card exists, repeatedly overwriting flash as fast as possible, not really very good for your flash lifetime!)

The alternative, which correctly generates a jump to the real 0, (These big ATmega’s have a 22 bit Program Counter, not a 16 bit one) is simply:

    asm volatile("jmp 0000");

The other required piece of the puzzle, is actually an AVR-libc FAQ item. You need to add -mrelax to your linker options.

As best I can tell, both of these additions should actually “do no harm” for regular sized AVRs as well, but I don’t have any boards handy to try that out with.

By the way, if you’re using the SD card on an arduino ethernetshield, below is the the only change you need in asmfunc.S. Just to save you from working out what the real name for “digital pin 4” is C land.

#define	DDR_CS	_SFR_IO_ADDR(DDRG), 5	// MMC CS pin (DDR, PORT)

Now, if only I could convince avrdude to erase all the flash, but only program the 4-8kb of bootloader, instead of insisting that it needs to program the entire 256k of flash each time I make a tweak to the bootloader. (139 seconds to program using a FabISP)

[1] The only thing I found unclear at first was setting up the “DI” and “DO” pins. Given that I was choosing pins that were on my mega2560, I assumed these were Data Out and Data In, when seen from the point of view of the mega2560. They are not, they are from the point of view of the SD card. (This is actually shown on the schematic image that comes with the PetitFatFs sample download)

FatFs with Arduino Mega 2560 and EthernetShield micro SD card

This is based on FatFs 0.8b, the latest release at the time of writing. We wanted to use the SD card slot on the standard arduino ethernet shield, and there’s a standard arduino provided SD library for working the sd card slot. However, despite the claims in the arduino FAQ, where it says, “… the C/C++ microcontroller libraries are under the LGPL” and “Using the Arduino core and libraries for the firmware of a commercial product does not require you to release the source code for the firmware. The LGPL does, however, require you to make available object files that allow for the relinking of the firmware against updated versions of the Arduino core and libraries. Any modifications to the core and libraries must be released under the LGPL.” this is actually untrue. Even on the SD card library reference page or Notes on using SD cards no mention is made of the fact that the SD library is actually GPLv3. Because the library is based on the GPLv3 sdfatlib

This is a pretty glaring omission, and a rather rude piece of code to just slip in.

Fortunately, there is also FatFs, and it’s tiny sister, PetiteFs, which are both under a BSD style license. They’re also plain C, and a lot more portable, with the sample code working on not just AVR, but ARM, i386, h8, and on and on.

So, I thought it should be possible to get that working with our mutant arduino here. Two websites were very useful in getting me started in the right direction, (in addition to the FatFs documentation)

What did I actually have to do?

  1. Download FatFs sample, and grab diskio.h, ff.c, ff.h, ffconf.h, integer.h and mmc.c and put them in my project
  2. Replace allll instances of BYTE with BYTEF (or anything else you want) in those files. BYTE is already defined (and differently) by the Arduino codebase
  3. In diskio.h, I had to add the following c++ wrapper
    #ifdef	__cplusplus
    extern "C" {

    at the start, and close it at the end.

  4. Edited the ffconf.h to suit, (This is up to you…)
  5. in mmc.c, I added #include "WProgram.h"
  6. in mmc.c, I replaced the #defines for CS_LOW and CS_HIGH with digitalWrite(4, LOW/HIGH). For the Arduino Ethernet shield, chip select is on pin 4.
  7. in mmc.c, the three power_* functions were stubbed out. The ethernet shield doesn’t support this.
  8. in mmc.c, the disk_timerproc function had the write detect and card inserted logic removed, again, the ethernet shield doesn’t support this.
  9. in mmc.c, because I wanted write support, I had to provide a function, DWORD get_fattime(), which simply returns 1. This is the file create time, and if you don’t really care what timestamp you get, a fixed value is fine. You would normally hook this up to an RTC or something.

    That’s about it. Then, just be careful to make sure that SPI is set up properly (taken care of if you’re using the ethernet on the ethernet shield) and, very importantly, make sure to include pinMode(4, OUTPUT) to make sure that the SD cards chip select pin is actually an output. If you forget this, it will sometimes work, and sometimes fail, and be very very very unpredictable.

    Oh, And you need to set up a timer to call disk_timerproc() every 10ms. The circleofcurrent page shows how to work around this with fixed loops if you’d prefer, but I just set up Timer2 to do this. This list of arduino resources used seems to imply that Timer2 is safe for us, but your mileage may vary. Here’s how we set up Timer2

            TCCR2A = _BV(WGM21);  // CTC MODE
    	TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); // clkdiv 1024
    	TIMSK2 = _BV(OCIE2A);			/* Output compare match interrupt */
    	OCR2A  = 156;         // 156 ticks at 16Mhz/1024 = ~10ms
            // Needs to be turned on before we start trying to wake up the sd card!
            // fatfs disk init code below...

    This was all done on an Arduino Mega 2560 board.

Remember, chip select pins need to be outputs!

I was struggling with (very) unreliable file reads and writes while trying to get FatFs running on an Arduino Mega 2560 board, with the standard Arduino Ethernet Shield. The ethernet connection was continually dropping and reconnecting as well.

What was missing? I hadn’t set the pin used for chip select on the SD card to be an output. As soon as I added that, my file operations became 100% reliable, and my ethernet connection stopped bouncing. Excellent!

(I’ll try and package up what we needed to get FatFs working, but it might not be today)

avrdude 5.10, arduino mega 2560, command line uploading

Note: The following probably applies to the arduino UNO as well, as it also uses an onboard atmega 8u2, rather than the old raw serial converter.

Part 1 of probably many. I’ve inherited some arduino code, targetting the quite new mega2560 boards. You know, the ones that include an onboard atmega8u2, rather than the original old serial adapters. In many ways, this is a welcome step into the future. Anyway, this place doesn’t even have a regular AVR ISP programmer, and with the onboard real usb, the code running on the 8u2 is actually effectively an AVR ISP programmer itself, talking the stk500 protocol.

I am trying to move some of this code slowly out of the arduino IDE, and towards a more standard shared tree of c/c++. I have mostly succeeded in building plain hex files from the command line, based on arduino libraries (for things like LiquidCrystal and Ethernet and so on) but was having problems getting them to program. By editing arduino’s “preferences.txt” and adding “upload.verbose=true” I could see that when programming from the arduino IDE, it was using a private patched version of avrdude (5.4-arduino) with the programmer type of stk500v2, and that it was issuing a reset, via some sort of DTR toggle…

c:\tools\arduino-022\hardware/tools/avr/bin/avrdude -CC:\tools\arduino-022\hardware/tools/avr/etc/avrdude.conf -v -v -v -v -cstk500v2 -p atmega2560 -P COM5 -b 115200
... version stuff ...
Using Programmer: stk500v2
Overriding Baud Rate: 115200
avrdude: ser_open(): setting dtr
avrdude: Send: . [1b] [20] . [00] . [03] . [0e] . [11] . [01] . [01] ' [27]

Ok, so now I had enough to try and run it myself, using avrdude 5.10, as comes with recent versions of WinAVR

C:\Users\karlp>avrdude.exe -p atmega2560 -P COM5 -c stk500v2 -v -U lfuse:r:-:h -b 115200
avrdude.exe: stk500_2_ReceiveMessage(): timeout
avrdude.exe: stk500_2_ReceiveMessage(): timeout

But, as you can see, this just timed out. Looking at the LEDs, I could see that the board wasn’t getting magically reset. With a bit of reading and searching, I found out that avrdude added a way of resetting the board, if you use the programmer type of “arduino”

Using Programmer : arduino
Overriding Baud Rate : 115200
avrdude.exe: Send: 0 [30] [20]
avrdude.exe: Send: 0 [30] [20]
avrdude.exe: Send: 0 [30] [20]

Interesting, following the lights on the board, I could see that this was now resetting properly, but clearly, those were not the right commands. It seems that the “arduino” programmer type, is set up to talk to the bootloader on the atmega328 of the prior versions of arduino, the Duemilanove and so on, that still had a direct USB-serial bridge, from the FTDI chip. So, if the “arduino” programmer does the reset, but the wrong protocol, looks like I’ll have to reset it myself.

I finally tried holding reset on the board, issuing the command with the programmer of “stk500v2” and immediately releasing reset. Presto!

C:\Users\karlp>avrdude.exe -p atmega2560 -P COM5 -c stk500v2 -v -b 115200
... more snipped ....
Programmer Type : STK500V2
Description : Atmel STK500 Version 2.x firmware
Programmer Model: AVRISP
Hardware Version: 15
Firmware Version Master : 2.10
Vtarget : 0.0 V
SCK period : 118.3 us

avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.03s

avrdude.exe: Device signature = 0x1e9801
... more snipped ...

Hooray! we’re working from the command line again. Now, if only the arduino gang’s pile of extra patches for avrdude would keep making their way back into mainline. It seems they don’t play well with others :(

MRF24J40 with arduino (teensyduino)

Earlier, I’d been working in pure C land, but I know not everyone uses pure C, and sometimes, the arduino environment is a nice easy way to get something prototyped.

So, I turned my mrf24j40 library into an arduino library! It supports all the basic stuff for sending and receiving 802.15.4 frames in a non-beacon network. It’s been tested so far with teensyduino, but it doesn’t use any teensy specific features, so it should work just fine on any arduino style board that has SPI and three spare pins for the reset, interrupt and chip select pins.

You can get the library from github, and like any arduino library, just extract it into your arduino/libraries directory. There are examples for tx only, rx only, and two way data.

Get the MRF24J40 arduino library

The examples are about the extent of the documentation so far, but just email me with questions!