TI eZ430 Watch – Unboxing and Hello World
September 3, 2011 22 Comments
It’s been almost a month since my last post, and this is due among others, to some August holidays in France… This being the 1st week-end back in London I thought I HAD to hack something and blog about it…
While away I have received the eZ430 Chronos Development Tool / Watch from Texas Instruments (have I ever mentioned how great their service is, how quick and free the delivery, etc. … !? ) and therefore had to put aside my Android / IOIO related projects, and delve into this new gadget !
1. First impressions
The packaging looks good, as good or even better than “real” watches… !
The contents are quite impressive, and TI seems to be taking these eval kits quite seriously : not only they include the USB programmer / debugger and an USB wireless access point for remote communication, but even a screwdriver and a couple of spare screws…
Have I mentioned that this kit costed me only 25$ (on sale from the original 50$) including free shipping to the UK !? I know it’s all about advertising their products, but still… THANK YOU TI, this is a lot of stuff for ~ 15£ !
Now let’s get down to business and try to program this “beast”…
2. Connect the hardware
This is quite easy, and here’s how it looks with the internals exposed:
And now connected to the USB programmer / debugger :
3. Software environment
Now the hard stuff commences…
First look at the “Sports Watch” code (basically the firmware that the watch comes with) reminds me why I’m a Java programmer by trade…
Then I install the IAR development environment and all of a sudden memories from high school rush back to my mind… haven’t these guys notices we’re in 2011 !
I can’t even seem to be able to open an existing project… lol…
I try Code Composer Studio… much better, Eclipse based… Java rocks indeed, at least for the IDE !
Ok, I know that I’m just a newbie when it comes to embedded electronics and that IAR is probably one of the best tools out there, but hey I want to have fun, I’m not paid to do this ! It’s enough that I have to program these little marvels in C and that even the slightest string manipulation takes 5 lines of code, I want to enjoy my hobby !
One issue worth nothing is also the general slowness of both the compilation and the download of the firmware to the eZ430. It takes around 1min 20secs even for the slightest change to get re-compiled and transfered over.
4. My first program
All I want to do is create a new mode on the watch that simply displays “Hello World”. To make things slightly more complex, and because there are not enough digits, I want the text to scroll.
I struggle a couple of hours on a Friday night but finally start to appreciate TI’s code… it’s quite clean and well organised, in some sort of state machine. All I need to do is replicate the already existing code for the “acceleration” mode (the one that periodically reads the accelerometer chip and displays the values on the screen).
1. the code for the new MODULE
The HEADER - trandi.h
#ifndef TRANDI_H_
#define TRANDI_H_
// ******************************************
// Defines section
#define TRANDI_MODE_OFF (0u)
#define TRANDI_MODE_ON (1u)
// ******************************************
// Global Variable section
struct trandi
{
// TRANDI_MODE_OFF, TRANDI_MODE_ON
u8 mode;
// Data to display
u8 msg[20];
};
extern struct trandi sTrandi;
// ******************************************
// Extern section
extern void reset_trandi(void);
extern void sx_trandi(u8 line);
extern void display_trandi(u8 line, u8 update);
extern u8 is_trandi_active(void);
extern void do_trandi_random(void);
#endif /*TRANDI_H_*/
The IMPLEMENTATION – trandi.c
// ******************************************
// Include section
// system
#include "project.h"
// driver
#include "display.h"
#include "vti_as.h"
// logic
#include "trandi.h"
#include "simpliciti.h"
#include "user.h"
#include "string.h"
// ******************************************
// Global Variable section
struct trandi sTrandi;
// ******************************************
// Extern section
// ******************************************
// @fn reset_trandi
// @brief Reset / INIT trandi data.
// @param none
// @return none
// ******************************************
void reset_trandi(void)
{
// Reset state is not active
sTrandi.mode = TRANDI_MODE_OFF;
strcpy(sTrandi.msg, (u8*)"TRANDI HELLO WORLD ");
}
// ******************************************
// @fn sx_trandi
// @brief Button UP does nothing for now...
// @param u8 line LINE2
// @return none
// ******************************************
void sx_trandi(u8 line)
{
}
// ******************************************
// @fn display_trandi
// @brief Display routine.
// @param u8 line LINE1
// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR
// @return none
// ******************************************
void display_trandi(u8 line, u8 update)
{
if (update == DISPLAY_LINE_UPDATE_FULL)
{
display_chars(LCD_SEG_L1_3_0, sTrandi.msg, SEG_ON);
display_symbol(LCD_ICON_HEART, SEG_ON_BLINK_ON);
// Set mode
sTrandi.mode = TRANDI_MODE_ON;
}
else if (update == DISPLAY_LINE_UPDATE_PARTIAL)
{
display_chars(LCD_SEG_L1_3_0, sTrandi.msg, SEG_ON);
}
else if (update == DISPLAY_LINE_CLEAR)
{
display_symbol(LCD_ICON_HEART, SEG_OFF);
reset_trandi();
}
}
// ******************************************
// @fn is_trandi_active
// @brief Returns 1 if trandi module is currently active and needs doing random stuff.
// @param none
// @return u8 1 = trandi module needs random stuff
// ******************************************
u8 is_trandi_active(void)
{
return sTrandi.mode == TRANDI_MODE_ON;
}
void do_trandi_random(void)
{
// Move the text
u8 firstElem = sTrandi.msg[0];
u8 len = sizeof(sTrandi.msg) / sizeof(u8);
u8 i;
for(i = 0; i < len - 1; i++) sTrandi.msg[i] = sTrandi.msg[i+1];
sTrandi.msg[len - 1] = firstElem;
// Set display update flag
display.flag.update_trandi = 1;
}
2. modify the main MENU
In the menu.c define this new structure
// Line1 - Trandi secret function
const struct menu menu_L1_Trandi =
{
FUNCTION(sx_trandi), // direct function
FUNCTION(dummy), // sub menu function
FUNCTION(display_trandi), // display function
FUNCTION(update_trandi), // new display data
&menu_L1_Alarm,
};
u8 update_trandi(void)
{
return (display.flag.update_trandi);
}
Add it to the chain of L1 menus, after the “Time” one, like so:
const struct menu menu_L1_Time =
{
FUNCTION(sx_time), // direct function
FUNCTION(mx_time), // sub menu function
FUNCTION(display_time), // display function
FUNCTION(update_time), // new display data
&menu_L1_Trandi,
};
3. modify the MAIN logic
In main.c , update init_global_variables() with a pointer to the new menu (if we want it to be displayed by default) and a call to reset_trandi().
void init_global_variables(void)
{
// --------------------------------------------
// Apply default settings
// set menu pointers to default menu items
// ptrMenu_L1 = &menu_L1_Time;
ptrMenu_L1 = &menu_L1_Trandi;
// ptrMenu_L1 = &menu_L1_Alarm;
// ptrMenu_L1 = &menu_L1_Heartrate;
...................
// Reset acceleration measurement
reset_acceleration();
// Reset / init trandi stuff
reset_trandi();
// Reset BlueRobin stack
reset_bluerobin();
}
Also add if (request.flag.trandi) do_trandi_random(); in process_requests().
4. update the TIMER calls to enable scrolling
There’s plenty of stuff in timer.c and we need to add a trigger on one of the periodic events, so that the trandi module gets “woken up” periodically and moves the custom string left.
Initially timer.c is EXCLUDED from the build, simply because I’m using the Core Edition of CSS which limits the max size of the code compiled (have I told you how much I love Arduino and the Open Source community !?
). However I could easily add back this file to be compiled with the others, without going beyond the limit … hooray…
In TIMER0_A0_ISR() (this is called every second which is really what we want !):
// Send a signal / do some random stuff every second on Trandi, WHEN enabled
if (is_trandi_active())
{
request.flag.trandi = 1;
}
// If BlueRobin transmitter is connected, get data from API
if (is_bluerobin()) get_bluerobin_data();
And that’s it ! The text “TRANDI HELLO WORLD” scrolls on the L1 display ! (notice that understandably there’s no easy way to fit a “W” in a 7 segments digit, so it’s not displayed correctly, I get a “-” instead…lol..;) )
At the end of the day, it’s not terribly complex, it works and it took me only about half a day to get here…
If you’re reading this, then thank you for your patience and interest, and please don’t forget to leave your feedback which would be more than appreciated !






