// ************************************************************************************************* // @fn process_requests // @brief Process requested actions outside ISR context. // @param none // @return none // ************************************************************************************************* void process_requests(void) { // Do temperature measurement if (request.flag.temperature_measurement) temperature_measurement(FILTER_ON); // Do pressure measurement #ifdef CONFIG_ALTITUDE if (request.flag.altitude_measurement) do_altitude_measurement(FILTER_ON); #endif #ifdef FEATURE_PROVIDE_ACCEL // Do acceleration measurement if (request.flag.acceleration_measurement) do_acceleration_measurement(); #endif // Do voltage measurement if (request.flag.voltage_measurement) battery_measurement(); // Generate alarm (two signals every second) if (request.flag.buzzer) start_buzzer(2, BUZZER_ON_TICKS, BUZZER_OFF_TICKS); #ifdef CONFIG_STRENGTH if (request.flag.strength_buzzer && strength_data.num_beeps != 0) { start_buzzer(strength_data.num_beeps, STRENGTH_BUZZER_ON_TICKS, STRENGTH_BUZZER_OFF_TICKS); strength_data.num_beeps = 0; } #endif // Reset request flag request.all_flags = 0; }
// ************************************************************************************************* // @fn process_requests // @brief Process requested actions outside ISR context. // @param none // @return none // ************************************************************************************************* void process_requests(void) { #ifdef ECO_DISPLAY // Change display freq when needed if (request.flag.eco_display) eco_display(); #endif // Do temperature measurement if (request.flag.temperature_measurement) temperature_measurement(FILTER_ON); // Do pressure measurement #ifdef CONFIG_ALTITUDE if (request.flag.altitude_measurement) do_altitude_measurement(FILTER_ON); #endif #ifdef CONFIG_ALTI_ACCUMULATOR if (request.flag.altitude_accumulator) altitude_accumulator_periodic(); #endif #ifdef FEATURE_PROVIDE_ACCEL // Do acceleration measurement if (request.flag.acceleration_measurement) do_acceleration_measurement(); #endif #ifdef CONFIG_BATTERY // Do voltage measurement if (request.flag.voltage_measurement) battery_measurement(); #endif #ifdef CONFIG_ALARM // Generate alarm (two signals every second) if (request.flag.alarm_buzzer) start_buzzer(2, BUZZER_ON_TICKS, BUZZER_OFF_TICKS); #endif #ifdef CONFIG_EGGTIMER // Generate alarm (two signals every second) if (request.flag.eggtimer_buzzer) start_buzzer(2, BUZZER_ON_TICKS, BUZZER_OFF_TICKS); #endif #ifdef CONFIG_STRENGTH if (request.flag.strength_buzzer && strength_data.num_beeps != 0) { start_buzzer(strength_data.num_beeps, STRENGTH_BUZZER_ON_TICKS, STRENGTH_BUZZER_OFF_TICKS); strength_data.num_beeps = 0; } #endif // Reset request flag request.all_flags = 0; }
// ************************************************************************************************* // @fn process_requests // @brief Process requested actions outside ISR context. // @param none // @return none // ************************************************************************************************* void process_requests(void) { // Do temperature measurement if (request.flag.temperature_measurement) temperature_measurement(FILTER_ON); // Do pressure measurement if (request.flag.altitude_measurement) do_altitude_measurement(FILTER_ON); // Do acceleration measurement if (request.flag.acceleration_measurement) do_acceleration_measurement(); // Do voltage measurement if (request.flag.voltage_measurement) battery_measurement(); // Generate alarm (two signals every second) if (request.flag.buzzer) start_buzzer(2, BUZZER_ON_TICKS, BUZZER_OFF_TICKS); // Reset request flag request.all_flags = 0; }
void ther_buzzer_playing_music(void) { struct ther_buzzer *b = &buzzer; unsigned char tone; if (b->cur_step == 0) { print(LOG_DBG, MODULE "why cur step is %d ??\n", b->cur_step); } b->cur_step++; if (b->cur_step == STEP_END) { print(LOG_DBG, MODULE "end music %d\n", b->music); stop_buzzer(); b->cur_step = 0; return; } if (b->cur_step % 2) { tone = musics[b->music][TONE_OFFSET]; start_buzzer(tone); } else { stop_buzzer(); } osal_start_timerEx(b->task_id, TH_BUZZER_EVT, musics[b->music][b->cur_step]); }
// Plays current winner tone and decrements it for a higher note next void next_winner_tone() { uint8_t tone = winner_tone; if (tone > 70) { start_buzzer(tone * (F_CPU / 1000000), 6, &next_winner_tone); winner_tone = tone - 1; } else { stop_buzzer(); } }
// ************************************************************************************************* // @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; }
void ther_buzzer_start_music(unsigned char music) { struct ther_buzzer *b = &buzzer; unsigned char tone; if (b->cur_step != 0) return; print(LOG_DBG, MODULE "start music %d\n", music); b->music = music; b->cur_step = STEP_START; tone = musics[b->music][TONE_OFFSET]; start_buzzer(tone); osal_start_timerEx(b->task_id, TH_BUZZER_EVT, musics[b->music][b->cur_step]); }
//Beep Function //Controls periodic beep void f_beep(void) { extern unsigned volatile flash; extern unsigned volatile flash_counter; if ((flash_counter / 4) == 1) { start_buzzer(1, BUZZER_ON_TICKS, BUZZER_OFF_TICKS); if (flash == 1) { flash = 0; display_symbol(LCD_ICON_ALARM, SEG_OFF); } else { flash = 1; display_symbol(LCD_ICON_ALARM, SEG_ON); } } }
__interrupt void PORT2_ISR(void) { // Clear flags u8 int_flag, int_enable; u8 buzzer = 0; u8 simpliciti_button_event = 0; static u8 simpliciti_button_repeat = 0; // Remember interrupt enable bits int_enable = BUTTONS_IE; if ((!button.flag.star_long) && (!button.flag.num_long)) { // Clear button flags button.all_flags = 0; // Store valid button interrupt flag int_flag = BUTTONS_IFG & int_enable; // --------------------------------------------------- // While SimpliciTI stack is active, buttons behave differently: // - Store button events in SimpliciTI packet data // - Exit SimpliciTI when button DOWN was pressed if (is_rf()) { // Erase previous button press after a number of resends (increase number if link // quality is low) // This will create a series of packets containing the same button press // Necessary because we have no acknowledge // Filtering (edge detection) will be done by receiver software if (simpliciti_button_repeat++ > 6) { simpliciti_data[0] &= ~0xF0; simpliciti_button_repeat = 0; } if ((int_flag & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) { simpliciti_data[0] |= SIMPLICITI_BUTTON_STAR; simpliciti_button_event = 1; } else if ((int_flag & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) { simpliciti_data[0] |= SIMPLICITI_BUTTON_NUM; simpliciti_button_event = 1; } else if ((int_flag & BUTTON_UP_PIN) == BUTTON_UP_PIN) { simpliciti_data[0] |= SIMPLICITI_BUTTON_UP; simpliciti_button_event = 1; } else if ((int_flag & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN) { simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; } // Trigger packet sending inside SimpliciTI stack if (simpliciti_button_event) simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; } else // Normal operation { // Debounce buttons if ((int_flag & ALL_BUTTONS) != 0) { // Disable PORT2 IRQ __disable_interrupt(); BUTTONS_IE = 0x00; __enable_interrupt(); // Debounce delay 1 Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN)); // Reset inactivity detection sTime.last_activity = sTime.system_time; } // --------------------------------------------------- // STAR button IRQ if (IRQ_TRIGGERED(int_flag, BUTTON_STAR_PIN)) { // Filter bouncing noise if (BUTTON_STAR_IS_PRESSED) { button.flag.star = 1; button.flag.star_not_long = 0; // Generate button click buzzer = 1; } else if ((BUTTONS_IES & BUTTON_STAR_PIN) == BUTTON_STAR_PIN) { button.flag.star = 1; button.flag.star_not_long = 0; BUTTONS_IES &= ~BUTTON_STAR_PIN; } } // --------------------------------------------------- // NUM button IRQ else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN)) { // Filter bouncing noise if (BUTTON_NUM_IS_PRESSED) { button.flag.num = 1; button.flag.num_not_long = 0; // Generate button click buzzer = 1; } else if ((BUTTONS_IES & BUTTON_NUM_PIN) == BUTTON_NUM_PIN) { button.flag.num = 1; button.flag.num_not_long = 0; BUTTONS_IES &= ~BUTTON_NUM_PIN; } } // --------------------------------------------------- // UP button IRQ else if (IRQ_TRIGGERED(int_flag, BUTTON_UP_PIN)) { // Filter bouncing noise if (BUTTON_UP_IS_PRESSED) { button.flag.up = 1; // Generate button click buzzer = 1; } } // --------------------------------------------------- // DOWN button IRQ else if (IRQ_TRIGGERED(int_flag, BUTTON_DOWN_PIN)) { // Filter bouncing noise if (BUTTON_DOWN_IS_PRESSED) { button.flag.down = 1; // Generate button click buzzer = 1; // Faster reaction for stopwatch stop button press if (is_stopwatch() && !sys.flag.lock_buttons) { stop_stopwatch(); button.flag.down = 0; } } } // --------------------------------------------------- // B/L button IRQ else if (IRQ_TRIGGERED(int_flag, BUTTON_BACKLIGHT_PIN)) { // Filter bouncing noise if (BUTTON_BACKLIGHT_IS_PRESSED) { sButton.backlight_status = 1; sButton.backlight_timeout = 0; P2OUT |= BUTTON_BACKLIGHT_PIN; P2DIR |= BUTTON_BACKLIGHT_PIN; } } } // Trying to lock/unlock buttons? if (button.flag.num && button.flag.down) { // No buzzer output buzzer = 0; button.all_flags = 0; } // Generate button click when button was activated if (buzzer) { // Any button event stops active alarm if (sAlarm.state == ALARM_ON) { stop_alarm(); button.all_flags = 0; } else if (!sys.flag.up_down_repeat_enabled) { start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150)); } // Debounce delay 2 Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); } // --------------------------------------------------- // Acceleration sensor IRQ if (IRQ_TRIGGERED(int_flag, AS_INT_PIN)) { // Get data from sensor request.flag.acceleration_measurement = 1; } // --------------------------------------------------- // Pressure sensor IRQ if (IRQ_TRIGGERED(int_flag, PS_INT_PIN)) { // Get data from sensor request.flag.altitude_measurement = 1; } // --------------------------------------------------- // Safe long button event detection if (button.flag.star || button.flag.num) { // Additional debounce delay to enable safe high detection - 50ms Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT)); // Check if this button event is short enough if (BUTTON_STAR_IS_PRESSED) { // Change interrupt edge to detect button release BUTTONS_IES |= BUTTON_STAR_PIN; button.flag.star = 0; // This flag is used to detect if the user released the button before the // time for a long button press (3s) button.flag.star_not_long = 1; } if (BUTTON_NUM_IS_PRESSED) { // Change interrupt edge to detect button release BUTTONS_IES |= BUTTON_NUM_PIN; button.flag.num = 0; // This flag is used to detect if the user released the button before the // time for a long button press (3s) button.flag.num_not_long = 1; } } } // Reenable PORT2 IRQ __disable_interrupt(); BUTTONS_IFG = 0x00; BUTTONS_IE = int_enable; __enable_interrupt(); // Exit from LPM3/LPM4 on RETI __bic_SR_register_on_exit(LPM4_bits); }
__interrupt void RTC_A_ISR(void) #endif { sTime.second++; if (sTime.second == 60) sTime.second = 0; static u8 button_lock_counter = 0; //gibbons TODO: need to put these just in the 1-sec interrupt section? static u8 button_beep_counter = 0; #ifdef CONFIG_CW u8 CW_Message[] = "NOON\0"; #endif switch (RTCIV) { case RTC_RT0PSIFG: // Interval timer (16384Hz - 128Hz interrupts (binary powers) ) // gibbons TODO: put stopwatch 1/100 sec interrupt here? break; case RTC_RT1PSIFG: // Interval timer (64Hz - 0.5Hz interrupts (binary powers) ) break; case RTC_RTCRDYIFG: // RTC registers ready and safe to read (Use this for 1-sec update) // Add 1 second to stored (global) time, update sTime.drawFlag appropriately clock_tick(); // Set clock update flag display.flag.update_time = 1; // While SimpliciTI stack operates or BlueRobin searches, freeze system state //pfs #ifdef ELIMINATE_BLUEROBIN if (is_rf()) #else if (is_rf() || is_bluerobin_searching()) #endif { // SimpliciTI automatic timeout if (sRFsmpl.timeout == 0) { simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; } else { sRFsmpl.timeout--; } // Exit from LPM3 on RETI _BIC_SR_IRQ(LPM3_bits); return; } // ------------------------------------------------------------------- // Service modules that require 1/min processing if (sTime.drawFlag >= 2) { // Measure battery voltage to keep track of remaining battery life request.flag.voltage_measurement = 1; // Check if alarm needs to be turned on //check_alarm(); //gibbons TODO: remove } // ------------------------------------------------------------------- // Service active modules that require 1/s processing #ifdef CONFIG_EGGTIMER if (sEggtimer.state == EGGTIMER_RUN) { eggtimer_tick(); // Subtract 1 second from eggtimer's count } if (sEggtimer.state == EGGTIMER_ALARM) { // no "else if" intentional // Decrement alarm duration counter if (sEggtimer.duration-- > 0) { request.flag.eggtimer_buzzer = 1; } else { stop_eggtimer_alarm(); // Set state to Stop and reset duration } } #endif // Generate alarm signal if (sAlarm.state == ALARM_ON) { // Decrement alarm duration counter if (sAlarm.duration-- > 0) { request.flag.alarm_buzzer = 1; } else { stop_alarm(); } } #ifdef CONFIG_PROUT if (is_prout()) prout_tick(); #endif #ifdef CONFIG_VARIO if(is_vario()) vario_tick(); #endif #ifdef CONFIG_STRENGTH // One more second gone by. if(is_strength()) { strength_tick(); } #endif // Do a temperature measurement each second while menu item is active if (is_temp_measurement()) request.flag.temperature_measurement = 1; // Do a pressure measurement each second while menu item is active #ifdef CONFIG_ALTITUDE if (is_altitude_measurement()) { // Countdown altitude measurement timeout while menu item is active sAlt.timeout--; // Stop measurement when timeout has elapsed if (sAlt.timeout == 0) { stop_altitude_measurement(); // Show ---- m/ft display_chars(LCD_SEG_L1_3_0, (u8*)"----", SEG_ON); // Clear up/down arrow display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); } // In case we missed the IRQ due to debouncing, get data now if ((PS_INT_IN & PS_INT_PIN) == PS_INT_PIN) request.flag.altitude_measurement = 1; } #endif #ifdef FEATURE_PROVIDE_ACCEL // Count down timeout if (is_acceleration_measurement()) { // Countdown acceleration measurement timeout sAccel.timeout--; // Stop measurement when timeout has elapsed if (sAccel.timeout == 0) as_stop(); // If DRDY is (still) high, request data again if ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN) request.flag.acceleration_measurement = 1; } #endif //pfs #ifndef ELIMINATE_BLUEROBIN // If BlueRobin transmitter is connected, get data from API if (is_bluerobin()) get_bluerobin_data(); #endif // If battery is low, decrement display counter if (sys.flag.low_battery) { if (sBatt.lobatt_display-- == 0) { message.flag.prepare = 1; message.flag.type_lobatt = 1; sBatt.lobatt_display = BATTERY_LOW_MESSAGE_CYCLE; } } // If a message has to be displayed, set display flag if (message.all_flags) { if (message.flag.prepare) { message.flag.prepare = 0; message.flag.show = 1; } else if (message.flag.erase) // message cycle is over, so erase it { message.flag.erase = 0; message.flag.block_line1 = 0; message.flag.block_line2 = 0; display.flag.full_update = 1; } } // ------------------------------------------------------------------- // Check idle timeout, set timeout flag if (sys.flag.idle_timeout_enabled) { if (sTime.last_activity > 0) { if (--sTime.last_activity == 0) sys.flag.idle_timeout = 1; //setFlag(sysFlag_g, SYS_TIMEOUT_IDLE); } } // ------------------------------------------------------------------- // Detect continuous button high states if (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED) { if (button_beep_counter++ > LEFT_BUTTON_LONG_TIME) { // Toggle no_beep buttons flag sys.flag.no_beep = ~sys.flag.no_beep; // Show "beep / nobeep" message synchronously with next second tick message.flag.prepare = 1; if (sys.flag.no_beep) message.flag.type_no_beep_on = 1; else message.flag.type_no_beep_off = 1; // Reset button beep counter button_beep_counter = 0; } } else if (BUTTON_NUM_IS_PRESSED && BUTTON_DOWN_IS_PRESSED) // Trying to lock/unlock buttons? { if (button_lock_counter++ > LEFT_BUTTON_LONG_TIME) { // Toggle lock / unlock buttons flag sys.flag.lock_buttons = ~sys.flag.lock_buttons; // Show "buttons are locked/unlocked" message synchronously with next second tick message.flag.prepare = 1; if (sys.flag.lock_buttons) message.flag.type_locked = 1; else message.flag.type_unlocked = 1; // Reset button lock counter button_lock_counter = 0; } } else // Trying to create a long button press? { // Reset button lock counter button_lock_counter = 0; if (BUTTON_STAR_IS_PRESSED) { sButton.star_timeout++; // Check if button was held low for some seconds if (sButton.star_timeout > LEFT_BUTTON_LONG_TIME) { button.flag.star_long = 1; sButton.star_timeout = 0; } } else { sButton.star_timeout = 0; } if (BUTTON_NUM_IS_PRESSED) { sButton.num_timeout++; // Check if button was held low for some seconds if (sButton.num_timeout > LEFT_BUTTON_LONG_TIME) { button.flag.num_long = 1; sButton.num_timeout = 0; } } else { sButton.num_timeout = 0; } } // Exit from LPM3 on RETI _BIC_SR_IRQ(LPM3_bits); //gibbons TODO: move this to other interrupts from the RTC? break; case RTC_RTCTEVIFG: // Interval alarm event (min or hour changed, or rollover to midnight or noon) (choose one) // Minute, hour, noon, or midnight rollover beep (same beep as button press, at least for now) #ifdef CONFIG_TIMECHIME #ifdef CONFIG_CW CW_Send_String(CW_Message); #else start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150)); #endif if (RTC_Toggle_12Hr) RTCCTL01 ^= 0x0100; // Toggle Time EVent between noon and midnight #endif break; case RTC_RTCAIFG: // User-configurable alarm event // Indicate that alarm is on sAlarm.state = ALARM_ON; break; } //gibbons: TODO: Remove this old code? (Associated with Timer0_A0 1-sec ISR) // Disable IE //TA0CCTL0 &= ~CCIE; // Reset IRQ flag //TA0CCTL0 &= ~CCIFG; // Add 1 sec to TACCR0 register (IRQ will be asserted at 0x7FFF and 0xFFFF = 1 sec intervals) //TA0CCR0 += 32768; //gibbons TODO: Should this perhaps be (32768 - 1) ? // Enable IE //TA0CCTL0 |= CCIE; }
__interrupt void PORT2_ISR(void) { u8 int_flag, int_enable; u8 buzzer = 0; u8 simpliciti_button_event = 0; static u8 simpliciti_button_repeat = 0; // Clear button flags button.all_flags = 0; // Remember interrupt enable bits int_enable = BUTTONS_IE; // Store valid button interrupt flag int_flag = BUTTONS_IFG & int_enable; // --------------------------------------------------- // While SimpliciTI stack is active, buttons behave differently: // - Store M1/M2/S1 button events in SimpliciTI packet data // - Exit SimpliciTI when S2 was pressed if (is_rf()) { // Erase previous button press after a number of resends (increase number if link quality is low) // This will create a series of packets containing the same button press // Necessary because we have no acknowledge // Filtering (edge detection) will be done by receiver software if (simpliciti_button_repeat++ > 6) { simpliciti_data[0] &= ~0xF0; simpliciti_button_repeat = 0; } if ((int_flag & BUTTON_M1_PIN) == BUTTON_M1_PIN) { simpliciti_data[0] |= SIMPLICITI_BUTTON_M1; simpliciti_button_event = 1; } else if ((int_flag & BUTTON_M2_PIN) == BUTTON_M2_PIN) { simpliciti_data[0] |= SIMPLICITI_BUTTON_M2; simpliciti_button_event = 1; } else if ((int_flag & BUTTON_S1_PIN) == BUTTON_S1_PIN) { simpliciti_data[0] |= SIMPLICITI_BUTTON_S1; simpliciti_button_event = 1; } else if ((int_flag & BUTTON_S2_PIN) == BUTTON_S2_PIN) { simpliciti_flag |= SIMPLICITI_TRIGGER_STOP; } // Trigger packet sending inside SimpliciTI stack if (simpliciti_button_event) simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA; } else // Normal operation { // Debounce buttons if ((int_flag & ALL_BUTTONS) != 0) { // Disable PORT2 IRQ __disable_interrupt(); BUTTONS_IE = 0x00; __enable_interrupt(); // Debounce delay 1 Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN)); // Reset inactivity detection sTime.last_activity = sTime.system_time; // Reset M button high detection sTime.previous_m_button_event = sTime.system_time; } // --------------------------------------------------- // M1 button IRQ if (IRQ_TRIGGERED(int_flag, BUTTON_M1_PIN)) { // Filter bouncing noise if (BUTTON_M1_IS_PRESSED) { button.flag.m1 = 1; sys.flag.mask_m1_button = 0; // Generate button click buzzer = 1; } } // --------------------------------------------------- // M2 button IRQ else if (IRQ_TRIGGERED(int_flag, BUTTON_M2_PIN)) { // Filter bouncing noise if (BUTTON_M2_IS_PRESSED) { button.flag.m2 = 1; sys.flag.mask_m2_button = 0; // Generate button click buzzer = 1; } } // --------------------------------------------------- // S1 button IRQ else if (IRQ_TRIGGERED(int_flag, BUTTON_S1_PIN)) { // Filter bouncing noise if (BUTTON_S1_IS_PRESSED) { button.flag.s1 = 1; // Generate button click buzzer = 1; } } // --------------------------------------------------- // S2 button IRQ else if (IRQ_TRIGGERED(int_flag, BUTTON_S2_PIN)) { // Filter bouncing noise if (BUTTON_S2_IS_PRESSED) { button.flag.s2 = 1; // Generate button click buzzer = 1; // Faster reaction for stopwatch stop button press if (is_stopwatch()) { stop_stopwatch(); button.flag.s2 = 0; } } } // --------------------------------------------------- // B/L button IRQ else if (IRQ_TRIGGERED(int_flag, BUTTON_BL_PIN)) { // Filter bouncing noise if (BUTTON_BL_IS_PRESSED) { button.flag.bl = 1; } } } // Generate button click when button was activated if (buzzer) { // Any button event stops active alarm if (sAlarm.state == ALARM_ON) { stop_alarm(); button.all_flags = 0; } else if (!sys.flag.s_button_repeat_enabled) { start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150)); } // Debounce delay 2 Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT)); } // --------------------------------------------------- // Acceleration sensor IRQ if (IRQ_TRIGGERED(int_flag, AS_INT_PIN)) { // Get data from sensor request.flag.acceleration_measurement = 1; } // --------------------------------------------------- // Pressure sensor IRQ if (IRQ_TRIGGERED(int_flag, PS_INT_PIN)) { // Get data from sensor request.flag.altitude_measurement = 1; } // --------------------------------------------------- // Enable safe long button event detection if(button.flag.m1 || button.flag.m2) { // Additional debounce delay to enable safe high detection Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_M)); // Check if this button event is short enough if (BUTTON_M1_IS_PRESSED) button.flag.m1 = 0; if (BUTTON_M2_IS_PRESSED) button.flag.m2 = 0; } // Reenable PORT2 IRQ __disable_interrupt(); BUTTONS_IFG = 0x00; BUTTONS_IE = int_enable; __enable_interrupt(); // Exit from LPM3/LPM4 on RETI __bic_SR_register_on_exit(LPM4_bits); }
// ************************************************************************************************* // @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 }
void beep_once(uint16_t d_ms) { start_buzzer(); _delay_ms(d_ms); stop_buzzer(); }
// ************************************************************************************************* // @fn cdtimer_tick // @brief Called by 1Hz clock_tick function. // Decreases cdtimer counter and triggers display update. // @param none // @return none // ************************************************************************************************* void cdtimer_tick(void) { //Make sure cdtimer is running before we do anything else if(scdtimer.state == CDTIMER_RUN) { // Draw flag minimizes display update activity // // swt.drawFlag = 1: second L // swt.drawFlag = 2: second H/L // swt.drawFlag = 3: minutes L, second H/L // swt.drawFlag = 4: minutes H/L, second H/L // swt.drawFlag = 5: hours L, minutes H/L, second H/L // swt.drawFlag = 6: hours H/L, minutes H/L, second H/L // Set always second draw flag scdtimer.drawFlag = 1; // Subtract sequentially scdtimer.time[5]--; // second L (0 - 9) if (scdtimer.time[5] == 0x2F) { scdtimer.drawFlag++; // 2 scdtimer.time[5] = '9'; scdtimer.time[4]--; // second H (0 - 5) if (scdtimer.time[4] == 0x2F) { scdtimer.drawFlag ++; // 3 scdtimer.time[4] = '5'; scdtimer.time[3]--; // minutes L (0 - 9) if (scdtimer.time[3] == 0x2F) { scdtimer.drawFlag++; // 4 scdtimer.time[3] = '9'; scdtimer.time[2]--; // minutes H (0 - 5) if (scdtimer.time[2] == 0x2F) { scdtimer.drawFlag++; // 5 scdtimer.time[2] = '5'; scdtimer.time[1]--; // hours L (0-9) if (scdtimer.time[1] == 0x2F) { scdtimer.drawFlag++; // 6 scdtimer.time[1] = '9'; scdtimer.time[0]--; // hours H (0-1) } if(scdtimer.time[0] ==0x2F) { // When we reach 0, reset and beep stop_cdtimer(); init_cdtimer(); // Refresh display display_cdtimer(LINE2, DISPLAY_LINE_UPDATE_FULL); // Option for continue if(scdtimer.mode == CDTIMER_MODE_CONTINUE) { // (Re) start cdtimer start_cdtimer(); } start_buzzer(20, CONV_MS_TO_TICKS(50), CONV_MS_TO_TICKS(150)); } } } } } } }
void start_buzzer_steps(u8 cycles, u16 on_time, u16 off_time, u8 steps ) { sBuzzer.steps = steps; start_buzzer( cycles, on_time, off_time ); }
void start_buzzer_steps(uint8_t cycles, uint16_t on_time, uint16_t off_time, uint8_t steps ) { sBuzzer.steps = steps; start_buzzer( cycles, on_time, off_time ); }