// ************************************************************************************************* // @fn stop_stopwatch // @brief Stops stopwatch timer interrupt and sets stopwatch state to off. // Does not reset stopwatch count. // @param none // @return none // ************************************************************************************************* void stop_stopwatch(void) { if(StopwatchMode == MODE_STOPTIMER) { // Clear timer interrupt enable TA0CCTL2 &= ~CCIE; // Clear stopwatch run flag sStopwatch.state = STOPWATCH_STOP; // Clear stopwatch icon display_symbol(LCD_ICON_STOPWATCH, SEG_OFF); } else // MODE_LAPTIMER { if(LAP_TimeFlag == LAP_RUNNING) { // Save LAP time memcpy(LAP_Time, sStopwatch.time, sizeof(LAP_Time)); LAP_TimeFlag = LAP_CATCHED; } else // LAP_CATCHED { LAP_TimeFlag = LAP_RUNNING; } } // Call draw routine immediately display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_FULL); }
/* * Called by the main loop to increment stopwatch or process a pressed key */ int stopwatch_callback(int key) { unsigned long currentTicker; if(StopWatchStatus.running) { currentTicker=getTicker(); StopWatch=currentTicker-FirstTicker; TotalStopWatch=currentTicker-TotalFirstTicker; StopWatchKeyticks=0; } else if(StopWatchKeyticks >= STOPWATCH_APD_TICKS) { KeyCallback=(int(*)(int)) NULL; return K_HEARTBEAT; } if(key!=K_HEARTBEAT && key!=K_RELEASE) { StopWatchKeyticks=0; if(StopWatchStatus.select_memory_mode || StopWatchStatus.rcl_mode) { process_select_memory_key(key); } else { process_stopwatch_key(key); } } display_stopwatch(); if(RclMemory>=0 && RclMemoryRemanentDisplay++ > RCL_MEMORY_REMANENCE) { StopWatchStatus.sigma_display_mode=0; RclMemory=-1; } return K_HEARTBEAT; }
// ************************************************************************************************* // @fn mx_stopwatch // @brief Stopwatch set routine. Mx stops stopwatch and resets count. // @param u8 line LINE2 // @return none // ************************************************************************************************* void mx_stopwatch(u8 line) { // Stop stopwatch stop_stopwatch(); // Reset stopwatch count reset_stopwatch(); // Display "00:00:00" display_stopwatch(line, DISPLAY_LINE_UPDATE_FULL); }
// ************************************************************************************************* // @fn Timer0_A4_Delay // @brief Wait for some microseconds // @param ticks (1 tick = 1/32768 sec) // @return none // ************************************************************************************************* void Timer0_A4_Delay(u16 ticks) { u16 value = 0; // Exit immediately if Timer0 not running - otherwise we'll get stuck here if ((TA0CTL & (BIT4 | BIT5)) == 0) return; // Disable timer interrupt TA0CCTL4 &= ~CCIE; // Clear delay_over flag sys.flag.delay_over = 0; // Add delay to current timer value // To make sure this value is correctly read while (value != TA0R) value = TA0R; value += ticks; // Update CCR TA0CCR4 = value; // Reset IRQ flag TA0CCTL4 &= ~CCIFG; // Enable timer interrupt TA0CCTL4 |= CCIE; // Wait for timer IRQ while (1) { // Delay in LPM to_lpm(); // will also set GIE again #ifdef USE_WATCHDOG // Service watchdog WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; #endif // Redraw stopwatch display if (is_stopwatch()) display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_PARTIAL); // Check stop condition // disable interrupt to prevent flag's change caused by interrupt methods __disable_interrupt(); if (sys.flag.delay_over) break; } __enable_interrupt(); }
// ************************************************************************************************* // @fn stop_stopwatch // @brief Stops stopwatch timer interrupt and sets stopwatch state to off. // Does not reset stopwatch count. // @param none // @return none // ************************************************************************************************* void stop_stopwatch(void) { // Clear timer interrupt enable TA0CCTL2 &= ~CCIE; // Clear stopwatch run flag sStopwatch.state = STOPWATCH_STOP; // Clear stopwatch icon display_symbol(LCD_ICON_STOPWATCH, SEG_OFF); // Call draw routine immediately display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_FULL); }
// ************************************************************************************************* // @fn mx_stopwatch // @brief Stopwatch set routine. Mx stops stopwatch and resets count. // @param u8 line LINE2 // @return none // ************************************************************************************************* void mx_stopwatch(u8 line) { // Stop stopwatch stop_stopwatch(); // Reset stopwatch count init_stopwatch(); LAP_TimeFlag = LAP_CATCHED; // Set mode set_stopwatchmode(); // Display "00:00:00" display_stopwatch(line, DISPLAY_LINE_UPDATE_FULL); }
// ************************************************************************************************* // @fn Timer0_A4_Delay // @brief Wait for some microseconds // @param ticks (1 tick = 1/32768 sec) // @return none // ************************************************************************************************* void Timer0_A4_Delay(u16 ticks) { u16 value; // Exit immediately if Timer0 not running - otherwise we'll get stuck here if ((TA0CTL & (BIT4 | BIT5)) == 0) return; // Disable timer interrupt TA0CCTL4 &= ~CCIE; // Clear delay_over flag sys.flag.delay_over = 0; // Add delay to current timer value value = TA0R + ticks; // Update CCR TA0CCR4 = value; // Reset IRQ flag TA0CCTL4 &= ~CCIFG; // Enable timer interrupt TA0CCTL4 |= CCIE; // Wait for timer IRQ while (1) { // Delay in LPM to_lpm(); #ifdef USE_WATCHDOG // Service watchdog WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL; #endif // Redraw stopwatch display if (is_stopwatch()) display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_PARTIAL); // Redraw countdown display if (is_countdown_active()) display_countdown(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); // Redraw countup display if (is_countup_active()) display_countup(LINE2, DISPLAY_LINE_UPDATE_PARTIAL); // Check stop condition if (sys.flag.delay_over) break; } }
// ************************************************************************************************* // @fn stopwatch_tick // @brief Called by 1/100Hz interrupt handler. // Increases stopwatch counter and triggers display update. // @param none // @return none // ************************************************************************************************* void stopwatch_tick(void) { static u8 delay = 0; // Default view (< 20 minutes): display and count MM:SS:hh if (sStopwatch.viewStyle == DISPLAY_DEFAULT_VIEW) { // Add 1/100 sec sStopwatch.time[7]++; // 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 // swt.drawFlag = 7: 1/10 sec, 1/100 sec // swt.drawFlag = 8: 1/100 sec (every 17/100 sec to reduce display draw activity) if (delay++ > 17) { sStopwatch.drawFlag = 8; delay = 0; } // Add 1/10 sec if (sStopwatch.time[7] == 0x3A) { sStopwatch.time[7] = '0'; sStopwatch.time[6]++; // 1/10Hz trigger sStopwatch.swtIs10Hz = 1; // Update draw flag sStopwatch.drawFlag = 7; } } else // Alternative view (20 minutes .. 20 hours): display and count // HH:MM:SS { // Just add 1 second sStopwatch.time[6] = 0x3A; } // Second overflow? if (sStopwatch.time[6] == 0x3A) { // Reset draw flag sStopwatch.drawFlag = 1; // 1Hz trigger sStopwatch.swtIs1Hz = 1; // Add data sStopwatch.time[6] = '0'; sStopwatch.time[5]++; // second L (0 - 9) if (sStopwatch.time[5] == 0x3A) { sStopwatch.drawFlag++; // 2 sStopwatch.time[5] = '0'; sStopwatch.time[4]++; // second H (0 - 5) if (sStopwatch.time[4] == '6') { sStopwatch.drawFlag++; // 3 sStopwatch.time[4] = '0'; sStopwatch.time[3]++; // minutes L (0 - 9) if (sStopwatch.time[3] == 0x3A) { sStopwatch.drawFlag++; // 4 sStopwatch.time[3] = '0'; sStopwatch.time[2]++; // minutes H (0 - 5) if (sStopwatch.time[2] == '2') { // SWT display changes from MM:SS:hh to HH:MM:SS when reaching 20 minutes sStopwatch.viewStyle = DISPLAY_ALTERNATIVE_VIEW; display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_FULL); } else if (sStopwatch.time[2] == '6') { sStopwatch.drawFlag++; // 5 sStopwatch.time[2] = '0'; sStopwatch.time[1]++; // hours L (0-9) if (sStopwatch.time[1] == 0x3A) { sStopwatch.drawFlag++; // 6 sStopwatch.time[1] = '0'; sStopwatch.time[0]++; // hours H (0-1) if (sStopwatch.time[0] == '2') { // When reaching 20 hours, start over reset_stopwatch(); sStopwatch.state = STOPWATCH_RUN; display_stopwatch(LINE2, DISPLAY_LINE_UPDATE_FULL); } } } } } } } // Always set display update flag display.flag.update_stopwatch = 1; }