Browse Source

add patches form Niek Lambert

* Added fixpointer version of altitude calculation.
when the two remaining filters get fixpointer replacments, a LOT of space gets free by not using floatpointer anywhere.
the fixpointer versions are also smaller in size.
* better display of weekday
* show time also in second line
* force gcc to not optimize anything in delay intrinsic

thanks a lot
master
Lambert, Niek 12 years ago committed by Daniel Poelzleithner
parent
commit
37c10e28b9
  1. 45
      driver/display1.c
  2. 177
      driver/vti_ps.c
  3. 6
      driver/vti_ps.h
  4. 28
      gcc/intrinsics.c
  5. 3
      include/project.h
  6. 1
      logic/acceleration.c
  7. 7
      logic/altitude.c
  8. 271
      logic/date.c
  9. 2
      logic/date.h
  10. 2
      makefile
  11. 7
      tools/config.py

45
driver/display1.c

@ -59,6 +59,11 @@
// Global Variable section
// Table with memory bit assignment for digits "0" to "9" and characters "A" to "Z"
// A
// F B
// G
// E C
// D
const u8 lcd_font[] =
{
SEG_A+SEG_B+SEG_C+SEG_D+SEG_E+SEG_F, // Displays "0"
@ -71,41 +76,39 @@ const u8 lcd_font[] =
SEG_A+SEG_B+SEG_C, // Displays "7"
SEG_A+SEG_B+SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "8"
SEG_A+SEG_B+SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "9"
0 , // Displays " "
0 , // Displays " "
0 , // Displays " "
0 , // Displays " "
0 , // Displays " "
SEG_D+SEG_E+ SEG_G, // Displays "c"
0 , // Displays " "
0 , // Displays " " (:)
0 , // Displays " " (;)
SEG_A+ SEG_F+SEG_G, // Displays "<" as high c
SEG_D+ SEG_G, // Displays "="
0 , // Displays " " (>)
SEG_A+SEG_B+ SEG_E+ SEG_G, // Displays "?"
0 , // Displays " " (@)
SEG_A+SEG_B+SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "A"
SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "b"
SEG_A+ SEG_D+SEG_E+SEG_F , // Displays "C"
SEG_D+SEG_E+ SEG_G, // Displays "c"
SEG_B+SEG_C+SEG_D+SEG_E+ SEG_G, // Displays "d"
SEG_A+ +SEG_D+SEG_E+SEG_F+SEG_G, // Displays "E"
SEG_A+ SEG_E+SEG_F+SEG_G, // Displays "F"
// SEG_A+ SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "G"
SEG_A+SEG_B+SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "g"
SEG_B+SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "H"
SEG_E+SEG_F , // Displays "I"
SEG_A+ SEG_E+SEG_F+SEG_G, // Displays "f"
SEG_A+SEG_B+SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "g" same as 9
SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "h"
SEG_E , // Displays "i"
SEG_A+SEG_B+SEG_C+SEG_D , // Displays "J"
// SEG_B+SEG_C+ SEG_E+SEG_F+SEG_G, // Displays "k"
SEG_D+SEG_E+SEG_F+SEG_G, // Displays "k"
SEG_D+ SEG_F+SEG_G, // Displays "k"
SEG_D+SEG_E+SEG_F , // Displays "L"
SEG_A+SEG_B+SEG_C+ SEG_E+SEG_F , // Displays "M"
SEG_C+ SEG_E+ SEG_G, // Displays "n"
SEG_C+SEG_D+SEG_E+ SEG_G, // Displays "o"
SEG_A+SEG_B+ SEG_E+SEG_F+SEG_G, // Displays "P"
SEG_A+SEG_B+SEG_C+SEG_D+SEG_E+SEG_F , // Displays "Q"
SEG_A+SEG_B+SEG_C+ SEG_F+SEG_G, // Displays "q"
SEG_E+ SEG_G, // Displays "r"
SEG_A+ SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "S"
SEG_A+ SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "S" same as 5
SEG_D+SEG_E+SEG_F+SEG_G, // Displays "t"
SEG_C+SEG_D+SEG_E , // Displays "u"
SEG_C+SEG_D+SEG_E , // Displays "u"
SEG_G, // Displays "-"
SEG_B+SEG_C+ +SEG_E+SEG_F+SEG_G, // Displays "X"
SEG_C+SEG_D+SEG_E , // Displays "v" same as u
SEG_B+SEG_C+SEG_D+SEG_E+SEG_F+SEG_G, // Displays "W"
SEG_B+SEG_C+ +SEG_E+SEG_F+SEG_G, // Displays "X" as H
SEG_B+SEG_C+SEG_D+ SEG_F+SEG_G, // Displays "Y"
SEG_A+SEG_B+ SEG_D+SEG_E+ SEG_G, // Displays "Z"
SEG_A+SEG_B+ SEG_D+SEG_E+ SEG_G, // Displays "Z" same as 2
};

