// ************************************************************************************************* // @fn CW_Send_Char // @brief Send (via the buzzer) an alphanumeric character ("letter") // @param letter character to send, in range 39 (''') to 90 ('Z'), inclusive // @return none // ************************************************************************************************* void CW_Send_Char(u8 letter) { if ((letter >= 39) && (letter <= 90)) { // In range letter = CW_Char[letter - 39]; // Get first "letter" //gibbons TODO: check if '=' operator or memcpy(...) is more appropriate } else if (letter == ' ') { // Send space (inter-word pause) Timer0_A4_Delay(CONV_MS_TO_TICKS(CW_WORD_PAUSE * CW_DOT_LENGTH)); return; } else { // Invalid character return; } int i = 0x80; // Mask bit, starting at 0x80 = 1000 0000b while (i > letter) i >>= 1; // Find start bit i >>= 1; // Needed to skip over start bit, otherwise all letters start with an extra DASH! while (i > 0) { if (i & letter) { // Send dash (and pause after it) start_buzzer(1, CONV_MS_TO_TICKS(3*CW_DOT_LENGTH), CONV_MS_TO_TICKS(CW_SIGNAL_PAUSE * CW_DOT_LENGTH)); } else { // Send dot (and pause after it) start_buzzer(1, CONV_MS_TO_TICKS(CW_DOT_LENGTH), CONV_MS_TO_TICKS(CW_SIGNAL_PAUSE * CW_DOT_LENGTH)); } i >>= 1; // Move mask bit to the right one // Wait until finished buzzing while (is_buzzer()) { Timer0_A4_Delay(CONV_MS_TO_TICKS(2*CW_DOT_LENGTH)); // Go into LPM3 } } // Now send inter-letter pause (space between successive letters) Timer0_A4_Delay(CONV_MS_TO_TICKS(CW_LETTER_PAUSE * CW_DOT_LENGTH)); // Clean up display display.flag.full_update = 1; }
// ************************************************************************************************* // @fn idle_loop // @brief Go to LPM. Service watchdog timer when waking up. // @param none // @return none // ************************************************************************************************* 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(50) // 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 // To low power mode to_lpm(); #ifdef USE_WATCHDOG // Service watchdog (reset counter) WDTCTL = (WDTCTL &0xff) | WDTPW | WDTCNTCL; #endif }