Browse Source

Merge branch 'eggtimer' of https://github.com/gibbons/OpenChronos into gibbons-eggtimer

master
Daniel Poelzleithner 11 years ago
parent
commit
9e2ebb7292
  1. 65
      README
  2. 3
      driver/display.h
  3. 13
      driver/ports.c
  4. 30
      driver/timer.c
  5. 14
      ezchronos.c
  6. 5
      include/project.h
  7. 586
      logic/eggtimer.c
  8. 67
      logic/eggtimer.h
  9. 2
      logic/menu.c
  10. 4
      tools/config.py

65
README

@ -1,54 +1,25 @@
This fork adds a variometer, an instrument indicating vertical speed,
essentially for use in free flight (paragliding, hang gliding, ...).
Initially based on the vario source coded by dkm, I ended up rewriting
that module completely.
- Pressing the "v" (down) button cycles between displays as follows:
* vario (in m/s)
Displays a signed fractional value representing the ascent or
descent speed in meters per second.
* vario (in Pascal)
Displays a signed integer value representing the ascent or
descent speed in Pascal/second.
* pressure (in hPa)
Displays a signed fraction representing the pressure measured at
the current altitude.
* max Vz (in m/s)
Displays the maximum vertical speed in meters/second.
* min Vz (in m/s)
Displays the minimum vertical speed in meters/second.
- A long press on the "#" button performs a context sensitive function:
* during vario display, changes the vario sound mode:
Off (default, no symbol displayed)
Ascent 0 (start beeping at 0.0m/s, beeper1 and beeper2 symbols
displayed)
Ascent 1 (start beeping at 0.1m/s, beeper1 symbol displayed)
Both (beep for up or down, beeper1 and beeper2 symbols
displayed)
Tone frequency, number and duration of beeps depend on climb rate.
* during max/min Vz display, resets both the max and min values.
- The "record" icon is flashed at one second intervals, indicating that
the watch is in vario mode and receiving pressure measurements.
Note that the upper line must be in altimeter mode for the vario to
work, as it relies on updates from the altimeter. If the altimeter
is not active, the vario display shows "noAlt".
Updates the eggtimer to be fully working, with a slightly reduced code-size.
== Status ==
Works, but in development :-)
Should be fully functional. Can be run concurrently with the stopwatch
without harm. Can also be run in the background (i.e. you can navigate
away from its menu and it will still run and go off at the correct time.)
The icon used for it ("R" with a circle around it) is on solid for when
its menu entry is active, and blinks when running, even if on a separate
menu (menu entry not active).
Resolution is in seconds, maximum hours is 19, max minutes is 99, and max
seconds is 99. (Note that a time of 2:90:00 == 3:30:00, since the minutes
will rollover to 59 after 90 minutes, not back up to 90 --> 2:90:00...
2:89:59...2:89:58......2:00:01...2:00:00...1:59:59...)
These updates reduce the (.elf) delta compiled codesize by about 40 bytes,
from 1524 to 1480.
== Requirements ==

3
driver/display.h

@ -92,6 +92,9 @@ typedef union
u16 update_sidereal_time : 1; // 1 = Sidereal Time was updated
#endif
u16 update_stopwatch : 1; // 1 = Stopwatch was updated
#ifdef CONFIG_EGGTIMER
u16 update_eggtimer : 1;
#endif
u16 update_temperature : 1; // 1 = Temperature was updated
u16 update_battery_voltage : 1; // 1 = Battery voltage was updated
u16 update_date : 1; // 1 = Date was updated

13
driver/ports.c

@ -60,6 +60,10 @@
#include "altitude.h"
#include "stopwatch.h"
#ifdef CONFIG_EGGTIMER
#include "eggtimer.h"
#endif
// *************************************************************************************************
// Prototypes section
@ -317,6 +321,15 @@ __interrupt void PORT2_ISR(void)
}
else
#endif
#ifdef CONFIG_EGGTIMER
if (sEggtimer.state == EGGTIMER_ALARM) {
stop_eggtimer_alarm();
button.all_flags = 0;
}
else
#endif
if (!sys.flag.up_down_repeat_enabled && !sys.flag.no_beep)
{
start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150));

30
driver/timer.c