177
driver/vti_ps.c

@ -45,6 +45,9 @@
// driver
#include "vti_ps.h"
#include "timer.h"
#ifdef FIXEDPOINT
#include "dsp.h"
#endif
// *************************************************************************************************
@ -62,10 +65,18 @@ void twi_delay(void);
// *************************************************************************************************
// Global Variable section
#ifndef FIXEDPOINT
// VTI pressure (hPa) to altitude (m) conversion tables
const s16 h0[17] = { -153, 0, 111, 540, 989, 1457, 1949, 2466, 3012, 3591, 4206, 4865, 5574, 6344, 7185, 8117, 9164 };
const u16 p0[17] = { 1031, 1013, 1000, 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300 };
float p[17];
#else
// Storage for pressure to altitude conversions
static s16 pLast; // Last measured pressure in 4Pa units
static s16 pRef; // Reference pressure at sea level in 4Pa units
static s16 hLast; // Last altitude estimate in normalized units b/H0/2^15
#endif
// Global flag for proper pressure sensor operation
u8 ps_ok;
@ -435,7 +446,6 @@ u16 ps_get_temp(void)
return (kelvin);
}
// *************************************************************************************************
// @fn init_pressure_table
// @brief Init pressure table with constants
@ -444,11 +454,67 @@ u16 ps_get_temp(void)
// *************************************************************************************************
void init_pressure_table(void)
{
#ifndef FIXEDPOINT
u8 i;
for (i=0; i<17; i++) p[i] = p0[i];
#else
pLast = 101325/4; // Last measured pressure in 4Pa units
pRef = 101325/4; // Reference pressure at sea level in 4Pa units
hLast = 0;
#endif
}
#ifdef FIXEDPOINT
// *************************************************************************************************
// @fn conv_altitude_to_fraction
// @brief Relative pressure deviation from reference pressure for given altitude estimate.
// @param s16 hh Altitude estimate (in normalised units).
// @return Calculated relative pressure deviation for this altitude
// *************************************************************************************************
s16 conv_altitude_to_fraction(s16 hh)
{
/*
The fixed part of the function of altitude can be broken into tabulated ranges
and/or interpolated according to a Taylor series expansion
(1 - f) = (1 h/H0)^b
= 1 - h*b/H0 + h^2*b*(b1)/2/H0^2 h^3*b8(b1)*(b-2)/6/H0^3 +
At low altitudes h/H0 << 1, so this series tends to converge rapidly and is
well-suited for fixed point implementation. With one or two additional terms
the series converges accurately over the range of interest so there is no need
for table interpolation. For the proposed fixed point implementation we rewrite
this expression a bit into
hh = b*h/H0
(1 - f) = (1 h/H0)^b
= 1 - hh*(1 hh*(b1)/2/b*(1 hh*(b2)/3/b*(...
We stick to integer multiply and shift operations. Signed s16 values can contain
values +/2^15 and unsigned u16 values 0..2^16. In C multiplication amounts to
expanding to s32, integer multiply and scaling back by a proper shift operation.
Given the above equations the natural unit of hh as the first order correction is
H0/b = 8434.48m. If we accept this as a maximum +/ range we can store s16 hh in
units of (H0/b)/2^15 = 0,26m which keeps the resolution at less than a foot.
*/
s16 f, hf;
// f = hh*(b – 4)/5/b, correction relevant above 3.5km:
// (Could be omitted, but it is relatively little work.)
f = mult_scale16(hh, 3132);
// f = hh*(b – 3)/4/b*(1 - f), correction relevant above 1.3km:
hf = mult_scale16(hh, 7032);
f = hf - mult_scale15(hf,f);
// f = hh*(b – 2)/3/b*(1 - f), correction relevant above 300m:
hf = mult_scale16(hh, 13533);
f = hf - mult_scale15(hf,f);
// f = hh*(b – 1)/2/b*(1 - f), correction relevant above 30m:
hf = mult_scale16(hh, 26533);
f = hf - mult_scale15(hf,f);
// f = hh*(1 - f), the linear part:
f = hh - mult_scale15(hh,f);
return f;
}
#endif // FIXEDPOINT
// *************************************************************************************************
// @fn update_pressure_table
@ -461,6 +527,7 @@ void init_pressure_table(void)
// *************************************************************************************************
void update_pressure_table(s16 href, u32 p_meas, u16 t_meas)
{
#ifndef FIXEDPOINT
const float Invt00 = 0.003470415;
const float coefp = 0.00006;
volatile float p_fact;
@ -495,9 +562,29 @@ void update_pressure_table(s16 href, u32 p_meas, u16 t_meas)
{
p[i] = p0[i]*p_fact;
}
#else
// Note: a user-provided sea-level reference pressure in mbar as used by pilots
// would be straightforward: href = 0; p_meas = (s32)mbar*100;
// The altitude reading will be iteratively updated.
// Convert to 4Pa units:
pLast = (s16)((p_meas+2) >> 2);
// Convert reference altitude to normalized units:
if (sys.flag.use_metric_units) { // user_altitude in m
hLast = 4*href - mult_scale16(href, 7536);
} else { // user_altitude in ft
hLast = href + mult_scale16(href,12068);
}
s32 f = (s32)0x8000 - conv_altitude_to_fraction(hLast);
// pRef = p_meas*2^15/f:
pRef = ((((s32)pLast << 16) + f) >> 1) / f;
// The long division is acceptable because it happens rarely.
// The term + f) is for proper rounding.
// The <<16 and >>1 operations correct for the 15bit scale of f.
#endif
}
#ifndef FIXEDPOINT
// *************************************************************************************************
// @fn conv_pa_to_meter
// @brief Convert pressure (Pa) to altitude (m) using a conversion table
@ -551,3 +638,89 @@ s16 conv_pa_to_meter(u32 p_meas, u16 t_meas)
return (h);
}
#else
// *************************************************************************************************
// @fn conv_pressure_to_altitude
// @brief Calculates altitude from current pressure, and
// stored reference pressure at sea level and previous altitude estimate.
// Temperature info is ignored.
// @param u32 p_meas Pressure (Pa)
// @param u16 t_meas Temperature (10*°K) Ignored !!!
// @return Estimated altitude in user-selected unit (m or ft)
// (internally filtered, slightly sluggish).
// *************************************************************************************************
s16 conv_pa_to_altitude(u32 p_meas, u16 t_meas)
{
/*
Assumption: fixed, linear T(h)
T = T0 dTdh*h
with
T0 = 288.15K (15C)
dTdh = 6.5mK/m
Basic differential equation:
dh = -(R/G)*T(H)*dp/p
Solution:
H = H0*(1 (p/pRef)^a)
with
H0 = T0/dTdh = 44330.77m
pRef = adjustable reference pressure at sea level (h=0).
a = dTdH*R/G = 0.190263
R = 287.052m^2/s^2/K
G = 9.80665 (at medium latitude)
We assume T0 and the temperature profile to be fixed; the temperature reading
of the watch is not very useful since it is strongly influenced by body heat,
clothing, shelter, etc.
Straight evaluation of h(p) requires an unattractive long division p/pRef
with pRef the adjustable reference pressure, and the Taylor expansion does
not converge very quickly.
Evaluation of p(h) requires a more attractive multiplication by the
user-adjustable reference pressure pRef:
f =(1 h/H0)^b
p = pRef*f
with
b = 1/a = G/(dTdH*R) = 5.255896
In a very crude linear iteration the h value can be updated by
delta_h = delta_p / dpdh
The slope dpdh varies by about a factor two over the range of interest,
but we can pick a fixed value on the safe side and accept that the updates
are a bit more damped at higher altitudes.
The sensor provides 19bit absolute pressure in units of 0.25Pa, but that is more
resolution than we can easily handle in the multiplications. We store measured
pressure p, reference pressure pRef and calculated pressure as u16 in units of 4Pa.
In the units chosen for p (4Pa) and for hLast (see function conv_altitude_to_fraction),
the slope dpdh is about -0.75 at sea level down to -0.375 at high altitudes. To avoid
overshoot and instabilities we assume a bigger value and accept a minor amount of
extra filtering delay at higher altitudes. The factor 1/0.75 is approximated by 1.
*/
// Scale to 4Pa units:
s16 p = (s16)((p_meas+2) >> 2);
// Predictor to speed up response to pressure changes:
// hLast -= p - pLast; // Factor of about 1/0.75 would be better.
// Store current pressure for next predictor:
pLast = p;
// Calculate pressure ratio based on guessed altitude (serious DSP work):
s16 f = conv_altitude_to_fraction(hLast);
// Calculate pressure expected for guessed height
u16 pCalculated = pRef - mult_scale15(pRef,f);
// This calculation is correct within about 7Pa.
// We still have to reverse the solution with a linearly improved guess:
hLast -= p - pCalculated;
// Iteration gain factor of about 1/0.75 would result in faster convergence,
// but even the big initial jump when the altimeter is switched on converges
// in some 5 or 6 steps to about 1m accuracy.
if (sys.flag.use_metric_units) {
// Altitude in meters (correct within about 0.7m):
return mult_scale16(hLast, 16869);
} else {
// Altitude in feet (correct within 1.5ft):
return mult_scale15(hLast, 27672);
}
}
#endif // FIXEDPOINT