How did you load the firmewarefiles like projekt.h in your CCS?
If i import the files i get a lot of errors so there is no projekt.h file in the folder, etc.
Hi Paul,
To be honest I don’t recall the details I have simply followed the instructions on the TI site to set up the project and all the rest.
The only “difficulty” I remember about was the fact that you have to choose the right frequency (there are basically 3 versions of some of the project files, one for each frequency of the wireless communication).
Other than that, it was straight forward…
dan
Hi, Trandi:
Nice post!
I follow your post and got the code compiled, but at the link stage (I am using IAR kickstart), I run into this error:
Linking
Error[e24]: Segment DATA16_AN (seg part no 2, symbol “TA0R” in module “stopwatch”, address [350-351]) overlaps segment DATA16_AN (seg part no 4, symbol “_A_TA0R_L” in module “BRRX_Radio”, address [350-351])
Error while running Linker
I don’t know where “BRRX_Radio” module is called in this project. Does this mean the code size overlimit?
I included “timer.c” in build as you mentioned, also included “ports.c” to avoid warnings.
Do you experienced same problem? Any suggestions?
Thanks in advance!
Kevin
Hi Kevin,
Thank you for your comment !
I’m personally using CodeComposer 4 (have tried IAR but I feel like going back 20 years in time, and just seeing its GUI makes me cringe…
) and have never seen this error.
But to be honest I’m far from an expert on this, I barely followed the tutorials myself…
Sorry for not being able to help more…
Dan
How do I transmit data[10-digit_code] from my laptop to the watch and store it in the watch ?
next, I want to read the data from the watch[same data] from my laptop..how do I do it?
Thanks
Nice work. I did have a question though.
You’ve used “request.flag.trandi” in two places, namely in main.c as [if (request.flag.trandi) do_trandi_random();] and in timer.c as [request.flag.trandi = 1;].
When I try to build the project I get two errors saying “struct “” has no field “trandi.”
Why is this happening and how can fix it?
thank you.
p.s. to implement the “W” i’ve used “SEG_B+SEG_D+SEG_F” where the segments are labeled as such. It seems to be unique and looks okay.
// A
// _
// F |_| B (G for the middle)
// E |_| C
// D
Good point !
I have actually updated the s_request_flags in project.h like so :
// Set of request flags
typedef union
{
struct
{
u16 temperature_measurement : 1; // 1 = Measure temperature
u16 voltage_measurement : 1; // 1 = Measure voltage
u16 altitude_measurement : 1; // 1 = Measure air pressure
u16 acceleration_measurement : 1; // 1 = Measure acceleration
u16 buzzer : 1; // 1 = Output buzzer
u16 trandi : 1; // 1 = Do stuff in Trandi
} flag;
u16 all_flags; // Shortcut to all display flags (for reset)
} s_request_flags;
extern volatile s_request_flags request;
But forgot to put this modif in this post…
Update your struct accordingly and let me know if it works for you ?
Hope this helps,
Dan
P.S. Thanks for the feedback on “W”…
I had already updated the struct in display.h with “u16 update_trandi: 1;” but didn’t know where the request struct was.
Cool! Thanks Dan. It works great.
-Paul
Great, glad it helped your !
I’d be curious to see what exactly you’re doing with your watch, don’t hesitate to post a link to your project if you have put anything online…
Dan
I am trying to make the watches communicate with each other how do I proceed ? Thanks
Here’s the official wiki page, where you can find plenty of examples…
hey trandi, I looked at them, I couldn’t find any applications where two watches communicate with each other without any help of access point. Should I modify the code of the simpliciti.c file?
Thanks,
AA
Found one. “Chronos Bike”
Yep, exactly ! That’s the only one I’ve seen that does watch-to-watch communication…
Do let me know how your project goes, I’m quite curious to see the final result !
Dan
Nice software. I suggest you hghlight to inform the modification on process_requests.
Thanks.
I’ve also just started with this great toy:-)
Nah look here : http://meskauskas.us/howard/de/Unit5Combinational/sevenSegFont.gif
| |
_
ok I get it now… thanks !
dan
no prob great to be of help
I just received my watch as well
Ok, great ! I can’t wait to see some pictures or code with your modifications… Can you post a link here to your blog or website ?
Dan
_
|_| | | Most use the right char to display a “W” on 7 segment displays
|_| _
You mean a “>”… ? That’s strange…