Oddly enough, buying an Arduino WiFi shield more than two years after the firmware was updated still gets you 1.0.0 firmware. Remembering that, even following the instructions, it was only by dumb luck that I succeeded in upgrading my first shield, I figured I would document the process a little more carefully this time.
- Check the version of the firmware built into the IDE:
grep fwVersion /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/firmwares/wifishield/wifiHD/src/main.c
which returns
const char* fwVersion = "1.1.0”;
If you don’t have the correct version, or if grep complains about “no such file or directory”, then download a newer build of the IDE.
- The Arduino documentation leads the user to install MacPorts and then use MacPorts to install the DFU. MacPorts and HomeBrew don’t play nicely together, and I prefer HomeBrew, so I went looking for another way. The DFU build process has several dependencies, most of which only show up via an iterative build process, so save some time and do these things first:
-
- Install HomeBrew
Open a terminal window and run these brew commands:
- brew install autoconf
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/autoconf-2.69.yosemite.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring autoconf-2.69.yosemite.bottle.1.tar.gz
🍺 /usr/local/Cellar/autoconf/2.69: 70 files, 3.6M
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/automake-1.14.1.yosemite.bottle.tar.gz
######################################################################## 100.0%
==> Pouring automake-1.14.1.yosemite.bottle.tar.gz
🍺 /usr/local/Cellar/automake/1.14.1: 131 files, 4.3M
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/libusb-1.0.19.yosemite.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring libusb-1.0.19.yosemite.bottle.1.tar.gz
🍺 /usr/local/Cellar/libusb/1.0.19: 11 files, 480K
-
- brew install libusb-compat
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/libusb-compat-0.1.5.yosemite.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring libusb-compat-0.1.5.yosemite.bottle.1.tar.gz
🍺 /usr/local/Cellar/libusb-compat/0.1.5: 12 files, 256K
- Download the DFU (Device Firmware Update) programmer from the source files page and follow the “unpack the sources” line below, or clone the Git repo following the “git clone…” line below. I chose git clone.
- Follow the build instructions (annotated with expected output):
Simple install procedure for Unix/Linux/MAC
===========================================
% tar -xzf dfu-programmer-<version>.tar.gz # unpack the sources
-- or --
% git clone https://github.com/dfu-programmer/dfu-programmer.git
% cd dfu-programmer # change to the top-level directory
[ If the source was checked-out from GitHub, run the following command.
You may also need to do this if your libusb is in a non-standard location,
or if the build fails to find it for some reason. This command requires
that autoconf is installed (sudo apt-get install autoconf) ]
% ./bootstrap.sh # regenerate base config files
(returns: configure.ac:14: installing 'm4/compile’)
[ Optionally you can add autocompletion using the dfu_completion file,
and possibly instructions provided after running the ./bootstrap command ]
% ./configure # regenerate configure and run it
(returns:
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
/Users/paulbeda/Documents/Arduino/dfu-programmer/m4/missing: Unknown `--is-lightweight' option
Try `/Users/paulbeda/Documents/Arduino/dfu-programmer/m4/missing --help' for more information
configure: WARNING: 'missing' script is too old or missing
checking for a thread-safe mkdir -p... m4/install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether to enable maintainer-specific portions of Makefiles... no
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
using libusb_1.0
checking for ANSI C header files... no
checking for an ANSI C-conforming const... yes
checking for size_t... yes
checking stdlib.h usability... yes
checking stdlib.h presence... no
configure: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!
configure: WARNING: stdlib.h: proceeding with the compiler's result
checking for stdlib.h... yes
checking for GNU libc compatible malloc... no
checking for working memcmp... no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating fedora/dfu-programmer.spec
config.status: creating Makefile
config.status: creating docs/Makefile
config.status: creating src/Makefile
config.status: creating src/config.h
config.status: executing depfiles commands
)
[ Optionally you can specify where dfu-programmer gets installed
using the --prefix= option to the ./configure command. See
% ./configure --help for more details. ]
[ By default the build process will use libusb-1.0 if available.
It tries to auto-discover the library, falling back to the older
libusb if libusb-1.0 is not available. This process is not entirely
reliable and may decide that libusb-1.0 is available when in fact
it is not. You can select libusb using --disable-libusb_1_0. If
usb library is not available try getting libusb-1.0-0-dev ]
% make # build dfu-programmer
(returns:
Making all in src
/Applications/Xcode.app/Contents/Developer/usr/bin/make all-am
gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -I/usr/local/include/libusb-1.0 -I/usr/include/libusb-1.0 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -I/usr/local/include/libusb-1.0 -I/usr/include/libusb-1.0 -MT arguments.o -MD -MP -MF .deps/arguments.Tpo -c -o arguments.o arguments.c
arguments.c:748:47: warning: implicit declaration of function 'rpl_malloc' is invalid in C99 [-Wimplicit-function-declaration]
serial_data = (int16_t *) malloc( (num_digits/2) * sizeof(int16_t) );
^
./config.h:72:16: note: expanded from macro 'malloc'
#define malloc rpl_malloc
^
arguments.c:748:35: warning: cast to 'int16_t *' (aka 'short *') from smaller integer type 'int' [-Wint-to-pointer-cast]
serial_data = (int16_t *) malloc( (num_digits/2) * sizeof(int16_t) );
^
2 warnings generated.
mv -f .deps/arguments.Tpo .deps/arguments.Po
gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -I/usr/local/include/libusb-1.0 -I/usr/include/libusb-1.0 -MT atmel.o -MD -MP -MF .deps/atmel.Tpo -c -o atmel.o atmel.c
mv -f .deps/atmel.Tpo .deps/atmel.Po
gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -I/usr/local/include/libusb-1.0 -I/usr/include/libusb-1.0 -MT commands.o -MD -MP -MF .deps/commands.Tpo -c -o commands.o commands.c
mv -f .deps/commands.Tpo .deps/commands.Po
gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -I/usr/local/include/libusb-1.0 -I/usr/include/libusb-1.0 -MT dfu.o -MD -MP -MF .deps/dfu.Tpo -c -o dfu.o dfu.c
dfu.c:903:12: warning: implicitly declaring library function 'malloc' with type 'void *(unsigned long)'
return malloc( n );
^
dfu.c:903:12: note: please include the header <stdlib.h> or explicitly provide a declaration for 'malloc'
1 warning generated.
mv -f .deps/dfu.Tpo .deps/dfu.Po
gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -I/usr/local/include/libusb-1.0 -I/usr/include/libusb-1.0 -MT intel_hex.o -MD -MP -MF .deps/intel_hex.Tpo -c -o intel_hex.o intel_hex.c
mv -f .deps/intel_hex.Tpo .deps/intel_hex.Po
gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -I/usr/local/include/libusb-1.0 -I/usr/include/libusb-1.0 -MT stm32.o -MD -MP -MF .deps/stm32.Tpo -c -o stm32.o stm32.c
mv -f .deps/stm32.Tpo .deps/stm32.Po
gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -I/usr/local/include/libusb-1.0 -I/usr/include/libusb-1.0 -MT util.o -MD -MP -MF .deps/util.Tpo -c -o util.o util.c
mv -f .deps/util.Tpo .deps/util.Po
gcc -Wall -g -O2 -I/usr/local/include/libusb-1.0 -I/usr/include/libusb-1.0 -o dfu-programmer main.o arguments.o atmel.o commands.o dfu.o intel_hex.o stm32.o util.o -lusb-1.0
Making all in docs
make[1]: Nothing to be done for `all'.
make[1]: Nothing to be done for `all-am'.
)
% make install # install dfu-programmer
(returns:
Making install in src
../m4/install-sh -c -d '/usr/local/bin'
/usr/bin/install -c dfu-programmer '/usr/local/bin'
make[2]: Nothing to be done for `install-data-am'.
Making install in docs
make[2]: Nothing to be done for `install-exec-am'.
../m4/install-sh -c -d '/usr/local/share/man/man1'
/usr/bin/install -c -m 644 dfu-programmer.1 '/usr/local/share/man/man1'
make[2]: Nothing to be done for `install-exec-am'.
make[2]: Nothing to be done for `install-data-am'.
)
- Now you should have...
paulbeda@crush:~/Documents/Arduino/dfu-programmer$ ls -al /usr/local/bin/df*
-rwxr-xr-x 1 paulbeda admin 90480 Mar 28 09:40 /usr/local/bin/dfu-programmer
- Move the WiFi shield jumper to enable firmware updates
- Connect JUST the shield (not mounted to an Arduino) to the host using a mini-USB cable
- Version 1.6.x of the IDE has changed the tree structure and fixed the path problem Katrina references. Use THIS command for v 1.6:
cd /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/firmwares/wifishield/scripts
sudo sh ArduinoWifiShield_upgrade_mac.sh -a /Applications/Arduino.app/Contents/Java -f shield
Password: ********
...and get...
Arduino WiFi Shield upgrade
=========================================
Disclaimer: to access to the USB devices correctly, the dfu-programmer needs to be used as root. Run this script as root.
****Upgrade WiFi Shield firmware****
Checking memory from 0x2000 to 0x3FFFF... Not blank at 0x2001.
Erasing flash... Success
Checking memory from 0x2000 to 0x3FFFF... Empty.
Checking memory from 0x2000 to 0x3FFFF... Empty.
0% 100% Programming 0x3E000 bytes...
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success
0% 100% Reading 0x3E000 bytes...
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success
Validating... Success
0x3E000 bytes written into 0x3E000 bytes memory (100.00%).
Done. Remove the J3 jumper and press the RESET button on the shield.
Thank you!
- Reconnect the WiFi shield to the Arduino and run the version check sketch in the IDE:
#include <WiFi.h>
void setup() {
Serial.begin(9600);
Serial.println("the version is: ");
Serial.println(WiFi.firmwareVersion());
}
void loop() {
}
…and get…
the version is:
1.1.0
Success!