6
driver/vti_ps.h

@ -47,10 +47,14 @@ extern void ps_start(void);
extern void ps_stop(void);
extern u32 ps_get_pa(void);
extern u16 ps_get_temp(void);
extern void init_pressure_table(void);
extern void update_pressure_table(s16 href, u32 p_meas, u16 t_meas);
#ifndef FIXEDPOINT
extern s16 conv_pa_to_meter(u32 p_meas, u16 t_meas);
#else
extern s16 conv_pa_to_altitude(u32 p_meas, u16 t_meas);
#endif
// *************************************************************************************************
// Defines section

28
gcc/intrinsics.c

@ -15,28 +15,28 @@
void __delay_cycles(unsigned long __cycles)
{
// divide by eight
asm("clrc");
asm("rra.w %[src]"
asm volatile("clrc");
asm volatile("rra.w %[src]"
: [src] "=r" (__cycles)
: "[src]" (__cycles) );
asm("clrc");
asm("rra.w %[src]"
asm volatile("clrc");
asm volatile("rra.w %[src]"
: [src] "=r" (__cycles)
: "[src]" (__cycles) );
asm("clrc");
asm("rra.w %[src]"
asm volatile("clrc");
asm volatile("rra.w %[src]"
: [src] "=r" (__cycles)
: "[src]" (__cycles) );
asm("DelayLoop:");
asm("nop"); // add nops to increase loop to eight clock cycles
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("dec.w %[src]"
asm volatile("DelayLoop:");
asm volatile("nop"); // add nops to increase loop to eight clock cycles
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("dec.w %[src]"
: [src] "=r" (__cycles)
: "[src]" (__cycles));
asm("jne DelayLoop");
asm volatile("jne DelayLoop");
}
//__set_interrupt_state used in bsp_msp430_defs.h, rf1a.c

3
include/project.h

@ -77,6 +77,9 @@
// *************************************************************************************************
// Typedef section
typedef u8 line_t;
typedef u8 update_t;
typedef enum
{
MENU_ITEM_NOT_VISIBLE = 0, // Menu item is not visible

1
logic/acceleration.c

@ -237,6 +237,7 @@ void display_acceleration(u8 line, u8 update)
}
accel_data = convert_acceleration_value_to_mgrav(raw_data) / 10;
// FIXME: find a FIXEDPOINTER way
// Filter acceleration
accel_data = (u16)((accel_data * 0.2) + (sAccel.data * 0.8));

7
logic/altitude.c

@ -235,6 +235,7 @@ void do_altitude_measurement(u8 filter)
else
{
// Filter current pressure
// FIXME: find a FIXEDPOINTER way
pressure = (u32)((pressure * 0.2) + (sAlt.pressure * 0.8));
// Store average pressure
@ -242,7 +243,11 @@ void do_altitude_measurement(u8 filter)
}
// Convert pressure (Pa) and temperature (?K) to altitude (m)
sAlt.altitude = conv_pa_to_meter(sAlt.pressure, sAlt.temperature);
#ifdef FIXEDPOINT
sAlt.altitude = conv_pa_to_altitude(sAlt.pressure, sAlt.temperature);
#else
sAlt.altitude = conv_pa_to_meter(sAlt.pressure, sAlt.temperature);
#endif
}

271
logic/date.c

@ -50,15 +50,14 @@
#include "date.h"
#include "user.h"
// *************************************************************************************************
// Prototypes section
void reset_date(void);
u8 get_numberOfDays(u8 month, u16 year);
void add_day(void);
void mx_date(u8 line);
void sx_date(u8 line);
void display_date(u8 line, u8 update);
void mx_date(line_t line);
void sx_date(line_t line);
void display_date(line_t line, update_t update);
// *************************************************************************************************
@ -72,8 +71,8 @@ struct date sDate;
// *************************************************************************************************
// Extern section
extern void (*fptr_lcd_function_line1)(u8 line, u8 update);
extern void (*fptr_lcd_function_line2)(u8 line, u8 update);
extern void (*fptr_lcd_function_line1)(line_t line, update_t update);
extern void (*fptr_lcd_function_line2)(line_t line, update_t update);
// *************************************************************************************************
@ -89,8 +88,8 @@ void reset_date(void)
sDate.month = 8;
sDate.day = 1;
// Show day and month on display
sDate.display = DISPLAY_DEFAULT_VIEW;
// Show default display
sDate.view = 0;
}
@ -159,9 +158,8 @@ void add_day(void)
sDate.year++;
}
}
// Indicate to display function that new value is available
display.flag.full_update = 1;
display.flag.update_date = 1;
}
@ -171,7 +169,7 @@ void add_day(void)
// @param line LINE1, LINE2
// @return none
// *************************************************************************************************
void mx_date(u8 line)
void mx_date(line_t line)
{
u8 select;
s32 day;
@ -179,7 +177,6 @@ void mx_date(u8 line)
s32 year;
s16 max_days;
u8 * str;
u8 * str1;
// Clear display
clear_display_all();
@ -193,26 +190,14 @@ void mx_date(u8 line)
select = 0;
// Init display
// LINE1: DD.MM (metric units) or MM.DD (English units)
// LINE2: YYYY (will be drawn by set_value)
// LINE1: YYYY (will be drawn by set_value)
// LINE2: MM DD
if (sys.flag.use_metric_units)
{
str = itoa(day, 2, 0);
display_chars(LCD_SEG_L1_3_2, str, SEG_ON);
str1 = itoa(month, 2, 0);
display_chars(LCD_SEG_L1_1_0, str1, SEG_ON);
}
else // English units
{
str = itoa(day, 2, 0);
display_chars(LCD_SEG_L1_1_0, str, SEG_ON);
str = itoa(day, 2, 0);
display_chars(LCD_SEG_L2_1_0, str, SEG_ON);
str1 = itoa(month, 2, 0);
display_chars(LCD_SEG_L1_3_2, str1, SEG_ON);
}
display_symbol(LCD_SEG_L1_DP1, SEG_ON);
str = itoa(month, 2, 0);
display_chars(LCD_SEG_L2_5_4, str, SEG_ON);
// Loop values until all are set or user breaks set
while(1)
@ -235,29 +220,15 @@ void mx_date(u8 line)
switch (select)
{
case 0: // Set year
set_value(&year, 4, 0, 2008, 2100, SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_3_0, display_value1);
set_value(&year, 4, 0, 2008, 2100, SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_0, display_value1);
select = 1;
break;
case 1: // Set month
if (sys.flag.use_metric_units)
{
set_value(&month, 2, 0, 1, 12, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value1);
}
else // English units
{
set_value(&month, 2, 0, 1, 12, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_value1);
}
set_value(&month, 2, 1, 1, 12, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_5_4, display_value1);
select = 2;
break;
case 2: // Set day
if (sys.flag.use_metric_units)
{
set_value(&day, 2, 0, 1, max_days, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_3_2, display_value1);
}
else // English units
{
set_value(&day, 2, 0, 1, max_days, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L1_1_0, display_value1);
}
set_value(&day, 2, 1, 1, max_days, SETVALUE_ROLLOVER_VALUE + SETVALUE_DISPLAY_VALUE + SETVALUE_NEXT_VALUE, LCD_SEG_L2_1_0, display_value1);
select = 0;
break;
}
@ -278,140 +249,122 @@ void mx_date(u8 line)
// @param line LINE1, LINE2
// @return none
// *************************************************************************************************
void sx_date(u8 line)
void sx_date(line_t line)
{
// Toggle display items
if (sDate.display == DISPLAY_DEFAULT_VIEW)
sDate.display = DISPLAY_ALTERNATIVE_VIEW;
#ifdef CONFIG_DAY_OF_WEEK
else if (sDate.display == DISPLAY_ALTERNATIVE_VIEW)
sDate.display = DISPLAY_ALTERNATIVE2_VIEW;
#endif
else
sDate.display = DISPLAY_DEFAULT_VIEW;
// Rotate through 4 views
if (++sDate.view >= 4) sDate.view = 0;
}
// *************************************************************************************************
// @fn display_date
// @brief Display date in DD.MM format (metric units) or MM.DD (English units).
// @param u8 line LINE1, LINE2
// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_UPDATE_PARTIAL
// @param line_t line LINE1, LINE2
// update_t update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_UPDATE_PARTIAL
// @return none
// *************************************************************************************************
void display_date(u8 line, u8 update)
void display_date(line_t line, update_t update)
{
u8 *str;
#ifdef CONFIG_DAY_OF_WEEK
const u8 weekDayStr[7][3] = {"SUN","MON","TUE","WED","THU","FRI","SAT"};
#endif
u8 * str;
if (update == DISPLAY_LINE_UPDATE_FULL)
if (update == DISPLAY_LINE_UPDATE_FULL)
{
if (sDate.display == DISPLAY_DEFAULT_VIEW)
switch (sDate.view)
{
// Convert day to string
str = itoa(sDate.day, 2, 0);
if (sys.flag.use_metric_units)
{
display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON);
}
else
{
case 0: //WWW.DD
// Convert day to string
#ifdef CONFIG_DAY_OF_WEEK
str = itoa(sDate.day, 2, 1);
display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON);
}
// Convert month to string
str = itoa(sDate.month, 2, 0);
if (sys.flag.use_metric_units)
{
display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON);
}
else
{
display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON);
}
// Display "." to separate day and month
display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON);
}
#ifdef CONFIG_DAY_OF_WEEK
else if(sDate.display == DISPLAY_ALTERNATIVE2_VIEW)
{
//pfs BEGIN replace year display with day of week
//pfs algorith from http://klausler.com/new-dayofweek.html
#define BASE_YEAR 2001 // not a leap year, so no need to add 1
u8 skew;
skew = (sDate.year - BASE_YEAR)+(sDate.year - BASE_YEAR)/4; // compute number of leap years since BASE_YEAR
if ((29 == get_numberOfDays(2, sDate.year)) && (sDate.month < 3))
skew--; // if this is a leap year but before February 29
skew = skew%7;
skew = (skew + sDate.day)%7; // add day of current month
//add this month's skew value
switch(sDate.month) {
case 5:
skew += 1;
break;
case 8:
skew += 2;
//pfs BEGIN replace year display with day of week
//pfs algorith from http://klausler.com/new-dayofweek.html
#define BASE_YEAR 2001 // not a leap year, so no need to add 1
u8 skew;
skew = (sDate.year - BASE_YEAR)+(sDate.year - BASE_YEAR)/4; // compute number of leap years since BASE_YEAR
if ((29 == get_numberOfDays(2, sDate.year)) && (sDate.month < 3))
skew--; // if this is a leap year but before February 29
skew = (skew + sDate.day); // add day of current month
//add this month's skew value
switch(sDate.month) {
case 5:
skew += 1;
break;
case 8:
skew += 2;
break;
case 2:
case 3:
case 11:
skew += 3;
break;
case 6:
skew += 4;
break;
case 9:
case 12:
skew += 5;
break;
case 4:
case 7:
skew += 6;
break;
default: //January and October
break;
}
skew = skew%7;
str = (u8 *)weekDayStr[skew];
display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_4_2), str, SEG_ON);
display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON);
break;
case 2:
case 3:
case 11:
skew += 3;
break;
case 6:
skew += 4;
break;
case 9:
case 12:
skew += 5;
#else
// skip this view
sDate.view++;
#endif
case 1: //MM DD
// Convert day to string
display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_ON);
// display date
#ifndef CONFIG_METRIC_ONLY
if (!sys.flag.use_metric_units) {
str = itoa(sDate.day, 2, 0);
display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON);
// Convert month to string
str = itoa(sDate.month, 2, 1);
display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON);
} else {
#else
if (1) {
#endif
str = itoa(sDate.day, 2, 0);
display_chars(switch_seg(line, LCD_SEG_L1_3_2, LCD_SEG_L2_3_2), str, SEG_ON);
str = itoa(sDate.month, 2, 0);
display_chars(switch_seg(line, LCD_SEG_L1_1_0, LCD_SEG_L2_1_0), str, SEG_ON);
}
break;
case 4:
case 7:
skew += 6;
case 2: //YYYY
// Convert year to string
str = itoa(sDate.year, 4, 0);
display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_3_0), str, SEG_ON);
break;
default: //January and October
default:
display_time(line, update);
break;
}
skew = skew%7;
switch (skew) {
case 0:
str = (u8*)" SUN"; break;
case 1:
str = (u8*)" MON"; break;
case 2:
str = (u8*)" TUE"; break;
case 3:
str = (u8*)"VVED"; break;
case 4:
str = (u8*)" THU"; break;
case 5:
str = (u8*)" FRI"; break;
default:
str = (u8*)" SAT"; break;
}
//str = itoa(skew,4,0);
// pfs END of day of week addendum
// Convert year to string
//pfs str = itoa(sDate.year, 4, 0);
display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_3_0), str, SEG_ON);
// Clear "."
display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_OFF);
}
#endif //CONFIG_DAY_OF_WEEK
else
{
// Convert year to string
str = itoa(sDate.year, 4, 0);
display_chars(switch_seg(line, LCD_SEG_L1_3_0, LCD_SEG_L2_3_0), str, SEG_ON);
// Clear "."
display_symbol(switch_seg(line, LCD_SEG_L1_DP1, LCD_SEG_L2_DP), SEG_OFF);
}
}
else if (update == DISPLAY_LINE_UPDATE_PARTIAL)
{
if ((sDate.view == 3) || (display.flag.update_date))
display_date(line, DISPLAY_LINE_UPDATE_FULL);
}
else if (update == DISPLAY_LINE_CLEAR)
{
// Show day and month on display when coming around next time
sDate.display = DISPLAY_DEFAULT_VIEW;
// Show default display when coming around next time
sDate.view = 0;
}
}

