Bike Computer V0.1 Build

Back: Electronics

I’ve built the first prototype of my bike computer and have been developing the firmware for a couple of weeks now. Everything except the temperature sensor, accelerometer, servo headers, and Li-ion fuel gauge have been populated.

There have been a few minor electrical bugs like forgetting resisters for the ISP programmer, but nothing too difficult to fix for the next prototype. The bigger problems have appeared in the software world. First, I’ve filled all 32K of the ATmega memory mainly because of lengthy sensor configurations, USB libs and FATFS. Second, RAM has become an issue when processing things like NMEA strings or drawing complex graphics. I’ve realized there is no point in having a vibrant TFT LCD screen if the 16MHz ATmega can only achieve low refresh rates, which is why I’ll probably switch to some ARM processor for the next prototype. Maybe I’ll go with the STM32F4 series.

Features:
  • ATmega32U4
  • 2 servo outputs to control an electronic derailleur
  • 3 axis accelerometer – MMA7260Q
  • GPS – Linx rxm-gps-sg
  • Altimeter – BMP085
  • Micro SD card
  • LIPO Charger – MCP73871
  • Fuel gauge – MAX1704X
  • 2.4′ x 2.0′
  • Electronic derailleur controller (electronic erailleur details)
Planned improvements
  • Heart rate monitor & pulse oximeter
  • LCD touch screen
  • Accurate measurement of energy output (maybe calibrate for each user instead of curve fitting)

Programming the STM32F4 DISCOVERY with the Bus Blaster

In my last post I talked about how to set up a toolchain on OSX. In this post I will show you how to program and debug the Discovery board using open source hardware and software.

The Discovery board supports ARM’s new two wire SWD serial debug port and 6 wire JTAG port. ST provides programmers and software to program their chip, but as usual no Linux support. Their dev boards also include a USB to JTAG translator called ST-LINK which has Linux support thanks to texane over at github. There has been discussion there about adding support for the STM32F4 and it appears one fork has been made for this purpose. At this point support seems spotty and programming takes longer than it should so I’ll show you the alternative.

Bus Blaster and OpenOCD
Warning: OpenOCD does not fully support the CortexM4 yet and this method may damage your hardware. I am not an expert OpenOCD user. Use at your own risk.

The Bus Blaster is an open hardware JTAG debugger made by Dangerous Prototypes, which you can get for about $35 at SeeedStudio. Any debugger compatible with Open On-Chip Debugger (OpenOCD) should work fine for these instructions.

Download OpenOCD version 0.5.0 here.
Extract and run the following configure script. You may want to change your install directory.

cd [OpenOCD]
CC=/usr/bin/gcc-4.2 CPP=/usr/bin/cpp-4.2 CXX=/usr/bin/g++-4.2 LD=/usr/bin/ld ./configure --prefix=/opt/local/ --enable-ft2232_libftdi
make
sudo make install

Download the STM32F4 Demo
Update: You will have to change LDFLAGS, CC, LD, … in the makefile to reflect your system.

git clone https://github.com/nabilt/STM32F4-Discovery-Firmware.git
cd STM32F4-Discovery_FW_V1.0.1/Project/IO_Toggle
make
Connect all 6 JTAG pins from the Bus Blaster to the Discovery. The Bus Blaster has labels on the PCB.
JTAG pinout Discovery board
TDI is located on pin PA15 on header P2 of the Discovery board.
Plugin the Bus Blaster to your computer. Power the Discover board via the mini USB, but NOT using a computer. The computer may cause unwanted signals sent through the JTAG pins.

Unload any FTDI kernel modules so they don’t conflict with OpenOCD

sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext/

Run OpenOCD

cd STM32F4-Discovery_FW_V1.0.1/openocd_config
openocd -f openocd.cfg -f stm32f4x.cfg

You should see something like this

Open On-Chip Debugger 0.5.0 (2011-10-30-17:32)
Licensed under GNU GPL v2
For bug reports, read
 http://openocd.berlios.de/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
2000 kHz
2000 kHz
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
Info : max TCK change to: 30000 kHz
Info : clock speed 2000 kHz
Info : JTAG tap: stm32f4xxx.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Info : JTAG tap: stm32f4xxx.bs tap/device found: 0x06413041 (mfg: 0x020, part: 0x6413, ver: 0x0)
Info : stm32f4xxx.cpu: hardware has 6 breakpoints, 4 watchpoints

1 Tap is for the CPU and the other is for the floating point unit.

