EvalBot: Hello World!
This is the first step for getting your feet wet with any new platform, be it a new programming language or a random device you wish to subject to your whims.
The Stellaris EvalBot, as supplied, reeks of advertisement for some sort of embedded operating system (µC/OS-III). In fact if you want the pre-baked API and documentation you have to pony up for a book on it. That's well and dandy, but armed with a few creative Google searches I was able to avoid all that and get the basics for absolutely nothing. I was very much almost there and found a cool project done by Martin Hubacek controlling the EvalBot with a WiiMote nunchuck. Martin, being the awesome nice guy that he is, also provided the project files and source for his project:
Using some source from Martin's project to simplify life (and boy does it ever, if you use Eclipse!), as well as some very helpful posts from community members on the TI boards, I was able to get a toolchain up and running and work on my own EvalBot project from Eclipse.
Getting Started
To get started, you need a safe place to install your toolchain and compile things. If you're using a computer you might actually care about (or if you're a neat freak like me) then I highly advise you start off creating a virtual machine and do the rest of this from there. The non-OSE version of VirtualBox appears to work great with the EvalBot, so if you don't have a preference for virtual machines, I highly recommend it.
http://virtualbox.org/ (Remember, DON'T get the OSE version. It doesn't have the USB emulation that you'll need later on!!)
After you install that, download Ubuntu (or whatever flavor of Linux you prefer) and create a new virtual machine. It shouldn't require much RAM at all, 1gb tops. But as for hard drive size, you can squeeze it all in a 4gb image but you'll have to uninstall stuff you don't need like OpenOffice. I recommend 5gb or more for hard drive size. Install Ubuntu and then after that process is completed you should be at the desktop. Once you do that, you can get your tools set up.
https://www.synthetos.com/blog/setup-arm-toolchain-in-ubuntu/
This is THE link. If you follow these instructions you'll have the toolchain and the StellarisWare libraries built. This is like 90% of what you need.
http://sourceforge.net/projects/gnuarmeclipse/
If you are using eclipse, this will help you set up your project using the CodeSourcery GCC toolchain with much less frustration
I used the FTDI and OpenOCD instructions from here, but couldn't get the crosstool script to work right. I used CodeSourcery G++ lite instead.
To install Eclipse, click on the System menu at the top of the screen and go to Administration > Synaptic Package Manager. From here, search for Eclipse and check the box next to it. You only need to check Eclipse. Next click Apply and this will install it for you. Once you've installed Eclpse, you'll want to install the gnuarmeclipse plugin mentioned above.
When all is said and done, create a new workspace and a new c project, adjusting paths to match your environment wherever your StellarisWare bits have gone as well as the location of your copy of CodeSourcery G++ lite. When you clean your project, it should immediately compile everything and build the target (so keep an eye out on the Console and Problems tabs at the bottom-right.) If it succeeds, then the ELF file should have been built in your project's Debug or Release folder, depending on how you've set it up. If not, look at the Console and Problem tabs for clues.
Eclipse Project Details
When creating your project, select the ARM Sourcery Linux GCC option
Copy these files from Martin's Nunchuck project into the root of your project:
I2Clib.c
I2Clib.h
oled.c
oled.h
startup_gcc.c
main.ld
In project properties, navigate to C/C++ Build > Settings
In Target Processor
Select cortex-m3
Check Thumb (-mthumb)
Unckeck Thumb interwork
In Additional Tools
Check Create Flash Image (I have all three checked but this is likely the most important)
In ARM Sourcery Linux GCC Assembler > Miscellaneous
Specify this for Other flags option: -c -fmessage-length=0
In ARM Sourcery Linux GCC C Compiler > Directories, the following include paths (-I) should be listed
StellarisWare
StellarisWare/driverlib
StellarisWare/utils
In ARM Sourcery Linux GCC C Linker > General
For script file (-T), specify the main.ld from Martin's project (note, copy main.ld into your project folder too!)
Check Remove unused sections (-Xlinker --gc-sections)
Uncheck everything else
In ARM Sourcery Linux GCC C Linker > Libraries
Add "driver" under the top libraries (-l) section
Add StellarisWare and StellarisWare/driverlib/gcc to library search path (-L)
In ARM Sourcery Linux GCC C Linker > Miscellaneous
Set other flags option to this: --entry ResetISR
Flashing the Robot
Plug in the left ICDI USB port. If you have an earlier release of the hardware, you might also need to use the right-side port or batteries to provide power. Press the ON button next to the OLED screen. In order for the virtual machine to access the USB device, click on Devices in the VirtualBox menu and go to USB Devices. Click the checkbox next to the Stellaris device. Also, with the bot plugged in an turned on, you can go to the virtual machine settings under USB and add the stellaris board to the USB device filters. This will automatically add the bot to the virtual machine as soon as it is detected. This is a big timesaver and, in some cases, can help avoid having to restart OpenOCD from time to time.
To get your program on to the bot, you can use OpenOCD. I've worked out how to do this from the command line but am still trying to find a more automated way to do the same from Eclipse directly. (All tips greatly appreciated.) From the command-line, type:
cd /PATH_TO_OPENOCD
sudo openocd -f interface/luminary.cfg -f target/stellaris.cfg &
telnet localhost 4444
Then form there, repeat the following until you're finally happy with your program:
halt
flash write_image erase /PATH_TO_YOUR_PROJECT/project.elf
reset
Also, it should be of importance that you can backup your bot's programming with the following:
dump_image backup.rom 0 0x040000
Automating the deployment process
You can automate calling OpenOCD from Eclipse directly by configuring it as an external tool. There are some caveats to consider: The eclipse external tool configuration wizard doesn't provide any way to run the tool as a different user; however, OpenOCD will only run properly as root. If you're already root (you naughty person you) then this is probably not a big deal -- well until you do something very clumsy and wish you weren't always running as root. Anyway, here's what I did to cobble together OpenOCD automation, using tips from this website: http://www.makingthings.com/documentation/tutorial/debug-with-openocd/configure-eclipse
Create a text file called ocd_flash.cfg and save it somewhere near your project folder -- it doesn't have to be in your workspace necessarily.
Put the following into this file:
init
halt
flash write_image erase /PATH_TO_YOUR_PROJECT/project.elf
reset
shutdown
Create another file, call it "sudo_openocd.sh" and set the execute bit (+x), its contents should be the following, adjusting OpenOCD path as necessary:
echo YOUR_PASSWORD_HERE | sudo -S /usr/local/bin/openocd $@
From eclipse external tools button (looks like a green circle with a white arrow, and a red box on the bottom-right edge of the circle), go to the external tools configurations option
Click "Program" on the left panel then click the New icon above that. For location, provide the path to the sudo_openocd.sh script above. Working directory should be the install path of openocd (where all the tcl scripts are for it).
For arguments provide, adjusting ocd.cfg to path of file created above: -f interface/luminary.cfg -f target/stellaris.cfg -f /PATH_TO_OCD_CFG/ocd.cfg
Now you should be able to deploy the build without leaving Eclipse. If you also add the device filter to VirtalBox (mentioned above) then it should work correctly almost every time. (No guarantees, I don't have a crystal ball!!)
Code examples
HelloWorld.c -- Version 1
#include "inc/lm3s9b92.h"
#include "inc/hw_i2c.h"
#include "oled.h"
// bootloader references this, but we're not using it just yet
void SysTickHandler()
{}
int main(void)
{
init_display();
dispString("Hello World!",0,0);
while (1) {}
}
HelloWorld.c -- Version 2 (Hello Hack A Day!)
(see bottom attachment for the spreadsheet in OpenOffice Calc format)
#include "inc/lm3s9b92.h"
#include "inc/hw_i2c.h"
#include "oled.h"
// bootloader references this, but we're not using it just yet
void SysTickHandler()
{}
static const unsigned char image[96*2] = {
// Top 8 rows, each byte is a column of 8 pixels
0,0,0,0x80,0xC0,0,0x1C,0x76,0xB2,0xBE,0xB2,0x76,0x1C,0,0xC0,0xBE,0x8,0x8,0x8,0xFE,0,
0x3E,0x2A,0x22,0x62,0,0x3E,0x20,0x20,0x60,0,0x3E,0x20,0x20,0x60,0,0x1C,0x22,0x22,0x1C,
0,0,0,0,0x3E,0x8,0x3E,0,0x3E,0xA,0x3E,0,0x3E,0x22,0x22,0,0x3E,0x8,0x36,0,0x8,0,0x3C,
0xA,0xBC,0,0x8,0,0x3E,0x22,0x1C,0,0x3C,0xA,0x7C,0,0x6,0x38,0x6,0,0x2E,0x80,0xC0,0,0x1C,
0x76,0xB2,0xBE,0xB2,0x76,0x1C,0,0xC0,0x80,0,0,
// Bottom 8 rows, each byte is a column of 8 pixels
0,0,0,0x20,0x60,0x11,0xA,0xE,0x4,0x4,0x4,0xE,0xA,0x11,0x60,0x20,0,0,0,0,0,0,0,0,0,0,0,
0,0,0x2,0,0,0,0,0x9,0,0,0,0,0,0,0,0,0,0xBE,0xAA,0x94,0x80,0xBE,0xA0,0xA0,0x80,0xB8,0xA0,
0xB8,0x80,0xBE,0x8A,0xB4,0x80,0xB0,0x88,0x80,0x98,0x90,0x78,0,0,0,0,0,0,0,0,0x1,0,0,0,0,
0,0,0x20,0x60,0x11,0xA,0xE,0x4,0x4,0x4,0xE,0xA,0x11,0x60,0x20,0,0
};
int main(void)
{
init_display();
dispImage(image, 0, 0, 96, 2);
while (1) {}
}
// Try this if you're about to get in the dog-house with your other half for spending too much time on this stuff
// Update: This worked for me but your mileage may vary. I make no promises. Replace the array above and let
// your other half press the magic ON button to reveal a happy and romantic message complete with hearts.
// I hope that it grants you the blessing of instant forgiveness.
0xFC,0x2,0x61,0xF1,0xF9,0xF9,0xF9,0xF1,0xE1,0xF1,0xF9,0xE9,0xC9,0xF1,0x61,0x1,0x9,0xD,0xFD,0xFD,0xD,
0x9,0x1,0x1,0x1,0xF9,0xFD,0x1,0x1,0x1,0x1,0x1,0xF9,0xFD,0xD,0xD,0xFD,0xF9,0x1,0xF9,0xFD,0x1,0x1,0x1,
0xFD,0xF9,0x1,0xF9,0xFD,0x8D,0x8D,0xD,0x9,0x1,0x1,0x1,0x79,0xFD,0xC1,0x81,0xC1,0xFD,0x79,0x1,0xF9,
0xFD,0xD,0xD,0xFD,0xF9,0x1,0xF9,0xFD,0x1,0x1,0x1,0xFD,0xF9,0x1,0x1,0x1,0x61,0xF1,0xF9,0xF9,0xF9,0xF1,
0xE1,0xF1,0xF9,0xE9,0xC9,0xF1,0x61,0x2,0xFC,
0x3F,0x40,0x80,0x80,0x81,0x83,0x87,0x8F,0x9F,0x8F,0x87,0x83,0x81,0x80,0x80,0x80,0x90,0xB0,0xBF,0xBF,
0xB0,0x90,0x80,0x80,0x80,0x9F,0xBF,0xB0,0xB0,0xB0,0x90,0x80,0x9F,0xBF,0xB0,0xB0,0xBF,0x9F,0x80,0x83,
0x87,0x9E,0xBC,0x9E,0x87,0x83,0x80,0x9F,0xBF,0xB1,0xB1,0xB0,0x90,0x80,0x80,0x80,0x90,0xB0,0xB1,0xBF,
0x9F,0x80,0x80,0x80,0x9F,0xBF,0xB0,0xB0,0xBF,0x9F,0x80,0x8F,0xBF,0xB8,0xB0,0xB8,0x9F,0x8F,0x80,0x80,
0x80,0x80,0x80,0x81,0x83,0x87,0x8F,0x9F,0x8F,0x87,0x83,0x81,0x80,0x80,0x40,0x3F