2
logic/date.h

@ -58,7 +58,7 @@ extern void display_date(u8 line, u8 update);
// Global Variable section
struct date
{
u8 display;
u8 view;
u8 day;
u8 month;
u16 year;

2
makefile

@ -23,7 +23,7 @@ LOGIC_SOURCE = logic/acceleration.c logic/alarm.c logic/altitude.c logic/battery
LOGIC_O = $(addsuffix .o,$(basename $(LOGIC_SOURCE)))
DRIVER_SOURCE = driver/adc12.c driver/buzzer.c driver/display.c driver/display1.c driver/pmm.c driver/ports.c driver/radio.c driver/rf1a.c driver/timer.c driver/vti_as.c driver/vti_ps.c
DRIVER_SOURCE = driver/adc12.c driver/buzzer.c driver/display.c driver/display1.c driver/pmm.c driver/ports.c driver/radio.c driver/rf1a.c driver/timer.c driver/vti_as.c driver/vti_ps.c driver/dsp.c
DRIVER_O = $(addsuffix .o,$(basename $(DRIVER_SOURCE)))

7
tools/config.py

@ -46,6 +46,13 @@ DATA["CONFIG_METRIC_ONLY"] = {
"help": "Only add code for Metric units (meter/celsius) to reduce image size",
}
DATA["FIXEDPOINT"] = {
"name": "Fixedpoint",
"depends": [],
"default": False,
"help": "Tries to use fix point aritmetric. If no module is using it, it reduces the code size dramaticly",
}
DATA["THIS_DEVICE_ADDRESS"] = {
"name": "Hardware address",
"type": "text",

Loading…
Cancel
Save