Programming and Debugging with GDB
With OpenOCD waiting for commands open another terminal and run GDB for arm. All commands use the ocd directory as their working directory.

arm-none-eabi-gcc
(gdb) target extended localhost:3333
(gdb) # reset and halt the chip
(gdb) monitor halt
(gdb) # load symbol files
(gdb) file demo.elf
(gdb) # load demo.elf into RAM
(gdb) load demo.elf
Loading section .isr_vector, size 0x188 lma 0x8000000
Loading section .text, size 0xc5c lma 0x8000188
Loading section .data, size 0x38 lma 0x8000de4
Start address 0x8000d6c, load size 3612
Transfer rate: 6 KB/sec, 1204 bytes/write.
(gdb) # run the program. hit Control-C to stop
(gdb) continue

(gdb) # run your favorite gdb commands
(gdb) br main.c:71
(gdb) continue
(gdb) list
(gdb) info registers

Writing to flash
So far we’ve only copied our code to SRAM so when the chip is reset the program no longer exists. To write our program to flash we will need to us the flash write_image command, which you can learn more about here.

In GDB the monitor command passes commands straight to OpenOCD. Make sure OpenOCD is running and start GDB.

arm-none-eabi-gdb
(gdb) target extended localhost:3333
(gdb) monitor halt
(gdb) file demo.elf
(gdb) monitor flash write_image erase demo.hex 0 ihex
(gdb) continue

This works with the demonstration hex file provided by ST, but I haven’t gotten it working with my build system. My guess is a problem with the linker script.

It seems to get stuck in  HardFault_Handler() at stm32f4xx_it.c:61. If you have any ideas let me know in the comments.

What needs to be done

  1. Figure out the flash problem
  2. Add full support for the STM32F4 in OpenOCD

Using the STM32F4 DISCOVERY Board in OSX Lion

Update: Check out the new post on programming with JTAG

I recently got the STM32F4DISCOVERY board, which features ARM’s new CortexM4 with 1 MB Flash and 192 KB RAM. For the past couple of years I’ve been using AVRs because you can get open source compilers, libraries and programmers unlike their competitors. The only thing I miss from the ARM world is processor speed. Most of Atmel’s low end chips are less than 100MHz and can cost as much as a 150MHz ARM cpu with similar peripherals. This is one of the reasons why I am switching to ARM for the next prototype of the bicycle computer. Maybe I’ll stay in the family and use Atmel’s new CortexM4 when it comes out.

To use the STM32F4 Discovery in OSX we are going to need a cross compiler. There is a great thread on dangerousprototypes with lots of info, which I will summarize here. Then I’ll show the alternative setup.

Option 1: The easy way?
Rious has instructions on setting up the cross compiler on OSX and Linux using a build script from github. However, I was not able to get this working in Lion and I’m not sure if it is taking advantage of the FPU instruction set so I decided to build one from scratch.

Option 2: The “fun” way
Here is what you need. Get the latest version of each.
MacPorts (the .dmg is fine): Package manager for OSX. We will need this to compile things like libusb.
Binutils: Binary utilies like a linker and assembler
Newlib: Standard C library for embedded systems
GCC: C Compiler source
GDB: C debugger
XCode: Compiler to compile arm-gcc

I’m using:
MacPorts 2.0.3
binutils-2.21.1
newlib-1.19.0
gcc-4.6.1
gdb-7.3.1
Xcode: 4.1

First we need to install the gcc dependencies using MacPorts

sudo port install gmp mpfr libmpc

Next we will build binutils. Notice the CC CPP CXX LD environment variables. This tells the Makefile to use gcc-4.2 instead of the llvm-gcc compiler.

Note: UnaClocker in the commets had problems when redefining CC, CPP, CXX and LD. If you have similar errors try removing them.

cd [binutils-build]
CC=/usr/bin/gcc-4.2 CPP=/usr/bin/cpp-4.2 CXX=/usr/bin/g++-4.2 LD=/usr/bin/ld ./configure  --target=arm-none-eabi --prefix=/opt/local/ --enable-interwork --enable-multilib --disable-nls --disable-libssp
make all
sudo make install

Some definitions
–prefix=/opt/local/: Set the install directory. I’m putting it with my MacPorts install.
–enable-interwork: Allows ARM and Thumb code to be used
–enable-multilib: Build multible versions of some libs. E.g. one with soft float and one with hard
–disable-nls: Tells gcc to only support American English output messages
–disable-libssp: Don’t include stack smashing protection

GCC is next
Update: added patch info. Thanks to Msmith+disqus from the comments in the bus blaster post.

