Quick TI MSP-430 Chronos Project
In a few earlier blogs I wrote about the TI eZ430-Chronos. This is my last entry about it for awhile -- I promise. In case you missed the last few installments, the Chronos is an inexpensive development kit for the TI MSP430 that happens to be built inside a wrist watch.
If you remember last time I was struggling to get the watch firmware where I could rebuild it and load it into the watch. Part of my problem was some buggy libraries provided with the watch and some of my problem was the lack of Linux tools. I finally solved it all by going with open source firmware and gcc. That was the last installment.
Once you can get the watch firmware loaded, how hard is it to make some significant change? Turns out it isn't that hard at all. The OpenChronos firmware has a nice Python script for configuring pieces in or out and I wanted to use that. I also didn't want to change the basic menu structure of the watch.
So a project idea was born: You might know I'm a ham radio operator (WD5GNR). I decided that when you switched the watch to display seconds it would cache the current time and send it once in Morse code. Then it would stop until you entered the seconds display mode again. You can see the result on YouTube.
So how hard was this? Trivial really. I replaced idle_loop with the following code in ezchronos.c:
void idle_loop(void)
{
#ifdef CONFIG_CW_TIME
// what I'd like to do here is set a morsepos variable
// if non-zero it is how many digits we have left to go
// on sending the time.
// we also would have a morse var that would only get set
// the first send and reset when not in view so we'd only
// send the time once
#define CW_DIT_LEN CONV_MS_TO_TICKS(100) // basic element size (100mS)
static int morse=0; // should send morse == 1
static int morsepos=0; // position in morse time (10 hour =1, hour=2, etc.)
static int morsehr; // cached hour for morse code
static int morsemin; // cached minute for morse code
static int morsedig=-1; // current digit
static int morseel; // current element in digit (always 5 elements max)
static unsigned int morseinitdelay; // start up delay
// We only send the time in morse code if the seconds display is active, and then only
// once per activation
if (sTime.line1ViewStyle == DISPLAY_ALTERNATIVE_VIEW)
{
if (!morse) // this means its the first time (we reset this to zero in the else)
{
morse=1; // mark that we are sending
morsepos=1; // initialize pointer
// Jim pointed out it is remotely possible that a button
// int could wake up this routine and then the hour could
// flip over after reading so I added this "do" loop
do {
morsehr=sTime.hour; // and cache
morsemin=sTime.minute;
} while (morsehr!=sTime.hour);
morsedig=-1; // not currently sending digit
morseinitdelay=45000; // delay for a bit before starting so the key beep can quiet down
}
if (morseinitdelay) // this handles the initial delay
{
morseinitdelay--;
return; // do not sleep yet or no event will get scheduled and we'll hang for a very long time
}
if (!is_buzzer() && morsedig==-1) // if not sending anything
{
morseel=0; // start a new character
switch (morsepos++) // get the right digit
{
case 1:
morsedig=morsehr/10;
break;
case 2:
morsedig=morsehr%10;
break;
case 3:
morsedig=morsemin/10;
break;
case 4:
morsedig=morsemin%10;
break;
default: morsepos=5; // done for now
}
if (morsedig==0) morsedig=10; // treat zero as 10 for code algorithm
}
// now we have a digit and we need to send element
if (!is_buzzer()&&morsedig!=-1)
{
int digit=morsedig;
// assume we are sending dit for 1-5 or dah for 6-10 (zero is 10)
int ditdah=(morsedig>5)?1:0;
int dit=CW_DIT_LEN;
if (digit>=6) digit-=5; // fold digits 6-10 to 1-5
if (digit>=++morseel) ditdah=ditdah?0:1; // flip dits and dahs at the right point
// send the code
start_buzzer(1,ditdah?dit:(3*dit),(morseel>=5)?10*dit:dit);
// all digits have 5 elements
if (morseel==5) morsedig=-1;
}
}
else
morse=0; // no morse code right now
#endif
// from here down, same as original code
// To low power mode
to_lpm();
#ifdef USE_WATCHDOG
// Service watchdog
WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
#endif
}
In addition, I added one entry to the "DATA" assignment in tools/config.py:
"CONFIG_CW_TIME": {
"name": "CW Time",
"depends": [],
"default": False},
This isn't really necessary, but it allows the configuration menu (brought up with "make config" to handle the "CW Time" option (CW is another term ham radio operators use for Morse code — it refers to how Morse code is modulated on a radio wave; namely, Continuous Wave).
So the verdict is in. The watch can be reprogrammed, even under Linux. It is reasonable to add functions to it and create a custom watch with your own desired features. Pretty cool even if my wife thinks the watch is way too geeky to wear.can be reprogrammed, even under Linux. It is reasonable to add functions to it and create a custom watch with your own desired features. Pretty cool even if my wife thinks the watch is way too geeky to wear.\n","id":"eta_0"}