@ -368,7 +368,7 @@ __interrupt void TIMER0_A0_ISR(void)
// If the chime is enabled, we beep here
if (sTime.minute == 0) {
if (sAlarm.hourly == ALARM_ENABLED) {
request.flag.buzzer = 1;
request.flag.alarm_buzzer = 1;
}
}
// Check if alarm needs to be turned on
@ -383,15 +383,31 @@ __interrupt void TIMER0_A0_ISR(void)
// -------------------------------------------------------------------
// Service active modules that require 1/s processing
#ifdef CONFIG_ALARM // N8VI NOTE eventually, eggtimer should use this code too
#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
#ifdef CONFIG_ALARM
// Generate alarm signal
if (sAlarm.state == ALARM_ON)
{
// Decrement alarm duration counter
if (sAlarm.duration-- > 0)
{
request.flag.buzzer = 1;
request.flag.alarm_buzzer = 1;
}
else
{
@ -652,18 +668,12 @@ __interrupt void TIMER0_A1_5_ISR(void)
// Load CCR register with next capture point
#ifdef CONFIG_STOP_WATCH
update_stopwatch_timer();
#endif
#ifdef CONFIG_EGGTIMER
update_eggtimer_timer();
#endif
// Enable timer interrupt
TA0CCTL2 |= CCIE;
// Increase stopwatch counter
#ifdef CONFIG_STOP_WATCH
stopwatch_tick();
#endif
#ifdef CONFIG_EGGTIMER
eggtimer_tick();
#endif
break;

14
ezchronos.c

@ -407,9 +407,7 @@ void init_global_variables(void)
#endif
#ifdef CONFIG_EGGTIMER
//Set Eggtimer to a 5 minute default
memcpy(seggtimer.defaultTime, "00010000", sizeof(seggtimer.time));
reset_eggtimer();
init_eggtimer(); // Initialize eggtimer
#endif
#ifdef CONFIG_PROUT
@ -590,11 +588,17 @@ void process_requests(void)
if (request.flag.voltage_measurement) battery_measurement();
#endif
#ifdef CONFIG_ALARM // N8VI NOTE eggtimer may want in on this
#ifdef CONFIG_ALARM
// Generate alarm (two signals every second)
if (request.flag.buzzer) start_buzzer(2, BUZZER_ON_TICKS, BUZZER_OFF_TICKS);
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)
{

5
include/project.h

@ -121,7 +121,10 @@ typedef union
u16 altitude_accumulator : 1; // 1 = Measure altitude & accumulate it
#endif
u16 acceleration_measurement : 1; // 1 = Measure acceleration
u16 buzzer : 1; // 1 = Output buzzer for alarm
u16 alarm_buzzer : 1; // 1 = Output buzzer for alarm
#ifdef CONFIG_EGGTIMER
u16 eggtimer_buzzer : 1; // 1 = Output buzzer for eggtimer
#endif
#ifdef CONFIG_STRENGTH
u16 strength_buzzer : 1; // 1 = Output buzzer from strength_data
#endif

586
logic/eggtimer.c

@ -32,18 +32,18 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// *************************************************************************************************
// eggtimer functions.
// Eggtimer feature
// *************************************************************************************************
// *************************************************************************************************
// Include section
// system
#include "project.h"
#include "config.h" //gibbons: bit of a hack: forces next ifdef statement to work
#ifdef CONFIG_EGGTIMER
#include "project.h"
#include <string.h>
// driver
@ -56,20 +56,22 @@
// logic
#include "menu.h"
#include "eggtimer.h"
// *************************************************************************************************
// Prototypes section
void init_eggtimer(void);
void start_eggtimer(void);
void stop_eggtimer(void);
void reset_eggtimer(void);
void stop_eggtimer_alarm(void);
void set_eggtimer_to_defaults(void);
void set_eggtimer(void);
void eggtimer_tick(void);
void update_eggtimer_timer(void);
void mx_eggtimer(u8 line);
void sx_eggtimer(u8 line);
void display_eggtimer(u8 line, u8 update);
extern void set_eggtimer(void);
u8 eggtimer_visible(void);
// *************************************************************************************************
// Defines section
@ -77,273 +79,216 @@ extern void set_eggtimer(void);
// *************************************************************************************************
// Global Variable section
struct eggtimer seggtimer;
struct eggtimer sEggtimer;
// *************************************************************************************************
// Extern section
extern void menu_skip_next(line_t line); // in ezchronos.c
// *************************************************************************************************
// @fn update_eggtimer_timer
// @brief Set new compare time for next 1/1Hz or 1/100Hz interrupt. Takes care for exact 1 second timing.
// @param ticks (1 tick = 1/32768 sec)
// @fn init_eggtimer
// @brief Initialize eggtimer; intended to be called once, on firmware restart
// @param none
// @return none
// *************************************************************************************************
void update_eggtimer_timer(void)
void init_eggtimer()
{
//Make sure eggtimer is running before we do anything else (this might slightly mess up my timing, but oh well)
if(seggtimer.state == EGGTIMER_RUN){
u16 value;
// Load CCR register with next capture time
if (seggtimer.viewStyle == DISPLAY_DEFAULT_VIEW)
{
// Timer interrupts occur every 32768/100 = 328 ACLK
// --> eggtimer runs too slow (1 sec nominal != 100 interupts * 328 ACLK = 32800 ACLK = 1.00098 sec)
// --> ideally correct timer value every 10 ticks by (32768 - 32800)/10 = 3.2
// --> correct timer value every 10Hz by 3,
// --> correct timer value every 1Hz correct by 5
value = TA0CCR2 + EGGTIMER_100HZ_TICK;
if (seggtimer.swtIs1Hz)
{
value -= 5;
seggtimer.swtIs1Hz = 0;
seggtimer.swtIs10Hz = 0;
}
else if (seggtimer.swtIs10Hz)
{
value -= 3;
seggtimer.swtIs10Hz = 0;
}
}
else // Alternative view
{
// Timer interrupts occur every 32768/1 = 32768 ACLK
value = TA0CCR2 + EGGTIMER_1HZ_TICK;
}
// Update CCR
TA0CCR2 = value;
}
sEggtimer.state = EGGTIMER_STOP;
sEggtimer.duration = EGGTIMER_ALARM_DURATION;
// Set eggtimer default to 1 minute
sEggtimer.default_hours = 0;
sEggtimer.default_minutes = 1;
sEggtimer.default_seconds = 0;
set_eggtimer_to_defaults();
}
// *************************************************************************************************
// @fn eggtimer_tick
// @brief Called by 1/100Hz interrupt handler.
// Decreases eggtimer counter and triggers display update.
// @fn start_eggtimer
// @brief Sets eggtimer state to on, draws eggtimer icon blinking
// @param none
// @return none
// *************************************************************************************************
void eggtimer_tick(void)
void start_eggtimer(void)
{
//Make sure eggtimer is running before we do anything else (this might slightly mess up my timing, but oh well)
if(seggtimer.state == EGGTIMER_RUN){
static u8 delay = 0;
// Default view (< 20 minutes): display and count MM:SS:hh
if (seggtimer.viewStyle == DISPLAY_DEFAULT_VIEW)
{
// Add 1/100 sec
seggtimer.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)
{
seggtimer.drawFlag = 8;
delay = 0;
}
// Subtract 1/10 sec
if (seggtimer.time[7] == 0x2F)
{
seggtimer.time[7]='9';
seggtimer.time[6]--;
// 1/10Hz trigger
seggtimer.swtIs10Hz = 1;
// Update draw flag
seggtimer.drawFlag = 7;
}
}
else // Alternative view (20 minutes .. 20 hours): display and count HH:MM:SS
{
// Just subtract 1 second
seggtimer.time[6] = 0x2F;
}
// Second overflow?
if (seggtimer.time[6] == 0x2F)
{
// Reset draw flag
seggtimer.drawFlag = 1;
// Set eggtimer run flag
sEggtimer.state = EGGTIMER_RUN;
// 1Hz trigger
seggtimer.swtIs1Hz = 1;
// Subtract sequentially
seggtimer.time[6]='9';
seggtimer.time[5]--; // second L (0 - 9)
if (seggtimer.time[5] == 0x2F)
{
seggtimer.drawFlag++; // 2
seggtimer.time[5] = '9';
seggtimer.time[4]--; // second H (0 - 5)
if (seggtimer.time[4] == 0x2F)
{
seggtimer.drawFlag ++; // 3
seggtimer.time[4] = '5';
seggtimer.time[3]--; // minutes L (0 - 9)
if (seggtimer.time[3] == 0x2F)
{
seggtimer.drawFlag++; // 4
seggtimer.time[3] = '9';
seggtimer.time[2]--; // minutes H (0 - 5)
if (seggtimer.time[0]=='0'&&
seggtimer.time[1]=='0'&&
seggtimer.time[2]< '2')
{
// SWT display changes from HH:MM:SS to MM:SS:hh when reaching 20 minutes
seggtimer.viewStyle = DISPLAY_DEFAULT_VIEW;
display_eggtimer(LINE2, DISPLAY_LINE_UPDATE_FULL);
}
if (seggtimer.time[2] == 0x2F)
{
seggtimer.drawFlag++; // 5
seggtimer.time[2] = '5';
seggtimer.time[1]--; // hours L (0-9)
if (seggtimer.time[1] == 0x2F)
{
seggtimer.drawFlag++; // 6
seggtimer.time[1] = '9';
seggtimer.time[0]--; // hours H (0-1)
}
if(seggtimer.time[0] ==0x2F)
{
// When we reach 0, stop, reset, and beep (not able to stop beeping yet)
stop_eggtimer();
reset_eggtimer();
display_eggtimer(LINE2, DISPLAY_LINE_UPDATE_FULL);
start_buzzer(100, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150));
}
}
}
}
}
}
// Always set display update flag (Only used in two places for no good reason, but whatever)
//seggtimer.update_eggtimer = 1;
display.flag.update_stopwatch = 1;
}
// Set eggtimer icon (doesn't exist so I wont untill I'll use stopwatch for now)
display_symbol(LCD_ICON_RECORD, SEG_ON_BLINK_ON);
}
// *************************************************************************************************
// @fn reset_eggtimer
// @brief Clears eggtimer counter and sets eggtimer state to off.
// @fn stop_eggtimer
// @brief Sets eggtimer state to off, but doesn't reset eggtimer count.
// Also draws eggtimer icon (solid on, no blink)
// @param none
// @return none
// *************************************************************************************************
void reset_eggtimer(void)
{
// Clear counter
memcpy(seggtimer.time, seggtimer.defaultTime, sizeof(seggtimer.time));
// Clear trigger
seggtimer.swtIs10Hz = 0; // 1/10Hz trigger
seggtimer.swtIs1Hz = 0; // 1Hz trigger
// Init eggtimer state 'Off'
seggtimer.state = EGGTIMER_STOP;
void stop_eggtimer(void)
{
// Clear eggtimer run flag
sEggtimer.state = EGGTIMER_STOP;
// Default display style is MM:SS:HH
if(seggtimer.defaultTime[0]=='0'&&
seggtimer.defaultTime[1]=='0'&&
seggtimer.defaultTime[2]<'2')
seggtimer.viewStyle = DISPLAY_DEFAULT_VIEW;
else
seggtimer.viewStyle = DISPLAY_ALTERNATIVE_VIEW;
// Clear eggtimer icon (doesn't exist so I'll use stopwatch for now)
display_symbol(LCD_ICON_RECORD, SEG_ON_BLINK_OFF); // Assumes the eggtimer menu is active
}
// *************************************************************************************************
// @fn is_eggtimer
// @brief Is eggtimer operating and visible?
// @fn stop_eggtimer_alarm
// @brief Puts eggtimer in STOP mode, halts alarm mode and buzzing if active, updates eggtimer
// symbol. Safe to call, even if eggtimer menu not active.
// @param none
// @return 1=EGGTIMER_RUN, 0=other states
// @return none
// *************************************************************************************************
u8 is_eggtimer(void)
void stop_eggtimer_alarm(void)
{
return ((seggtimer.state == EGGTIMER_RUN) && (ptrMenu_L2 == &menu_L2_Eggtimer));
sEggtimer.state = EGGTIMER_STOP;
sEggtimer.duration = EGGTIMER_ALARM_DURATION;
if (eggtimer_visible()) {
display_symbol(LCD_ICON_RECORD, SEG_ON_BLINK_OFF);
}
else {
display_symbol(LCD_ICON_RECORD, SEG_OFF_BLINK_OFF);
}
stop_buzzer(); // FIXME: needs to play friendly with other buzzer-using modules (e.g. alarm)
}
// *************************************************************************************************
// @fn start_eggtimer
// @brief Starts eggtimer timer interrupt and sets eggtimer state to on.
// @fn set_eggtimer_to_defaults
// @brief Clears eggtimer counter; DOES NOT set state to EGGTIMER_STOP! (This way, this
// function can be called without stopping the alarm.)
// @param none
// @return none
// *************************************************************************************************
void start_eggtimer(void)
void set_eggtimer_to_defaults(void)
{
// Set eggtimer run flag
seggtimer.state = EGGTIMER_RUN;
// Init CCR register with current time
TA0CCR2 = TA0R;
// Load CCR register with next capture time
update_eggtimer_timer();
// Reset IRQ flag
TA0CCTL2 &= ~CCIFG;
// Enable timer interrupt
TA0CCTL2 |= CCIE;
// Reset eggtimer counts to default (aka last used) values
sEggtimer.hours = sEggtimer.default_hours;
sEggtimer.minutes = sEggtimer.default_minutes;
sEggtimer.seconds = sEggtimer.default_seconds;
// Set eggtimer icon (doesn't exist so I wont untill I'll use stopwatch for now)
display_symbol(LCD_ICON_RECORD, SEG_ON);
if (eggtimer_visible()) {
display.flag.line2_full_update = 1; // gibbons: this is hardcoded to line 2; change?
}
}
// *************************************************************************************************
// @fn stop_eggtimer
// @brief Stops eggtimer timer interrupt and sets eggtimer state to off.
// Does not reset eggtimer count.
// @fn set_eggtimer
// @brief Set's the eggtimer. (Almost entirely copied from the alarm section
// @param none
// @return none
// *************************************************************************************************
void stop_eggtimer(void)
{
// Clear timer interrupt enable
TA0CCTL2 &= ~CCIE;
extern void set_eggtimer(void){
u8 select;
s32 hours; // must be s32 to work properly with set_value(...)
s32 minutes;
s32 seconds;
u8 * str;
// Store hours, minutes, and seconds in local variables
hours = sEggtimer.hours;
minutes = sEggtimer.minutes;
seconds = sEggtimer.seconds;
// Display HH:MM:SS (LINE2)
str = itoa(hours, 2, 0);
display_chars(LCD_SEG_L2_5_4, str, SEG_ON);
str = itoa(minutes, 2, 0);
display_chars(LCD_SEG_L2_3_2, str, SEG_ON);
str = itoa(seconds, 2, 0);
display_chars(LCD_SEG_L2_1_0, str, SEG_ON);
// Clear eggtimer run flag
seggtimer.state = EGGTIMER_STOP;
// Init value index
select = 0;
// Loop values until all are set or user breaks set
while(1)
{
// Idle timeout: exit without saving
if (sys.flag.idle_timeout) break;
// M2 (short): save, then exit
if (button.flag.num)
{
if ((hours == 0) && (minutes == 0) && (seconds == 0)) { //prevent zero time
seconds = 1;
}
// Store local variables in global Eggtimer default and counters
sEggtimer.hours = sEggtimer.default_hours = hours;
sEggtimer.minutes = sEggtimer.default_minutes = minutes;
sEggtimer.seconds = sEggtimer.default_seconds = seconds;
break;
}
switch (select)
{
case 0: // Set hours
set_value(&hours, 2, 0, 0, 19, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_5_4, display_value1);
select = 1;
break;
case 1: // Set minutes
set_value(&minutes, 2, 0, 0, 99, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_3_2, display_value1);
select = 2;
break;
case 2: // Set seconds
set_value(&seconds, 2, 0, 0, 99, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_1_0, display_value1);
select = 0;
break;
}
}
// Clear eggtimer icon (doesn't exist so I'll use stopwatch for now)
display_symbol(LCD_ICON_RECORD, SEG_OFF);
// Clear button flag
button.all_flags = 0;
}
// Call draw routine immediately
display_eggtimer(LINE2, DISPLAY_LINE_UPDATE_FULL);
// *************************************************************************************************
// @fn eggtimer_tick
// @brief To be called every second; decreases eggtimer counter and sets display update flag.
// @param none
// @return none
// *************************************************************************************************
void eggtimer_tick(void) //gibbons: This function could benefit from an alarm queue...
{
if (sEggtimer.state != EGGTIMER_RUN) return;
//sEggtimer.drawFlag == 1 --> seconds changed
//sEggtimer.drawFlag == 2 --> minutes also changed
//sEggtimer.drawFlag == 3 --> hours also changed
sEggtimer.drawFlag = 1;
display.flag.update_eggtimer = 1;
// gibbons: Is it possible to merge the if and else if blocks into one?
if ((sEggtimer.hours == 0) && (sEggtimer.minutes == 0) && (sEggtimer.seconds == 1)) {
// Die Zeit ist um! Time's up!
sEggtimer.state = EGGTIMER_ALARM;
set_eggtimer_to_defaults(); // Set values to defaults, so user can see what time duration just timed out
}
else if (sEggtimer.seconds-- == 0) { // NOTE: intentionally sEggtimer.seconds--, and not --sEggtimer.seconds
sEggtimer.seconds = 59;
sEggtimer.drawFlag++;
// Subtract a minute from the remaining time
if (sEggtimer.minutes-- == 0) {
sEggtimer.minutes = 59;
sEggtimer.drawFlag++;
// Subtract an hour from the remaining time
sEggtimer.hours--;
}
}
}
@ -358,16 +303,14 @@ void mx_eggtimer(u8 line)
// Stop eggtimer
stop_eggtimer();
//Set eggtimer
// Reset eggtimer count to default values
set_eggtimer_to_defaults();
// Set eggtimer
set_eggtimer();
// Reset eggtimer count
reset_eggtimer();
// Display eggtimer time
display_eggtimer(line, DISPLAY_LINE_UPDATE_FULL);
}
@ -379,171 +322,86 @@ void mx_eggtimer(u8 line)
// *************************************************************************************************
void sx_eggtimer(u8 line)
{
// S2: RUN, STOP
if(button.flag.down)
if (sEggtimer.state == EGGTIMER_STOP)
{
if (seggtimer.state == EGGTIMER_STOP)
{
// (Re)start eggtimer
start_eggtimer();
}
else
{
// Stop eggtimer
stop_eggtimer();
}
// (Re)start eggtimer
start_eggtimer();
}
else
{
// Stop eggtimer
stop_eggtimer();
}
}
// *************************************************************************************************
// @fn display_eggtimer
// @brief eggtimer user routine. Sx starts/stops eggtimer, but does not reset count.
// @param u8 line LINE2
// u8 update DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_UPDATE_FULL
// @brief eggtimer user routine.
// @param u8 line LINE2
// u8 update DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_UPDATE_FULL
// @return none
// *************************************************************************************************
void display_eggtimer(u8 line, u8 update)
{
u8 * str;
// Partial line update only
if (update == DISPLAY_LINE_UPDATE_PARTIAL)
{
// if (seggtimer.update_eggtimer)
if (display.flag.update_stopwatch)
{
// Check draw flag to minimize workload
switch(sEggtimer.drawFlag)
{
if (seggtimer.viewStyle == DISPLAY_DEFAULT_VIEW)
{
// Display MM:SS:hh
// Check draw flag to minimize workload
if(seggtimer.drawFlag != 0)
{
switch(seggtimer.drawFlag)
{
case 4: display_char(LCD_SEG_L2_5, seggtimer.time[2], SEG_ON);
case 3: display_char(LCD_SEG_L2_4, seggtimer.time[3], SEG_ON);
case 2: display_char(LCD_SEG_L2_3, seggtimer.time[4], SEG_ON);
case 1: display_char(LCD_SEG_L2_2, seggtimer.time[5], SEG_ON);
case 7: display_char(LCD_SEG_L2_1, seggtimer.time[6], SEG_ON);
case 8: display_char(LCD_SEG_L2_0, seggtimer.time[7], SEG_ON);
}
}
}
else // DISPLAY_ALTERNATIVE_VIEW
{
// Display HH:MM:SS
switch(seggtimer.drawFlag)
{
case 6: display_char(LCD_SEG_L2_5, seggtimer.time[0], SEG_ON);
case 5: display_char(LCD_SEG_L2_4, seggtimer.time[1], SEG_ON);
case 4: display_char(LCD_SEG_L2_3, seggtimer.time[2], SEG_ON);
case 3: display_char(LCD_SEG_L2_2, seggtimer.time[3], SEG_ON);
case 2: display_char(LCD_SEG_L2_1, seggtimer.time[4], SEG_ON);
case 1: display_char(LCD_SEG_L2_0, seggtimer.time[5], SEG_ON);
}
}
case 3: // Hours changed
str = itoa(sEggtimer.hours, 2, 0);
display_chars(LCD_SEG_L2_5_4, str, SEG_ON);
case 2: // Minutes changed
str = itoa(sEggtimer.minutes, 2, 0);
display_chars(LCD_SEG_L2_3_2, str, SEG_ON);
case 1: // Seconds changed
str = itoa(sEggtimer.seconds, 2, 0);
display_chars(LCD_SEG_L2_1_0, str, SEG_ON);
}
sEggtimer.drawFlag = 0; // Clear draw flag
}
// Redraw whole line
else if (update == DISPLAY_LINE_UPDATE_FULL)
{
if (seggtimer.viewStyle == DISPLAY_DEFAULT_VIEW)
{
// Display MM:SS:hh
display_chars(LCD_SEG_L2_5_0, seggtimer.time+2, SEG_ON);
}
else // DISPLAY_ALTERNATIVE_VIEW
{
// Display HH:MM:SS
display_chars(LCD_SEG_L2_5_0, seggtimer.time, SEG_ON);
}
// Display HH:MM:SS
str = itoa(sEggtimer.hours, 2, 0);
display_chars(LCD_SEG_L2_5_4, str, SEG_ON);
str = itoa(sEggtimer.minutes, 2, 0);
display_chars(LCD_SEG_L2_3_2, str, SEG_ON);
str = itoa(sEggtimer.seconds, 2, 0);
display_chars(LCD_SEG_L2_1_0, str, SEG_ON);
display_symbol(LCD_SEG_L2_COL1, SEG_ON);
display_symbol(LCD_SEG_L2_COL0, SEG_ON);
if (sEggtimer.state != EGGTIMER_STOP) { // Blink if running or alarm triggered
display_symbol(LCD_ICON_RECORD, SEG_ON_BLINK_ON);
}
else { // Solid on if not running
display_symbol(LCD_ICON_RECORD, SEG_ON_BLINK_OFF);
}
}
else if (update == DISPLAY_LINE_CLEAR)
{
// Clean up symbols when leaving function
// Stop blinking icon only if eggtimer isn't running
if (sEggtimer.state == EGGTIMER_STOP) display_symbol(LCD_ICON_RECORD, SEG_OFF);
}
}
// *************************************************************************************************
// @fn set_eggtimer
// @brief Set's the eggtimer. (Almost entirely copied from the alarm section
// @fn eggtimer_visible
// @brief Is eggtimer visible?
// @param none
// @return none
// @return 1=Eggtimer menu currently visible, 0=menu not visible
// *************************************************************************************************
extern void set_eggtimer(void){
u8 select;
s32 hours;
s32 minutes;
s32 seconds;
u8 * str;
//Get hours, minutes, and seconds into interger form
hours = (seggtimer.defaultTime[0]-48)*10 + (seggtimer.defaultTime[1]-48);
minutes = (seggtimer.defaultTime[2]-48)*10 + (seggtimer.defaultTime[3]-48);
seconds = (seggtimer.defaultTime[4]-48)*10 + (seggtimer.defaultTime[5]-48);
// Display HH:MM:SS (LINE2)
str = itoa(hours, 2, 0);
display_chars(LCD_SEG_L2_5_4, str, SEG_ON);
display_symbol(LCD_SEG_L2_COL0, SEG_ON);
str = itoa(minutes, 2, 0);
display_chars(LCD_SEG_L2_3_2, str, SEG_ON);
str = itoa(seconds, 2, 0);
display_chars(LCD_SEG_L2_1_0, str, SEG_ON);
// Init value index
select = 0;
// Loop values until all are set or user breaks set
while(1)
{
// Idle timeout: exit without saving
if (sys.flag.idle_timeout) break;
// M2 (short): save, then exit
if (button.flag.num)
{
// Store local variables in global Eggtimer default
//sAlarm.hour = hours;
//sAlarm.minute = minutes;
seggtimer.defaultTime[0]=*itoa(hours, 2, 0);
seggtimer.defaultTime[1]=*itoa(hours, 1, 0);
seggtimer.defaultTime[2]=*itoa(minutes, 2, 0);
seggtimer.defaultTime[3]=*itoa(minutes, 1, 0);
seggtimer.defaultTime[4]=*itoa(seconds, 2, 0);
seggtimer.defaultTime[5]=*itoa(seconds, 1, 0);
//Set display update flag
display.flag.line2_full_update = 1;
break;
}
switch (select)
{
case 0: // Set hours
set_value(&hours, 2, 0, 0, 19, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_5_4, display_value1);
select = 1;
break;
case 1: // Set minutes
set_value(&minutes, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_3_2, display_value1);
select = 2;
break;
case 2: // Set seconds
set_value(&seconds, 2, 0, 0, 59, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_1_0, display_value1);
select = 0;
break;
}
}
// Clear button flag
button.all_flags = 0;
u8 eggtimer_visible(void)
{
return (ptrMenu_L2 == &menu_L2_Eggtimer); // gibbons: currently hardcoded to Line2; change?
}
#endif // CONFIG_EGGTIMER
#endif //ifdef CONFIG_EGGTIMER

67
logic/eggtimer.h

@ -32,20 +32,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// *************************************************************************************************
//
// Eggtimer is currently just a copy of stopwatch.
// I'm going to be turning it into a count down timer.
//
// TO DO:
// Make sure it doesn't interfere with stopwatch
// (timer.c causing weird things especially relating to alt mode)
// (do NOT run both eggtimer and stopwatch at the same time)
// (this is because Stopwatch and Eggtimer both use the same Capture & Compare Register)
// Figure out why I have to use the stopwatch display update flag.
// Set it so stopwatch and eggtimer blink their respective icons when selected
// this prevents confusion as to which is currently selected.
// Change beeping so user can stop it at will, instead of having to wait.
// *************************************************************************************************
#ifndef eggtimer_H_
#define eggtimer_H_
@ -54,66 +40,53 @@
// Include section
#include <project.h>
#ifdef CONFIG_EGGTIMER
// *************************************************************************************************
// Prototypes section
extern void init_eggtimer(void);
extern void start_eggtimer(void);
extern void stop_eggtimer(void);
extern void reset_eggtimer(void);
extern u8 is_eggtimer(void);
extern void stop_eggtimer_alarm(void);
extern void set_eggtimer_to_defaults(void);
extern void set_eggtimer(void);
extern void eggtimer_tick(void);
extern void update_eggtimer_timer(void);
extern void mx_eggtimer(u8 line);
extern void sx_eggtimer(u8 line);
extern void display_eggtimer(u8 line, u8 update);
extern void set_eggtimer(void);
extern u8 eggtimer_visible(void);
// *************************************************************************************************
// Defines section
#define EGGTIMER_1HZ_TICK (32768/1)
#define EGGTIMER_100HZ_TICK (32768/100)
#define EGGTIMER_STOP (0u)
#define EGGTIMER_RUN (1u)
#define EGGTIMER_HIDE (2u)
#define EGGTIMER_ALARM (2u)
#define EGGTIMER_ALARM_DURATION (10u)
// *************************************************************************************************
// Global Variable section
struct eggtimer
{
//NOTE: u8 means unsigned char
u8 state;
u8 drawFlag;
u8 swtIs1Hz;
u8 swtIs10Hz;
u8 state;
u8 drawFlag;
// time[0] hour H
// time[1] hour L
// time[2] minute H
// time[3] minute L
// time[4] second H
// time[5] second L
// time[6] 1/10 sec
// time[7] 1/100 sec
u8 time[8];
// Values that are decremented each second
u8 hours;
u8 minutes;
u8 seconds;
// Display style
u8 viewStyle;
//Default Eggtimer time
u8 defaultTime[8];
//eggtimer update flag
u16 update_eggtimer : 1; // 1 = Eggtimer was updated
// Values to default to, after timer runs out and is cleared
u8 default_hours;
u8 default_minutes;
u8 default_seconds;
u8 duration; //Number of times to request buzzer double-beep when time is up
};
extern struct eggtimer seggtimer;
extern struct eggtimer sEggtimer;
// *************************************************************************************************
// Extern section
#endif // CONFIG_EGGTIMER
#endif /*eggtimer_H_*/

2
logic/menu.c

@ -151,7 +151,7 @@ u8 update_acceleration(void)
#ifdef CONFIG_EGGTIMER
u8 update_eggtimer(void)
{
return (display.flag.update_stopwatch);
return (display.flag.update_eggtimer);
}
#endif

4
tools/config.py

@ -112,10 +112,10 @@ DATA["TEXT_MODULES"] = {
#### MODULES ####
DATA["CONFIG_EGGTIMER"] = {
"name": "Eggtimer (1524 bytes)",
"name": "Eggtimer (1480 bytes)",
"depends": [],
"default": False,
"help": "Countdown timer to count down from 1 minute - 20 hours to 0 and start an alarm",
"help": "Countdown timer for intervals from seconds up to 20+ hours.",
}
DATA["CONFIG_PHASE_CLOCK"] = {

Loading…
Cancel
Save