First lets apply a patch to gcc to add hardware floating point.
Download the patch from here.

cd [gcc-build]
patch gcc/config/arm/t-arm-elf patch-gcc-config-arm-t-arm-elf.diff

Make sure to set the path of –with-headers. Notice we are bootstrapping gcc by running make all-gcc. We will have to come back and run make all later.
Update: changed sudo make install-gcc to make all-gcc and sudo make install-gcc. Thanks UnaClocker.

cd [gcc-build]
mkdir objdir
cd objdir
CC=/usr/bin/gcc-4.2 CPP=/usr/bin/cpp-4.2 CXX=/usr/bin/g++-4.2 LD=/usr/bin/ld ../configure --target=arm-none-eabi --prefix=/opt/local/ --enable-interwork --enable-multilib --enable-languages="c" --with-newlib --with-headers=[newlibdir]/newlib-1.19.0/newlib/libc/include/ --disable-libssp --with-gmp=/opt/local/ --with-mpfr=/opt/local/ --with-mpc=/opt/local/ --with-libiconv-prefix=/opt/local/ --disable-nls
make all-gcc
sudo make install-gcc

Try running arm-none-eabi-gcc -print-multi-lib to see if you hardware floating point. You should see:


.;
thumb/arm7tdmi-s;@mthumb@mcpu=arm7tdmi-s
thumb/cortex-m3;@mthumb@mcpu=cortex-m3
thumb/cortex-m4;@mthumb@mcpu=cortex-m4
thumb/cortex-m4/float-abi-hard/fpuv4-sp-d16;@mthumb@mcpu=cortex-m4@mfloat-abi=hard@mfpu=fpv4-sp-d16

Build Newlib

cd [newlib-build]
CC=/usr/bin/gcc-4.2 CPP=/usr/bin/cpp-4.2 CXX=/usr/bin/g++-4.2 LD=/usr/bin/ld ./configure --target=arm-none-eabi --prefix=/opt/local/ --enable-interwork --enable-multilib --disable-libssp --disable-nls
make all
sudo make install

Finish building GCC

cd [gcc-build]/objdir
make all
sudo make install

Build the debugger

cd [gdb-build]
CC=/usr/bin/gcc-4.2 CPP=/usr/bin/cpp-4.2 CXX=/usr/bin/g++-4.2 LD=/usr/bin/ld ./configure --target=arm-none-eabi --prefix=/opt/local/ --enable-interwork --enable-multilib --disable-libssp --disable-nls
make all
sudo make install

Setting up ST-LINK
ST-LINK lets you debug and program the dev board from a windows box. To get it working in OSX and linux we will need the help of open source software.

Once again Rious has instructions on how to do this. For documentation see the pdf in github. It looks like it only supports writing to RAM and not Flash for CortexM4 devices. Check out the bug report here.

In the next post I’ll upload the modified example source files from ST.

SnapBill: Receipt scanning for your N8

Update: Just published in the Ovi store: http://store.ovi.com/content/111546

SnapBill is a simple expense management tool that lets you save receipts using your camera phone.

Features
– OCR
– Split restaurant bills with friends
– Track who owes you money
– Expense reporting

It should be in the Ovi Store at the beginning of May.

Receipt and debt view

 

Stats and users view

 

Example photo take with the app

TapGrab – Print screen for Symbian^3

Update: Just published in the Ovi store http://store.ovi.com/content/111560
For my last post I talked about the Symbian UI and posted screenshots as visuals. Well, the app I used was one I developed called TapGrab. Just tap double tap the phone and a screenshot of your desktop is saved locally in “E:/Images/Screen Captures” and uploaded to Dropbox.
The app is free, but it contains ads. I also plan to release a paid version to see which one does better.

Weekend Project: Optimize your cell phone plan (Canada Only)

Note: This is a very basic prototype and it not meant for consumers at this point and the pricing for the plans are not current.

I built a simple web service that compares Canadian cellphone plans. It can be found at http://cellgauge.alwaysdata.net. Just upload a previous bill from Rogers, Bell or Fido and get a recommendation on which plan you should be using. You also get graphs about your usage. Hosting is provided by alwaysdata for free so please excuse the speed of the site.

Limitations

  • Only reads Rogers, Bell or Fido bills
  • Only compares plans from Bell, Fido and Telus
  • Only compares based on monthly minutes in plan (charged using carrier rate if you go over), evenings and weekend usage, free 5 friends calling
  • No long distance support
  • The carrier’s plan data is not updated automatically
  • No text messaging or data support