Merge branch 'master' of http://github.com/poelzi/OpenChronos
This commit is contained in:
commit
fe862ac2cf
6
README
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 ==
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
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…
Reference in New Issue