Marc 13 years ago
parent
commit
fe862ac2cf
  1. 6
      README
  2. 2
      driver/timer.c
  3. 8
      ezchronos.c
  4. 8
      logic/altitude.c
  5. 12
      logic/menu.c
  6. 2
      logic/menu.h
  7. 6
      logic/rfsimpliciti.c
  8. 8
      logic/test.c
  9. 131
      tools/config.py

6
README

@ -45,8 +45,12 @@ It is HIGHLY suggested to make a clean build before you flash the image with:
.../msp430/bin/ld: region `text' overflowed by 13250 bytes
collect2: ld returned 1 exit status
Your image is simply to large and will not fit into the flash. Try to disable some code with make config and try again :-)
or
section .vectors loaded at [0000ff80,0000ffff] overlaps section .data loaded at [0000ff4e,0000ffcb]
Your image is simply to large and will not fit into the flash. Try to disable some modules with make config and try again
Or even better, send some patches that reduce code size ;-)
== Difference to the TI Firmware ==

2
driver/timer.c

@ -350,6 +350,7 @@ __interrupt void TIMER0_A0_ISR(void)
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
@ -369,6 +370,7 @@ __interrupt void TIMER0_A0_ISR(void)
// 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
// Count down timeout
if (is_acceleration_measurement())

8
ezchronos.c

@ -364,7 +364,9 @@ void init_global_variables(void)
reset_stopwatch();
// Reset altitude measurement
#ifdef CONFIG_ALTITUDE
reset_altitude_measurement();
#endif
// Reset acceleration measurement
reset_acceleration();
@ -556,7 +558,9 @@ void process_requests(void)
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
// Do acceleration measurement
if (request.flag.acceleration_measurement) do_acceleration_measurement();
@ -728,7 +732,9 @@ void read_calibration_values(void)
simpliciti_ed_address[1] = sMyROMAddress.addr[1];
simpliciti_ed_address[2] = sMyROMAddress.addr[2];
simpliciti_ed_address[3] = sMyROMAddress.addr[3];
#ifdef CONFIG_ALTITUDE
sAlt.altitude_offset = 0;
#endif
}
else
{
@ -746,6 +752,7 @@ void read_calibration_values(void)
simpliciti_ed_address[2] = cal_data[8];
simpliciti_ed_address[3] = cal_data[9];
// S/W version byte set during calibration?
#ifdef CONFIG_ALTITUDE
if (cal_data[12] != 0xFF)
{
sAlt.altitude_offset = (s16)((cal_data[10] << 8) + cal_data[11]);;
@ -754,6 +761,7 @@ void read_calibration_values(void)
{
sAlt.altitude_offset = 0;
}
#endif
}
}

8
logic/altitude.c

@ -42,6 +42,8 @@
// system
#include "project.h"
#ifdef CONFIG_ALTITUDE
// driver
#include "altitude.h"
#include "display.h"
@ -219,7 +221,7 @@ void do_altitude_measurement(u8 filter)
// If sensor is not ready, skip data read
if ((PS_INT_IN & PS_INT_PIN) == 0) return;
// Get temperature (format is *10°K) from sensor
// Get temperature (format is *10?K) from sensor
sAlt.temperature = ps_get_temp();
// Get pressure (format is 1Pa) from sensor
@ -239,7 +241,7 @@ void do_altitude_measurement(u8 filter)
sAlt.pressure = pressure;
}
// Convert pressure (Pa) and temperature (°K) to altitude (m)
// Convert pressure (Pa) and temperature (?K) to altitude (m)
sAlt.altitude = conv_pa_to_meter(sAlt.pressure, sAlt.temperature);
}
@ -447,3 +449,5 @@ void display_altitude(u8 line, u8 update)
display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF);
}
}
#endif // CONFIG_ALTITUDE

12
logic/menu.c

@ -164,8 +164,19 @@ const struct menu menu_L1_Temperature =
FUNCTION(mx_temperature), // sub menu function
FUNCTION(display_temperature), // display function
FUNCTION(update_temperature), // new display data
#ifdef CONFIG_ALTITUDE
&menu_L1_Altitude,
#else
#ifdef ELIMINATE_BLUEROBIN
&menu_L1_Acceleration,
#else
&menu_L1_Heartrate,
#endif
#endif
};
#ifdef CONFIG_ALTITUDE
// Line1 - Altitude
const struct menu menu_L1_Altitude =
{
@ -180,6 +191,7 @@ const struct menu menu_L1_Altitude =
&menu_L1_Heartrate,
#endif
};
#endif
//pfs
#ifndef ELIMINATE_BLUEROBIN

2
logic/menu.h

@ -72,7 +72,9 @@ struct menu
// Line1 navigation
extern const struct menu menu_L1_Time;
extern const struct menu menu_L1_Alarm;
#ifdef CONFIG_ALTITUDE
extern const struct menu menu_L1_Altitude;
#endif
extern const struct menu menu_L1_Temperature;
extern const struct menu menu_L1_Altitude;
extern const struct menu menu_L1_Heartrate;

6
logic/rfsimpliciti.c

@ -587,8 +587,10 @@ void start_simpliciti_sync(void)
as_stop();
// Get updated altitude
#ifdef CONFIG_ALTITUTDE
start_altitude_measurement();
stop_altitude_measurement();
#endif
// Get updated temperature
temperature_measurement(FILTER_OFF);
@ -681,8 +683,10 @@ void simpliciti_sync_decode_ap_cmd_callback(void)
sTemp.offset = offset;
sTemp.degrees = t1;
// Set altitude
#ifdef CONFIG_ALTITUDE
sAlt.altitude = (s16)((simpliciti_data[12]<<8) + simpliciti_data[13]);
update_pressure_table(sAlt.altitude, sAlt.pressure, sAlt.temperature);
#endif
break;
case SYNC_AP_CMD_GET_MEMORY_BLOCKS_MODE_1:
@ -747,8 +751,10 @@ void simpliciti_sync_get_data_callback(unsigned int index)
simpliciti_data[9] = sAlarm.minute;
simpliciti_data[10] = sTemp.degrees >> 8;
simpliciti_data[11] = sTemp.degrees & 0xFF;
#ifdef CONFIG_ALTITUDE
simpliciti_data[12] = sAlt.altitude >> 8;
simpliciti_data[13] = sAlt.altitude & 0xFF;
#endif
break;
case SYNC_ED_TYPE_MEMORY:

8
logic/test.c

@ -87,7 +87,7 @@ void test_mode(void)
Timer0_Stop();
// Disable LCD charge pump while in standby mode
// This reduces current consumption by ca. 5µA to ca. 10µA
// This reduces current consumption by ca. 5?A to ca. 10?A
LCDBVCTL = 0;
// Show welcome screen
@ -152,6 +152,7 @@ void test_mode(void)
while (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED);
break;
case 1: // Altitude measurement
#ifdef CONFIG_ALTITUDE
display_altitude(LINE1, DISPLAY_LINE_UPDATE_FULL);
for (i=0; i<2; i++)
{
@ -160,6 +161,7 @@ void test_mode(void)
display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);
}
stop_altitude_measurement();
#endif
break;
case 2: // Temperature measurement
display_temperature(LINE1, DISPLAY_LINE_UPDATE_FULL);
@ -239,7 +241,7 @@ void test_mode(void)
// Hold watchdog
WDTCTL = WDTPW + WDTHOLD;
// Sleep until button is pressed (ca. 4µA current consumption)
// Sleep until button is pressed (ca. 4?A current consumption)
_BIS_SR(LPM4_bits + GIE);
__no_operation();
@ -281,4 +283,4 @@ void display_all_on(void)
}
#endif // CONFIG_TEST
#endif // CONFIG_TEST

131
tools/config.py

@ -25,47 +25,62 @@ DATA["CONFIG_FREQUENCY"] = {
"values": [902, 869, 433]}
DATA["CONFIG_METRIC_ONLY"] = {
"name": "Metric only code (saves space)",
"name": "Metric only code",
"depends": [],
"default": False
"default": False,
"help": "Only add code for Metric units (24 hours/meter/celsius) to reduce image size",
}
DATA["THIS_DEVICE_ADDRESS"] = {
"name": "Hardware address",
"type": "text",
"default": rand_hw(),
"ifndef": True
"ifndef": True,
"help": "Default Radio Hardware Address to use on the device",
}
DATA["USE_LCD_CHARGE_PUMP"] = {
"name": "Use LCD Charge Pump",
"default": False,
"help": "Use the internal charge pump to make the display contrast same tho whole battery lifetime. But this increases currency",
"help": "Use the internal charge pump to make the display contrast same tho whole battery lifetime. But this increases currency and reduces battery lifetime.",
}
DATA["USE_WATCHDOG"] = {
"name": "Use Watchdog",
"default": True,
"help": "Protects the clock against deadlocks by rebooting it.",
"help": "Protects the clock against deadlocks by rebooting it.",
}
# FIXME implement
# DATA["CONFIG_AUTOSYNC"] = {
# "name": "Automaticly SYNC after reboot",
# "default": False,
# "help": "Automaticly sync clock after reboot",
# }
DATA["DEBUG"] = {
"name": "Debug",
"default": False}
"default": False,
"help": "Activates debug code",
}
# modules
DATA["CONFIG_DAY_OF_WEEK"] = {
"name": "Date: Show Day of Week",
"name": "Date: Day of Week",
"depends": [],
"default": True}
"default": True,
"help": "Shows day of week on the date module",
}
DATA["CONFIG_TEST"] = {
"name": "Test Mode",
"depends": [],
"default": True}
"default": True,
"help": "Test module to test some functionalities when the clock started",
}
DATA["TEXT_MODULES"] = {
"name": "Modules",
@ -77,12 +92,24 @@ DATA["TEXT_MODULES"] = {
DATA["CONFIG_EGGTIMER"] = {
"name": "Eggtimer",
"depends": [],
"default": False}
"default": False,
"help": "Countdown timer to count down from 1 minute - 20 hours to 0 and start an alarm",
}
DATA["CONFIG_PHASE_CLOCK"] = {
"name": "Phase Clock",
"depends": [],
"default": False}
"default": False,
"help": "Messures sleep phase by recording body movement and sends the data to the accesspoint.\n"
"Designed to be used with uberclock",
}
DATA["CONFIG_ALTITUDE"] = {
"name": "Altitude",
"depends": [],
"default": True,
"help": "Messures altitude"
}
DATA["CONFIG_VARIO"] = {
@ -105,10 +132,6 @@ DATA["CONFIG_ALARM"] = {
"name": "Alarm",
"depends": [],
"default": True}
DATA["CONFIG_ALTITUDE"] = {
"name": "Altitude",
"depends": [],
"default": True}
DATA["CONFIG_BATTERY"] = {
"name": "Battery",
"depends": [],
@ -152,12 +175,77 @@ FOOTER = """
#print DATA
#sys.exit(1)
import curses, weakref
def wrap(text, width):
"""
A word-wrap function that preserves existing line breaks
and most spaces in the text. Expects that existing line
breaks are posix newlines (\n).
"""
return reduce(lambda line, word, width=width: '%s%s%s' %
(line,
' \n'[(len(line)-line.rfind('\n')-1
+ len(word.split('\n',1)[0]
) >= width)],
word),
text.split(' ')
)
class ConfigForm(npyscreen.TitleForm):
BLANK_LINES_BASE = 0
BLANK_COLUMNS_RIGHT = 0
DEFAULT_X_OFFSET = 2
FRAMED = False
#MAIN_WIDGET_CLASS = wgmultiline.MultiLine
STATUS_WIDGET_CLASS = npyscreen.Textfield
COMMAND_WIDGET_CLASS= npyscreen.Textfield
#MAIN_WIDGET_CLASS = grid.SimpleGrid
#MAIN_WIDGET_CLASS = editmultiline.MultiLineEdit
def __init__(self, *args, **keywords):
super(ConfigForm, self).__init__(cycle_widgets=False, *args, **keywords)
def draw_form(self):
MAXY, MAXX = self.lines, self.columns #self.curses_pad.getmaxyx()
self.curses_pad.hline(0, 0, curses.ACS_HLINE, MAXX-1)
self.curses_pad.hline(MAXY-2, 0, curses.ACS_HLINE, MAXX-1)
def create(self):
MAXY, MAXX = self.lines, self.columns
self.wStatus1 = self.add(self.__class__.STATUS_WIDGET_CLASS, rely=0, relx=0, editable=False, )
self.wStatus1.value = "Config Chronos Firmware"
#self.wMain = self.add(npyscreen.SimpleGrid, rely=1, relx=0, max_height = -2, )
#self.wMain = self.add(self.__class__.MAIN_WIDGET_CLASS, rely=1, relx=0, max_height = -2, )
self.wStatus2 = self.add(self.__class__.STATUS_WIDGET_CLASS, rely=MAXY-6, relx=0, max_heigh=3, heigth=3, editable=False, )
self.wStatus2.value = ""
#self.wCommand = self.add(self.__class__.COMMAND_WIDGET_CLASS, rely = MAXY-1, relx=0,)
self.wStatus1.important = True
self.wStatus2.important = False
self.nextrely = 2
def set_help(self):
if hasattr(self._widgets__[self.editw], "_datafield") and \
"help" in self._widgets__[self.editw]._datafield:
#print wrap(self._widgets__[self.editw]._datafield["help"], self.columns-40)
val = wrap(self._widgets__[self.editw]._datafield["help"], self.columns-5)+"\n\n\n"
else:
val = ""
self.wStatus2.value = val + "\n"*(2-val.count("\n"))
self.wStatus2.display()
def while_editing(self, *args, **kwargs):
self.set_help()
super(ConfigForm, self).while_editing(*args, **kwargs)
class OpenChronosApp(npyscreen.NPSApp):
def main(self):
self.fields = {}
# These lines create the form and populate it with widgets.
# A fairly complex screen in only 8 or so lines of code - a line for each control.
F = npyscreen.Form(name = "Config Chronos Firmware",)
F = ConfigForm(name = "Config Chronos Firmware",)
# ms2= F.add(npyscreen.TitleMultiSelect, max_height =-2, value = [1,], name="Frequency",
# values = ["911","868","Option3"], scroll_exit=True)
@ -179,8 +267,6 @@ class OpenChronosApp(npyscreen.NPSApp):
#f=F.add(npyscreen.TitleMultiSelect, max_height = 1, value = ["ENABLED",], name=field["name"],
# values = [""], scroll_exit=True)
f = F.add(npyscreen.Checkbox, name=field["name"], value=field["value"])
f._key = key
self.fields[key] = f
elif field["type"] == "choices":
try:
value = field["values"].index(field["value"])
@ -188,15 +274,14 @@ class OpenChronosApp(npyscreen.NPSApp):
value = field["values"].index(field["default"])
f = F.add(npyscreen.TitleSelectOne, max_height=4, value=value, name=field["name"],
values = field["values"], scroll_exit=True)
f._key = key
self.fields[key] = f
elif field["type"] == "text":
f = F.add(npyscreen.TitleText, max_height=1, value=field["value"], name=field["name"],
values = field["value"])
f._key = key
self.fields[key] = f
elif field["type"] == "info":
f = F.add(npyscreen.TitleText, max_height=1, name=field["name"])
f._key = key
f._datafield = field
self.fields[key] = f
# This lets the user play with the Form.
@ -259,7 +344,7 @@ class OpenChronosApp(npyscreen.NPSApp):
DATA[m[0]]["value"] = value
else:
m = match2.search(line)
if m:
if m and m.groups()[0] in DATA:
m = m.groups()
DATA[m[0]]["value"] = False

Loading…
Cancel
Save