From 9513be7f9d3d0b0ec29f6487fa9dc8f1ac24d0de Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 25 Aug 2011 20:43:44 -0700 Subject: altos: Restructure altos build to prepare for multi-arch support Split out sources into separate directories: core: architecture and product independent bits cc1111: cc1111-specific code drivers: architecture independent drivers product: product-specific sources and Makefile fragments util: scripts for building stuff This should have no effect on the built products, but testing is encouraged Signed-off-by: Keith Packard --- src/core/ao_cmd.c | 320 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 src/core/ao_cmd.c (limited to 'src/core/ao_cmd.c') diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c new file mode 100644 index 00000000..1442ebea --- /dev/null +++ b/src/core/ao_cmd.c @@ -0,0 +1,320 @@ +/* + * Copyright © 2009 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" + +__pdata uint16_t ao_cmd_lex_i; +__pdata uint32_t ao_cmd_lex_u32; +__pdata char ao_cmd_lex_c; +__pdata enum ao_cmd_status ao_cmd_status; + +#define CMD_LEN 32 + +static __xdata char cmd_line[CMD_LEN]; +static __pdata uint8_t cmd_len; +static __pdata uint8_t cmd_i; + +static void +put_string(__code char *s) +{ + char c; + while (c = *s++) + putchar(c); +} + +static void +readline(void) +{ + __pdata char c; + if (ao_echo()) + put_string("> "); + cmd_len = 0; + for (;;) { + flush(); + c = getchar(); + /* backspace/delete */ + if (c == '\010' || c == '\177') { + if (cmd_len != 0) { + if (ao_echo()) + put_string("\010 \010"); + --cmd_len; + } + continue; + } + + /* ^U */ + if (c == '\025') { + while (cmd_len != 0) { + if (ao_echo()) + put_string("\010 \010"); + --cmd_len; + } + continue; + } + + /* map CR to NL */ + if (c == '\r') + c = '\n'; + + if (c == '\n') { + if (ao_echo()) + putchar('\n'); + break; + } + + if (cmd_len >= CMD_LEN - 2) { + if (ao_echo()) + putchar('\007'); + continue; + } + cmd_line[cmd_len++] = c; + if (ao_echo()) + putchar(c); + } + cmd_line[cmd_len++] = '\n'; + cmd_line[cmd_len++] = '\0'; + cmd_i = 0; +} + +void +ao_cmd_lex(void) +{ + ao_cmd_lex_c = '\n'; + if (cmd_i < cmd_len) + ao_cmd_lex_c = cmd_line[cmd_i++]; +} + +static void +putnibble(uint8_t v) +{ + if (v < 10) + putchar(v + '0'); + else + putchar(v + ('a' - 10)); +} + +void +ao_cmd_put16(uint16_t v) +{ + ao_cmd_put8(v >> 8); + ao_cmd_put8(v); +} + +void +ao_cmd_put8(uint8_t v) +{ + putnibble((v >> 4) & 0xf); + putnibble(v & 0xf); +} + +void +ao_cmd_white(void) +{ + while (ao_cmd_lex_c == ' ' || ao_cmd_lex_c == '\t') + ao_cmd_lex(); +} + +void +ao_cmd_hex(void) +{ + __pdata uint8_t r = ao_cmd_lex_error; + uint8_t n; + + ao_cmd_lex_i = 0; + ao_cmd_white(); + for(;;) { + if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9') + n = (ao_cmd_lex_c - '0'); + else if ('a' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'f') + n = (ao_cmd_lex_c - 'a' + 10); + else if ('A' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'F') + n = (ao_cmd_lex_c - 'A' + 10); + else + break; + ao_cmd_lex_i = (ao_cmd_lex_i << 4) | n; + r = ao_cmd_success; + ao_cmd_lex(); + } + if (r != ao_cmd_success) + ao_cmd_status = r; +} + +void +ao_cmd_decimal(void) +{ + __pdata uint8_t r = ao_cmd_lex_error; + + ao_cmd_lex_u32 = 0; + ao_cmd_white(); + for(;;) { + if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9') + ao_cmd_lex_u32 = (ao_cmd_lex_u32 * 10) + (ao_cmd_lex_c - '0'); + else + break; + r = ao_cmd_success; + ao_cmd_lex(); + } + if (r != ao_cmd_success) + ao_cmd_status = r; + ao_cmd_lex_i = (uint16_t) ao_cmd_lex_u32; +} + +uint8_t +ao_match_word(__code char *word) +{ + while (*word) { + if (ao_cmd_lex_c != *word) { + ao_cmd_status = ao_cmd_syntax_error; + return 0; + } + word++; + ao_cmd_lex(); + } + return 1; +} + +static void +eol(void) +{ + while (ao_cmd_lex_c != '\n') + ao_cmd_lex(); +} + +static void +echo(void) +{ + ao_cmd_hex(); + if (ao_cmd_status == ao_cmd_success) + ao_stdios[ao_cur_stdio].echo = ao_cmd_lex_i != 0; +} + +static void +ao_reboot(void) +{ + ao_cmd_white(); + if (!ao_match_word("eboot")) + return; + WDCTL = WDCTL_EN | WDCTL_MODE_WATCHDOG | WDCTL_INT_64; + ao_delay(AO_SEC_TO_TICKS(2)); + ao_panic(AO_PANIC_REBOOT); +} + +static void +version(void) +{ + printf("manufacturer %s\n", ao_manufacturer); + printf("product %s\n", ao_product); + printf("serial-number %u\n", ao_serial_number); +#if HAS_EEPROM + printf("log-format %u\n", ao_log_format); +#endif + printf("software-version %s\n", ao_version); +} + +#define NUM_CMDS 11 + +static __code struct ao_cmds *__xdata (ao_cmds[NUM_CMDS]); +static __pdata uint8_t ao_ncmds; + +static void +help(void) +{ + register uint8_t cmds; + register uint8_t cmd; + register __code struct ao_cmds * cs; + + for (cmds = 0; cmds < ao_ncmds; cmds++) { + cs = ao_cmds[cmds]; + for (cmd = 0; cs[cmd].func; cmd++) + printf("%-45s %s\n", + cs[cmd].help, + cs[cmd].help+1+strlen(cs[cmd].help)); + } +} + +static void +report(void) +{ + switch(ao_cmd_status) { + case ao_cmd_lex_error: + case ao_cmd_syntax_error: + puts("Syntax error"); + ao_cmd_status = 0; + break; + } +} + +void +ao_cmd_register(__code struct ao_cmds *cmds) +{ + if (ao_ncmds >= NUM_CMDS) + ao_panic(AO_PANIC_CMD); + ao_cmds[ao_ncmds++] = cmds; +} + +void +ao_cmd(void) +{ + char c; + uint8_t cmd, cmds; + __code struct ao_cmds * __xdata cs; + void (*__xdata func)(void); + + for (;;) { + readline(); + ao_cmd_lex(); + ao_cmd_white(); + c = ao_cmd_lex_c; + ao_cmd_lex(); + if (c == '\r' || c == '\n') + continue; + func = (void (*)(void)) NULL; + for (cmds = 0; cmds < ao_ncmds; cmds++) { + cs = ao_cmds[cmds]; + for (cmd = 0; cs[cmd].func; cmd++) + if (cs[cmd].help[0] == c) { + func = cs[cmd].func; + break; + } + if (func) + break; + } + if (func) + (*func)(); + else + ao_cmd_status = ao_cmd_syntax_error; + report(); + } +} + +__xdata struct ao_task ao_cmd_task; + +__code struct ao_cmds ao_base_cmds[] = { + { help, "?\0Help" }, + { ao_task_info, "T\0Show tasks" }, + { echo, "E <0 off, 1 on>\0Set echo mode" }, + { ao_reboot, "r eboot\0Reboot" }, + { version, "v\0Version" }, + { 0, NULL }, +}; + +void +ao_cmd_init(void) +{ + ao_cmd_register(&ao_base_cmds[0]); + ao_add_task(&ao_cmd_task, ao_cmd, "cmd"); +} -- cgit v1.2.3 From a588092a7d76dab92e4ab11e0fdb457d2ddc9025 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 25 Aug 2011 21:10:56 -0700 Subject: altos: AVR changes - create ao_arch.h files, define ao_arch_reboot Start pulling changes needed for avr port; architecture-specific code will live in /ao_arch.h. This first change defines the ao_arch_reboot macro to reboot the microcontroller. Signed-off-by: Keith Packard --- src/avr/ao_arch.h | 36 ++++++++++++++++++++++++++++++++++++ src/cc1111/ao_arch.h | 32 ++++++++++++++++++++++++++++++++ src/core/ao.h | 2 +- src/core/ao_cmd.c | 13 +++---------- 4 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 src/avr/ao_arch.h create mode 100644 src/cc1111/ao_arch.h (limited to 'src/core/ao_cmd.c') diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h new file mode 100644 index 00000000..2b566814 --- /dev/null +++ b/src/avr/ao_arch.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_ARCH_H_ +#define _AO_ARCH_H_ + +#include "avr.h" + + +/* + * AVR definitions and code fragments for AltOS + */ + +#define AO_STACK_SIZE 128 + +/* Various definitions to make GCC look more like SDCC */ + +#define __naked __attribute__((naked)) + +#define ao_arch_reboot() /* XXX */ + +#endif /* _AO_ARCH_H_ */ diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h new file mode 100644 index 00000000..585fffe5 --- /dev/null +++ b/src/cc1111/ao_arch.h @@ -0,0 +1,32 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/* + * CC1111 definitions and code fragments for AltOS + */ + +#ifndef _AO_ARCH_H_ +#define _AO_ARCH_H_ + +#include "cc1111.h" + +#define ao_arch_reboot() do { \ + WDCTL = WDCTL_EN | WDCTL_MODE_WATCHDOG | WDCTL_INT_64; \ + ao_delay(AO_SEC_TO_TICKS(2)); \ + } while (0) + +#endif /* _AO_ARCH_H_ */ diff --git a/src/core/ao.h b/src/core/ao.h index 8ac9ac3d..0f1a24ad 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -22,7 +22,7 @@ #include #include #include -#include "cc1111.h" +#include #include "ao_pins.h" #define TRUE 1 diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 1442ebea..7663d875 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -32,7 +32,7 @@ static void put_string(__code char *s) { char c; - while (c = *s++) + while ((c = *s++)) putchar(c); } @@ -187,13 +187,6 @@ ao_match_word(__code char *word) return 1; } -static void -eol(void) -{ - while (ao_cmd_lex_c != '\n') - ao_cmd_lex(); -} - static void echo(void) { @@ -208,8 +201,7 @@ ao_reboot(void) ao_cmd_white(); if (!ao_match_word("eboot")) return; - WDCTL = WDCTL_EN | WDCTL_MODE_WATCHDOG | WDCTL_INT_64; - ao_delay(AO_SEC_TO_TICKS(2)); + ao_arch_reboot(); ao_panic(AO_PANIC_REBOOT); } @@ -254,6 +246,7 @@ report(void) case ao_cmd_syntax_error: puts("Syntax error"); ao_cmd_status = 0; + default: break; } } -- cgit v1.2.3 From 4299b5a36a2f6f9f7bbbc3a1b935dd2357c1fb0f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 21 Jul 2011 20:04:05 -0700 Subject: altos: Implement remote launch protocol Uses the radio_cmac module to provide secure communication. Keeps igniter closed for 500ms. Provides remote status for arming and ignition. Signed-off-by: Keith Packard --- src/ao_launch.c | 170 +++++++++++++++++++++++--- src/ao_radio_cmac.c | 278 ++++++++++++++++++++++++++++++------------ src/ao_telelaunch.c | 1 - src/cc1111/ao_ignite.c | 6 - src/cc1111/ao_packet_master.c | 6 +- src/cc1111/ao_timer.c | 1 + src/core/ao.h | 59 ++++++++- src/core/ao_cmd.c | 44 +++++-- src/core/ao_config.c | 36 ++++++ src/core/ao_task.c | 7 +- 10 files changed, 497 insertions(+), 111 deletions(-) (limited to 'src/core/ao_cmd.c') diff --git a/src/ao_launch.c b/src/ao_launch.c index 4870869e..6c154719 100644 --- a/src/ao_launch.c +++ b/src/ao_launch.c @@ -17,43 +17,183 @@ #include "ao.h" +__xdata uint16_t ao_launch_ignite; + +static void +ao_launch_run(void) +{ + for (;;) { + while (!ao_launch_ignite) + ao_sleep(&ao_launch_ignite); + while (ao_launch_ignite) { + ao_launch_ignite = 0; + + ao_ignition[ao_igniter_drogue].firing = 1; + ao_ignition[ao_igniter_main].firing = 1; + AO_IGNITER_DROGUE = 1; + ao_delay(AO_MS_TO_TICKS(500)); + AO_IGNITER_DROGUE = 0; + ao_ignition[ao_igniter_drogue].firing = 0; + ao_ignition[ao_igniter_main].firing = 0; + } + } +} + +static void +ao_launch_status(void) +{ + uint8_t i; + for (;;) { + ao_delay(AO_SEC_TO_TICKS(1)); + if (ao_igniter_status(ao_igniter_drogue) == ao_igniter_ready) { + if (ao_igniter_status(ao_igniter_main) == ao_igniter_ready) { + for (i = 0; i < 5; i++) { + ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(50)); + ao_delay(AO_MS_TO_TICKS(100)); + } + } else { + ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); + } + } + } +} + +static __pdata uint8_t ao_launch_armed; +static __pdata uint16_t ao_launch_arm_time; + static void ao_launch(void) { - enum ao_igniter_status arm_status, ignite_status; + static __xdata struct ao_launch_command command; + static __xdata struct ao_launch_query query; + int16_t time_difference; ao_led_off(AO_LED_RED); ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); for (;;) { - arm_status = ao_igniter_status(ao_igniter_drogue); + if (ao_radio_cmac_recv(&command, sizeof (command), 0) != AO_RADIO_CMAC_OK) + continue; + + printf ("tick %d serial %d cmd %d channel %d\n", + command.tick, command.serial, command.cmd, command.channel); + + if (command.serial != ao_serial_number) { + printf ("serial number mismatch\n"); + continue; + } - switch (arm_status) { - case ao_igniter_unknown: + switch (command.cmd) { + case AO_LAUNCH_QUERY: + if (command.channel == 0) { + query.valid = 1; + query.arm_status = ao_igniter_status(ao_igniter_drogue); + query.igniter_status = ao_igniter_status(ao_igniter_main); + } else { + query.valid = 0; + } + query.tick = ao_time(); + query.serial = ao_serial_number; + query.channel = command.channel; + printf ("query tick %d serial %d channel %d valid %d arm %d igniter %d\n", + query.tick, query.serial, query.channel, query.valid, query.arm_status, + query.igniter_status); + ao_radio_cmac_send(&query, sizeof (query)); break; - case ao_igniter_active: - case ao_igniter_open: + case AO_LAUNCH_ARM: + if (command.channel != 0) + break; + time_difference = command.tick - ao_time(); + printf ("arm tick %d local tick %d\n", command.tick, ao_time()); + if (time_difference < 0) + time_difference = -time_difference; + if (time_difference > 10) { + printf ("time difference too large %d\n", time_difference); + break; + } + printf ("armed\n"); + ao_launch_armed = 1; + ao_launch_arm_time = ao_time(); break; - case ao_igniter_ready: - ignite_status = ao_igniter_status(ao_igniter_main); - switch (ignite_status) { - case ao_igniter_unknown: - /* some kind of failure signal here */ + case AO_LAUNCH_FIRE: + if (command.channel != 0) break; - case ao_igniter_active: + if (!ao_launch_armed) { + printf ("not armed\n"); break; - case ao_igniter_open: + } + if ((uint16_t) (ao_launch_arm_time - ao_time()) > AO_SEC_TO_TICKS(20)) { + printf ("late launch arm_time %d time %d\n", + ao_launch_arm_time, ao_time()); + break; + } + time_difference = command.tick - ao_time(); + if (time_difference < 0) + time_difference = -time_difference; + if (time_difference > 10) { + printf ("time different too large %d\n", time_difference); break; } + printf ("ignite\n"); + ao_launch_ignite = 1; + ao_wakeup(&ao_launch_ignite); break; } - ao_delay(AO_SEC_TO_TICKS(1)); } } +void +ao_launch_test(void) +{ + switch (ao_igniter_status(ao_igniter_drogue)) { + case ao_igniter_ready: + case ao_igniter_active: + printf ("Armed: "); + switch (ao_igniter_status(ao_igniter_main)) { + default: + printf("unknown status\n"); + break; + case ao_igniter_ready: + printf("igniter good\n"); + break; + case ao_igniter_open: + printf("igniter bad\n"); + break; + } + break; + default: + printf("Disarmed\n"); + } +} + +void +ao_launch_manual(void) +{ + ao_cmd_white(); + if (!ao_match_word("DoIt")) + return; + ao_cmd_white(); + ao_launch_ignite = 1; + ao_wakeup(&ao_launch_ignite); +} + static __xdata struct ao_task ao_launch_task; +static __xdata struct ao_task ao_launch_ignite_task; +static __xdata struct ao_task ao_launch_status_task; + +__code struct ao_cmds ao_launch_cmds[] = { + { ao_launch_test, "t\0Test launch continuity" }, + { ao_launch_manual, "i \0Fire igniter. is doit with D&I" }, + { 0, NULL } +}; void ao_launch_init(void) { - ao_add_task(&ao_launch_task, ao_launch, "launch status"); + AO_IGNITER_DROGUE = 0; + AO_IGNITER_MAIN = 0; + AO_IGNITER_DIR |= AO_IGNITER_DROGUE_BIT | AO_IGNITER_MAIN_BIT; + ao_cmd_register(&ao_launch_cmds[0]); + ao_add_task(&ao_launch_task, ao_launch, "launch listener"); + ao_add_task(&ao_launch_ignite_task, ao_launch_run, "launch igniter"); + ao_add_task(&ao_launch_status_task, ao_launch_status, "launch status"); } diff --git a/src/ao_radio_cmac.c b/src/ao_radio_cmac.c index 7648a2f5..9694b5b3 100644 --- a/src/ao_radio_cmac.c +++ b/src/ao_radio_cmac.c @@ -17,27 +17,24 @@ #include "ao.h" -#define AO_CMAC_KEY_LEN 16 +#define AO_CMAC_KEY_LEN AO_AES_LEN #define AO_CMAC_MAX_LEN (128 - AO_CMAC_KEY_LEN) -static __xdata uint8_t cmac_key[AO_CMAC_KEY_LEN]; +static __xdata uint8_t ao_radio_cmac_mutex; static __xdata uint8_t cmac_data[AO_CMAC_MAX_LEN + AO_CMAC_KEY_LEN + 2 + AO_CMAC_KEY_LEN]; static __pdata uint8_t ao_radio_cmac_len; static uint8_t getnibble(void) { - __pdata char c; - - c = getchar(); - if ('0' <= c && c <= '9') - return c - '0'; - if ('a' <= c && c <= 'f') - return c - ('a' - 10); - if ('A' <= c && c <= 'F') - return c - ('A' - 10); - ao_cmd_status = ao_cmd_lex_error; - return 0; + int8_t b; + + b = ao_cmd_hexchar(getchar()); + if (b < 0) { + ao_cmd_status = ao_cmd_lex_error; + return 0; + } + return (uint8_t) b; } static uint8_t @@ -49,20 +46,137 @@ getbyte(void) return b; } +static uint8_t +round_len(uint8_t len) +{ + uint8_t rem; + + /* Make sure we transfer at least one packet, and + * then make sure every packet is full. Note that + * there is no length encoded, and that the receiver + * must deal with any extra bytes in the packet + */ + if (len < AO_CMAC_KEY_LEN) + len = AO_CMAC_KEY_LEN; + rem = len % AO_CMAC_KEY_LEN; + if (rem != 0) + len += (AO_CMAC_KEY_LEN - rem); + return len; +} + +/* + * Sign and deliver the data sitting in the cmac buffer + */ static void -ao_radio_cmac_key(void) __reentrant +radio_cmac_send(uint8_t len) __reentrant { uint8_t i; - for (i = 0; i < AO_CMAC_KEY_LEN; i++) { - cmac_key[i] = getbyte(); - if (ao_cmd_status != ao_cmd_success) - return; + len = round_len(len); + /* Make sure the AES key is loaded */ + ao_config_get(); + +#if HAS_MONITOR + ao_set_monitor(0); +#endif + + ao_mutex_get(&ao_aes_mutex); + ao_aes_set_mode(ao_aes_mode_cbc_mac); + ao_aes_set_key(ao_config.aes_key); + ao_aes_zero_iv(); + for (i = 0; i < len; i += AO_CMAC_KEY_LEN) { + if (i + AO_CMAC_KEY_LEN < len) + ao_aes_run(&cmac_data[i], NULL); + else + ao_aes_run(&cmac_data[i], &cmac_data[len]); } + ao_mutex_put(&ao_aes_mutex); + + ao_radio_send(cmac_data, len + AO_CMAC_KEY_LEN); +} + +/* + * Receive and validate an incoming packet + */ + +static int8_t +radio_cmac_recv(uint8_t len, uint16_t timeout) __reentrant +{ + uint8_t i; + + len = round_len(len); +#if HAS_MONITOR + ao_set_monitor(0); +#endif + if (timeout) + ao_alarm(timeout); + + i = ao_radio_recv(cmac_data, len + AO_CMAC_KEY_LEN + 2); + ao_clear_alarm(); + + if (!i) + return AO_RADIO_CMAC_TIMEOUT; + + if (!(cmac_data[len + AO_CMAC_KEY_LEN +1] & PKT_APPEND_STATUS_1_CRC_OK)) + return AO_RADIO_CMAC_CRC_ERROR; + + ao_config_get(); + + /* Compute the packet signature + */ + ao_mutex_get(&ao_aes_mutex); + ao_aes_set_mode(ao_aes_mode_cbc_mac); + ao_aes_set_key(ao_config.aes_key); + ao_aes_zero_iv(); + for (i = 0; i < len; i += AO_CMAC_KEY_LEN) { + if (i + AO_CMAC_KEY_LEN < len) + ao_aes_run(&cmac_data[i], NULL); + else + ao_aes_run(&cmac_data[i], &cmac_data[len + AO_CMAC_KEY_LEN + 2]); + } + ao_mutex_put(&ao_aes_mutex); + + /* Check the packet signature against the signature provided + * over the link + */ + + if (memcmp(&cmac_data[len], + &cmac_data[len + AO_CMAC_KEY_LEN + 2], + AO_CMAC_KEY_LEN) != 0) { + return AO_RADIO_CMAC_MAC_ERROR; + } + + return AO_RADIO_CMAC_OK; +} + +int8_t +ao_radio_cmac_send(__xdata void *packet, uint8_t len) __reentrant +{ + if (len > AO_CMAC_MAX_LEN) + return AO_RADIO_CMAC_LEN_ERROR; + ao_mutex_get(&ao_radio_cmac_mutex); + memcpy(cmac_data, packet, len); + radio_cmac_send(len); + ao_mutex_put(&ao_radio_cmac_mutex); + return AO_RADIO_CMAC_OK; +} + +int8_t +ao_radio_cmac_recv(__xdata void *packet, uint8_t len, uint16_t timeout) __reentrant +{ + uint8_t i; + if (len > AO_CMAC_MAX_LEN) + return AO_RADIO_CMAC_LEN_ERROR; + ao_mutex_get(&ao_radio_cmac_mutex); + i = radio_cmac_recv(len, timeout); + if (i == AO_RADIO_CMAC_OK) + memcpy(packet, cmac_data, len); + ao_mutex_put(&ao_radio_cmac_mutex); + return i; } static void -ao_radio_cmac_send(void) __reentrant +radio_cmac_send_cmd(void) __reentrant { uint8_t i; uint8_t len; @@ -70,43 +184,25 @@ ao_radio_cmac_send(void) __reentrant ao_cmd_decimal(); if (ao_cmd_status != ao_cmd_success) return; - if (ao_cmd_lex_i < AO_CMAC_KEY_LEN || - ao_cmd_lex_i > AO_CMAC_MAX_LEN || - ao_cmd_lex_i % AO_CMAC_KEY_LEN != 0) - { + len = ao_cmd_lex_i; + if (len > AO_CMAC_MAX_LEN) { ao_cmd_status = ao_cmd_syntax_error; return; } flush(); + ao_mutex_get(&ao_radio_cmac_mutex); len = ao_cmd_lex_i; for (i = 0; i < len; i++) { cmac_data[i] = getbyte(); if (ao_cmd_status != ao_cmd_success) return; } - ao_mutex_get(&ao_aes_mutex); - ao_aes_set_mode(ao_aes_mode_cbc_mac); - ao_aes_set_key(cmac_key); - ao_aes_zero_iv(); - for (i = 0; i < len; i += AO_CMAC_KEY_LEN) { - if (i + AO_CMAC_KEY_LEN < len) - ao_aes_run(&cmac_data[i], NULL); - else - ao_aes_run(&cmac_data[i], &cmac_data[len]); - } - ao_mutex_put(&ao_aes_mutex); -#if HAS_MONITOR - ao_set_monitor(0); -#endif - printf("send:"); - for (i = 0; i < len + AO_CMAC_KEY_LEN; i++) - printf(" %02x", cmac_data[i]); - printf("\n"); flush(); - ao_radio_send(cmac_data, len + AO_CMAC_KEY_LEN); + radio_cmac_send(len); + ao_mutex_put(&ao_radio_cmac_mutex); } static void -ao_radio_cmac_recv(void) __reentrant +radio_cmac_recv_cmd(void) __reentrant { uint8_t len, i; uint16_t timeout; @@ -114,47 +210,79 @@ ao_radio_cmac_recv(void) __reentrant ao_cmd_decimal(); if (ao_cmd_status != ao_cmd_success) return; - if (ao_cmd_lex_i < AO_CMAC_KEY_LEN || - ao_cmd_lex_i > AO_CMAC_MAX_LEN || - ao_cmd_lex_i % AO_CMAC_KEY_LEN != 0) - { - ao_cmd_status = ao_cmd_syntax_error; - return; - } len = ao_cmd_lex_i; ao_cmd_decimal(); if (ao_cmd_status != ao_cmd_success) return; - timeout = ao_cmd_lex_i; -#if HAS_MONITOR - ao_set_monitor(0); -#endif - if (timeout) - ao_alarm(timeout); - if (!ao_radio_recv(cmac_data, len + AO_CMAC_KEY_LEN + 2)) { - printf("timeout\n"); + timeout = AO_MS_TO_TICKS(ao_cmd_lex_i); + ao_mutex_get(&ao_radio_cmac_mutex); + i = radio_cmac_recv(len, timeout); + if (i == AO_RADIO_CMAC_OK) { + printf ("PACKET "); + for (i = 0; i < len; i++) + printf("%02x", cmac_data[i]); + printf ("\n"); + } else + printf ("ERROR %d\n", i); + ao_mutex_put(&ao_radio_cmac_mutex); +} + +static void +launch_report_cmd(void) __reentrant +{ + static __xdata struct ao_launch_command command; + static __xdata struct ao_launch_query query; + uint8_t channel; + uint16_t serial; + uint8_t i; + + ao_cmd_decimal(); + serial = ao_cmd_lex_i; + ao_cmd_decimal(); + channel = ao_cmd_lex_i; + if (ao_cmd_status != ao_cmd_success) return; + flush(); + for (i = 0; i < 10; i++) { + printf ("."); flush(); + command.tick = 0; + command.serial = serial; + command.cmd = AO_LAUNCH_QUERY; + command.channel = channel; + ao_radio_cmac_send(&command, sizeof (command)); + switch (ao_radio_cmac_recv(&query, sizeof (query), AO_MS_TO_TICKS(500))) { + case AO_RADIO_CMAC_OK: + printf("\n"); + switch (query.arm_status) { + case ao_igniter_ready: + case ao_igniter_active: + printf ("Armed: "); + switch (query.igniter_status) { + default: + printf("unknown status\n"); + break; + case ao_igniter_ready: + printf("igniter good\n"); + break; + case ao_igniter_open: + printf("igniter bad\n"); + break; + } + default: + printf("Disarmed\n"); + } + return; + default: + continue; + } } - ao_mutex_get(&ao_aes_mutex); - ao_aes_set_mode(ao_aes_mode_cbc_mac); - ao_aes_set_key(cmac_key); - ao_aes_zero_iv(); - for (i = 0; i < len; i += AO_CMAC_KEY_LEN) { - if (i + AO_CMAC_KEY_LEN < len) - ao_aes_run(&cmac_data[i], NULL); - else - ao_aes_run(&cmac_data[i], &cmac_data[len + AO_CMAC_KEY_LEN + 2]); - } - printf ("PACKET "); - for (i = 0; i < len + AO_CMAC_KEY_LEN + 2 + AO_CMAC_KEY_LEN; i++) - printf("%02x", cmac_data[i]); - printf ("\n"); + printf ("Timeout\n"); } static __code struct ao_cmds ao_radio_cmac_cmds[] = { - { ao_radio_cmac_key, "k\0Set AES-CMAC key. 16 key bytes follow on next line" }, - { ao_radio_cmac_send, "s \0Send AES-CMAC packet. Bytes to send follow on next line" }, - { ao_radio_cmac_recv, "S \0Receive AES-CMAC packet. Timeout in ms" }, + { radio_cmac_send_cmd, "s \0Send AES-CMAC packet. Bytes to send follow on next line" }, + { radio_cmac_recv_cmd, "S \0Receive AES-CMAC packet. Timeout in ms" }, + { launch_report_cmd, "l \0Get remote launch status" }, { 0, NULL }, }; diff --git a/src/ao_telelaunch.c b/src/ao_telelaunch.c index b5404710..506431de 100644 --- a/src/ao_telelaunch.c +++ b/src/ao_telelaunch.c @@ -35,7 +35,6 @@ main(void) ao_storage_init(); ao_usb_init(); ao_radio_init(); - ao_igniter_init(); #if HAS_DBG ao_dbg_init(); #endif diff --git a/src/cc1111/ao_ignite.c b/src/cc1111/ao_ignite.c index 5238beb4..0fd2b4bf 100644 --- a/src/cc1111/ao_ignite.c +++ b/src/cc1111/ao_ignite.c @@ -39,12 +39,6 @@ #define AO_IGNITER_FIRE_TIME AO_MS_TO_TICKS(50) #define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000) -struct ao_ignition { - uint8_t request; - uint8_t fired; - uint8_t firing; -}; - __xdata struct ao_ignition ao_ignition[2]; void diff --git a/src/cc1111/ao_packet_master.c b/src/cc1111/ao_packet_master.c index b0fdf5a8..0d0be30e 100644 --- a/src/cc1111/ao_packet_master.c +++ b/src/cc1111/ao_packet_master.c @@ -80,13 +80,16 @@ ao_packet_master(void) ao_packet_master_time = ao_time(); ao_packet_master_delay = AO_PACKET_MASTER_DELAY_SHORT; while (ao_packet_enable) { + uint8_t r; memcpy(ao_tx_packet.callsign, ao_config.callsign, AO_MAX_CALLSIGN); ao_packet_send(); if (ao_tx_packet.len) ao_packet_master_busy(); ao_packet_master_check_busy(); ao_alarm(ao_packet_master_delay); - if (ao_packet_recv()) { + r = ao_packet_recv(); + ao_clear_alarm(); + if (r) { /* if we can transmit data, do so */ if (ao_packet_tx_used && ao_tx_packet.len == 0) continue; @@ -95,6 +98,7 @@ ao_packet_master(void) ao_packet_master_sleeping = 1; ao_alarm(ao_packet_master_delay); ao_sleep(&ao_packet_master_sleeping); + ao_clear_alarm(); ao_packet_master_sleeping = 0; } } diff --git a/src/cc1111/ao_timer.c b/src/cc1111/ao_timer.c index c977fbc8..aadee71e 100644 --- a/src/cc1111/ao_timer.c +++ b/src/cc1111/ao_timer.c @@ -31,6 +31,7 @@ ao_delay(uint16_t ticks) { ao_alarm(ticks); ao_sleep(&ao_forever); + ao_clear_alarm(); } #define T1_CLOCK_DIVISOR 8 /* 24e6/8 = 3e6 */ diff --git a/src/core/ao.h b/src/core/ao.h index 2898852b..a5bbb6f1 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -68,6 +68,10 @@ ao_wakeup(__xdata void *wchan); void ao_alarm(uint16_t delay); +/* Clear any pending alarm */ +void +ao_clear_alarm(void); + /* Yield the processor to another task */ void ao_yield(void) ao_arch_naked_declare; @@ -342,6 +346,12 @@ ao_cmd_put16(uint16_t v); void ao_cmd_white(void); +int8_t +ao_cmd_hexchar(char c); + +void +ao_cmd_hexbyte(void); + void ao_cmd_hex(void); @@ -1417,6 +1427,14 @@ enum ao_igniter_status { ao_igniter_open, /* open circuit detected */ }; +struct ao_ignition { + uint8_t request; + uint8_t fired; + uint8_t firing; +}; + +extern __xdata struct ao_ignition ao_ignition[2]; + enum ao_igniter_status ao_igniter_status(enum ao_igniter igniter); @@ -1431,7 +1449,8 @@ ao_igniter_init(void); */ #define AO_CONFIG_MAJOR 1 -#define AO_CONFIG_MINOR 8 +#define AO_CONFIG_MINOR 9 +#define AO_AES_LEN 16 struct ao_config { uint8_t major; @@ -1448,6 +1467,7 @@ struct ao_config { uint8_t pad_orientation; /* minor version 6 */ uint32_t radio_setting; /* minor version 7 */ uint8_t radio_enable; /* minor version 8 */ + uint8_t aes_key[AO_AES_LEN]; /* minor version 9 */ }; #define AO_IGNITE_MODE_DUAL 0 @@ -1635,8 +1655,6 @@ __xdata uint8_t ao_aes_mutex; /* AES keys and blocks are 128 bits */ -#define AO_AES_LEN 16 - enum ao_aes_mode { ao_aes_mode_cbc_mac }; @@ -1664,10 +1682,45 @@ ao_aes_init(void); /* ao_radio_cmac.c */ +int8_t +ao_radio_cmac_send(__xdata void *packet, uint8_t len) __reentrant; + +#define AO_RADIO_CMAC_OK 0 +#define AO_RADIO_CMAC_LEN_ERROR -1 +#define AO_RADIO_CMAC_CRC_ERROR -2 +#define AO_RADIO_CMAC_MAC_ERROR -3 +#define AO_RADIO_CMAC_TIMEOUT -4 + +int8_t +ao_radio_cmac_recv(__xdata void *packet, uint8_t len, uint16_t timeout) __reentrant; + void ao_radio_cmac_init(void); /* ao_launch.c */ + +struct ao_launch_command { + uint16_t tick; + uint16_t serial; + uint8_t cmd; + uint8_t channel; + uint16_t unused; +}; + +#define AO_LAUNCH_QUERY 1 + +struct ao_launch_query { + uint16_t tick; + uint16_t serial; + uint8_t channel; + uint8_t valid; + uint8_t arm_status; + uint8_t igniter_status; +}; + +#define AO_LAUNCH_ARM 2 +#define AO_LAUNCH_FIRE 3 + void ao_launch_init(void); diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 7663d875..9e14c221 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -22,7 +22,7 @@ __pdata uint32_t ao_cmd_lex_u32; __pdata char ao_cmd_lex_c; __pdata enum ao_cmd_status ao_cmd_status; -#define CMD_LEN 32 +#define CMD_LEN 48 static __xdata char cmd_line[CMD_LEN]; static __pdata uint8_t cmd_len; @@ -128,22 +128,48 @@ ao_cmd_white(void) ao_cmd_lex(); } +int8_t +ao_cmd_hexchar(char c) +{ + if ('0' <= c && c <= '9') + return (c - '0'); + if ('a' <= c && c <= 'f') + return (c - 'a' + 10); + if ('A' <= c && c <= 'F') + return (c - 'A' + 10); + return -1; +} + +void +ao_cmd_hexbyte(void) +{ + uint8_t i; + int8_t n; + + ao_cmd_lex_i = 0; + ao_cmd_white(); + for (i = 0; i < 2; i++) { + n = ao_cmd_hexchar(ao_cmd_lex_c); + if (n < 0) { + ao_cmd_status = ao_cmd_syntax_error; + break; + } + ao_cmd_lex_i = (ao_cmd_lex_i << 4) | n; + ao_cmd_lex(); + } +} + void ao_cmd_hex(void) { __pdata uint8_t r = ao_cmd_lex_error; - uint8_t n; + int8_t n; ao_cmd_lex_i = 0; ao_cmd_white(); for(;;) { - if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9') - n = (ao_cmd_lex_c - '0'); - else if ('a' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'f') - n = (ao_cmd_lex_c - 'a' + 10); - else if ('A' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'F') - n = (ao_cmd_lex_c - 'A' + 10); - else + n = ao_cmd_hexchar(ao_cmd_lex_c); + if (n < 0) break; ao_cmd_lex_i = (ao_cmd_lex_i << 4) | n; r = ao_cmd_success; diff --git a/src/core/ao_config.c b/src/core/ao_config.c index ec2b61f6..7f999feb 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -74,11 +74,14 @@ _ao_config_get(void) if (ao_config.major != AO_CONFIG_MAJOR) { ao_config.major = AO_CONFIG_MAJOR; ao_config.minor = 0; + + /* Version 0 stuff */ ao_config.main_deploy = AO_CONFIG_DEFAULT_MAIN_DEPLOY; ao_config.radio_channel = AO_CONFIG_DEFAULT_RADIO_CHANNEL; memset(&ao_config.callsign, '\0', sizeof (ao_config.callsign)); memcpy(&ao_config.callsign, AO_CONFIG_DEFAULT_CALLSIGN, sizeof(AO_CONFIG_DEFAULT_CALLSIGN) - 1); + ao_config_dirty = 1; } if (ao_config.minor < AO_CONFIG_MINOR) { /* Fixups for minor version 1 */ @@ -104,6 +107,8 @@ _ao_config_get(void) ao_config.radio_setting = ao_config.radio_cal; if (ao_config.minor < 8) ao_config.radio_enable = TRUE; + if (ao_config.minor < 9) + memset(&ao_config.aes_key, '\0', AO_AES_LEN); ao_config.minor = AO_CONFIG_MINOR; ao_config_dirty = 1; } @@ -414,6 +419,33 @@ ao_config_radio_enable_set(void) __reentrant _ao_config_edit_finish(); } +#if HAS_AES +void +ao_config_key_show(void) __reentrant +{ + uint8_t i; + printf("AES key: "); + for (i = 0; i < AO_AES_LEN; i++) + printf ("%02x", ao_config.aes_key[i]); + printf("\n"); +} + +void +ao_config_key_set(void) __reentrant +{ + uint8_t i; + + _ao_config_edit_start(); + for (i = 0; i < AO_AES_LEN; i++) { + ao_cmd_hexbyte(); + if (ao_cmd_status != ao_cmd_success) + break; + ao_config.aes_key[i] = ao_cmd_lex_i; + } + _ao_config_edit_finish(); +} +#endif + struct ao_config_var { __code char *str; void (*set)(void) __reentrant; @@ -461,6 +493,10 @@ __code struct ao_config_var ao_config_vars[] = { #if HAS_ACCEL { "o <0 antenna up, 1 antenna down>\0Set pad orientation", ao_config_pad_orientation_set,ao_config_pad_orientation_show }, +#endif +#if HAS_AES + { "k <32 hex digits>\0Set AES encryption key", + ao_config_key_set, ao_config_key_show }, #endif { "s\0Show", ao_config_show, 0 }, diff --git a/src/core/ao_task.c b/src/core/ao_task.c index 32826114..a19a6a6f 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -107,7 +107,6 @@ ao_sleep(__xdata void *wchan) ao_cur_task->wchan = wchan; ); ao_yield(); - ao_cur_task->alarm = 0; if (ao_cur_task->wchan) { ao_cur_task->wchan = NULL; return 1; @@ -135,6 +134,12 @@ ao_alarm(uint16_t delay) ao_cur_task->alarm = 1; } +void +ao_clear_alarm(void) +{ + ao_cur_task->alarm = 0; +} + void ao_exit(void) { -- cgit v1.2.3 From 8a1cbef0e316e38c80b71d3bac15641fe56e0a99 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 27 Aug 2011 13:27:28 -0700 Subject: altos: Add HAS_LOG for products that log to eeprom Some products have eeprom for config, but none for logging (like telelaunch) Signed-off-by: Keith Packard --- src/core/ao_cmd.c | 2 +- src/core/ao_config.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/core/ao_cmd.c') diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 9e14c221..d0a46633 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -237,7 +237,7 @@ version(void) printf("manufacturer %s\n", ao_manufacturer); printf("product %s\n", ao_product); printf("serial-number %u\n", ao_serial_number); -#if HAS_EEPROM +#if HAS_LOG printf("log-format %u\n", ao_log_format); #endif printf("software-version %s\n", ao_version); diff --git a/src/core/ao_config.c b/src/core/ao_config.c index 28854ab5..a653bed2 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -308,7 +308,7 @@ ao_config_radio_cal_set(void) __reentrant _ao_config_edit_finish(); } -#if HAS_EEPROM && HAS_FLIGHT +#if HAS_LOG void ao_config_log_show(void) __reentrant { @@ -336,7 +336,7 @@ ao_config_log_set(void) __reentrant _ao_config_edit_finish(); } } -#endif /* HAS_EEPROM && HAS_FLIGHT */ +#endif /* HAS_LOG */ #if HAS_IGNITE void @@ -482,7 +482,7 @@ __code struct ao_config_var ao_config_vars[] = { #endif /* HAS_ACCEL */ { "f \0Radio calib (cal = rf/(xtal/2^16))", ao_config_radio_cal_set, ao_config_radio_cal_show }, -#if HAS_EEPROM && HAS_FLIGHT +#if HAS_LOG { "l \0Flight log size in kB", ao_config_log_set, ao_config_log_show }, #endif -- cgit v1.2.3 From 258b75498916183ed250d3abb3282fe3d843e7a1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 7 Oct 2011 09:53:09 -0600 Subject: altos: Write xdata versions of memory functions These are significantly smaller than the general pointer versions from libc on the cc1111. Signed-off-by: Keith Packard Conflicts: src/Makefile.proto src/cc1111/ao_adc.c src/cc1111/ao_packet_master.c src/core/ao.h Fix up the new makefiles --- src/cc1111/ao_adc.c | 2 +- src/cc1111/ao_arch.h | 17 +++++++++++++++++ src/cc1111/ao_intflash.c | 2 +- src/cc1111/ao_packet.c | 4 ++-- src/cc1111/ao_packet_master.c | 2 +- src/cc1111/ao_packet_slave.c | 2 +- src/core/ao.h | 6 ++++++ src/core/ao_cmd.c | 4 ++-- src/core/ao_config.c | 11 ++++++----- src/core/ao_ee_fake.c | 2 +- src/core/ao_gps_report.c | 4 ++-- src/core/ao_host.h | 4 ++++ src/core/ao_monitor.c | 4 ++-- src/core/ao_telemetry.c | 10 +++++----- src/drivers/ao_25lc1024.c | 6 +++--- src/drivers/ao_at45db161d.c | 6 +++--- src/drivers/ao_gps_skytraq.c | 4 ++-- src/product/Makefile.telebt | 1 + src/product/Makefile.teledongle | 1 + src/product/Makefile.telelaunch | 1 + src/product/Makefile.telemetrum | 1 + src/product/Makefile.telemini | 1 + src/product/Makefile.telenano | 1 + src/test/ao_flight_test.c | 8 ++++++-- src/tidongle/Makefile | 1 + 25 files changed, 72 insertions(+), 33 deletions(-) (limited to 'src/core/ao_cmd.c') diff --git a/src/cc1111/ao_adc.c b/src/cc1111/ao_adc.c index 6aa6e018..1688eceb 100644 --- a/src/cc1111/ao_adc.c +++ b/src/cc1111/ao_adc.c @@ -46,7 +46,7 @@ ao_adc_get(__xdata struct ao_adc *packet) #else uint8_t i = ao_adc_ring_prev(ao_adc_head); #endif - memcpy(packet, &ao_adc_ring[i], sizeof (struct ao_adc)); + ao_xmemcpy(packet, &ao_adc_ring[i], sizeof (struct ao_adc)); } void diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index 8a41791f..02e36189 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -204,4 +204,21 @@ struct ao_adc { #define AO_ADC_RING 32 +/* ao_string.c */ + +void +_ao_xmemcpy(__xdata uint8_t *dst, __xdata uint8_t *src, uint8_t count); + +#define ao_xmemcpy(d,s,c) _ao_xmemcpy((__xdata uint8_t *) (d), (__xdata uint8_t *) (s), (c)) + +void +_ao_xmemset(__xdata uint8_t *dst, uint8_t value, uint8_t count); + +#define ao_xmemset(d,v,c) _ao_xmemset((__xdata uint8_t *) (d), (v), (c)) + +int8_t +_ao_xmemcmp(__xdata uint8_t *a, __xdata uint8_t *b, uint8_t count); + +#define ao_xmemcmp(d,s,c) _ao_xmemcmp((__xdata uint8_t *) (d), (__xdata uint8_t *) (s), (c)) + #endif /* _AO_ARCH_H_ */ diff --git a/src/cc1111/ao_intflash.c b/src/cc1111/ao_intflash.c index d76d954e..632e2a85 100644 --- a/src/cc1111/ao_intflash.c +++ b/src/cc1111/ao_intflash.c @@ -180,7 +180,7 @@ ao_storage_device_read(uint32_t pos, __xdata void *d, uint16_t len) __reentrant { if (pos >= ao_storage_total || pos + len > ao_storage_total) return 0; - memcpy(d, ao_intflash+pos, len); + ao_xmemcpy(d, ao_intflash+pos, len); return 1; } diff --git a/src/cc1111/ao_packet.c b/src/cc1111/ao_packet.c index f627e02b..37ba92e0 100644 --- a/src/cc1111/ao_packet.c +++ b/src/cc1111/ao_packet.c @@ -35,7 +35,7 @@ ao_packet_send(void) ao_led_on(AO_LED_RED); /* If any tx data is pending then copy it into the tx packet */ if (ao_packet_tx_used && ao_tx_packet.len == 0) { - memcpy(&ao_tx_packet.d, tx_data, ao_packet_tx_used); + ao_xmemcpy(&ao_tx_packet.d, tx_data, ao_packet_tx_used); ao_tx_packet.len = ao_packet_tx_used; ao_tx_packet.seq++; ao_packet_tx_used = 0; @@ -80,7 +80,7 @@ ao_packet_recv(void) /* Copy data to the receive data buffer and set up the * offsets */ - memcpy(rx_data, ao_rx_packet.packet.d, ao_rx_packet.packet.len); + ao_xmemcpy(rx_data, ao_rx_packet.packet.d, ao_rx_packet.packet.len); ao_packet_rx_used = 0; ao_packet_rx_len = ao_rx_packet.packet.len; diff --git a/src/cc1111/ao_packet_master.c b/src/cc1111/ao_packet_master.c index 0d0be30e..ab19f979 100644 --- a/src/cc1111/ao_packet_master.c +++ b/src/cc1111/ao_packet_master.c @@ -81,7 +81,7 @@ ao_packet_master(void) ao_packet_master_delay = AO_PACKET_MASTER_DELAY_SHORT; while (ao_packet_enable) { uint8_t r; - memcpy(ao_tx_packet.callsign, ao_config.callsign, AO_MAX_CALLSIGN); + ao_xmemcpy(ao_tx_packet.callsign, ao_config.callsign, AO_MAX_CALLSIGN); ao_packet_send(); if (ao_tx_packet.len) ao_packet_master_busy(); diff --git a/src/cc1111/ao_packet_slave.c b/src/cc1111/ao_packet_slave.c index d7cafa68..fd5d443e 100644 --- a/src/cc1111/ao_packet_slave.c +++ b/src/cc1111/ao_packet_slave.c @@ -24,7 +24,7 @@ ao_packet_slave(void) ao_tx_packet.len = AO_PACKET_SYN; while (ao_packet_enable) { if (ao_packet_recv()) { - memcpy(&ao_tx_packet.callsign, &ao_rx_packet.packet.callsign, AO_MAX_CALLSIGN); + ao_xmemcpy(&ao_tx_packet.callsign, &ao_rx_packet.packet.callsign, AO_MAX_CALLSIGN); #if HAS_FLIGHT ao_flight_force_idle = TRUE; #endif diff --git a/src/core/ao.h b/src/core/ao.h index 04610fea..c0474729 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -1817,4 +1817,10 @@ ao_log_single(void); #define AO_TELEPYRO_NUM_ADC 9 +#ifndef ao_xmemcpy +#define ao_xmemcpy(d,s,c) memcpy(d,s,c) +#define ao_xmemset(d,v,c) memset(d,v,c) +#define ao_xmemcmp(d,s,c) memcmp(d,s,c) +#endif + #endif /* _AO_H_ */ diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 2b64b8ca..0c902f6b 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -265,8 +265,8 @@ help(void) cs = ao_cmds[cmds]; for (cmd = 0; cs[cmd].func; cmd++) printf("%-45s %s\n", - cs[cmd].help, - cs[cmd].help+1+strlen(cs[cmd].help)); + cs[cmd].help, + cs[cmd].help+1+strlen(cs[cmd].help)); } } diff --git a/src/core/ao_config.c b/src/core/ao_config.c index a653bed2..08cc79b1 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -78,8 +78,8 @@ _ao_config_get(void) /* Version 0 stuff */ ao_config.main_deploy = AO_CONFIG_DEFAULT_MAIN_DEPLOY; ao_config.radio_channel = AO_CONFIG_DEFAULT_RADIO_CHANNEL; - memset(&ao_config.callsign, '\0', sizeof (ao_config.callsign)); - memcpy(&ao_config.callsign, AO_CONFIG_DEFAULT_CALLSIGN, + ao_xmemset(&ao_config.callsign, '\0', sizeof (ao_config.callsign)); + ao_xmemcpy(&ao_config.callsign, AO_CONFIG_DEFAULT_CALLSIGN, sizeof(AO_CONFIG_DEFAULT_CALLSIGN) - 1); ao_config_dirty = 1; } @@ -148,7 +148,7 @@ ao_config_callsign_set(void) __reentrant uint8_t c; static __xdata char callsign[AO_MAX_CALLSIGN + 1]; - memset(callsign, '\0', sizeof callsign); + ao_xmemset(callsign, '\0', sizeof callsign); ao_cmd_white(); c = 0; while (ao_cmd_lex_c != '\n') { @@ -161,7 +161,7 @@ ao_config_callsign_set(void) __reentrant if (ao_cmd_status != ao_cmd_success) return; _ao_config_edit_start(); - memcpy(&ao_config.callsign, &callsign, + ao_xmemcpy(&ao_config.callsign, &callsign, AO_MAX_CALLSIGN + 1); _ao_config_edit_finish(); } @@ -535,7 +535,8 @@ ao_config_help(void) __reentrant for (cmd = 0; ao_config_vars[cmd].str != NULL; cmd++) printf("%-20s %s\n", ao_config_vars[cmd].str, - ao_config_vars[cmd].str+1+strlen(ao_config_vars[cmd].str)); + ao_config_vars[cmd].str+1+ + strlen(ao_config_vars[cmd].str)); } static void diff --git a/src/core/ao_ee_fake.c b/src/core/ao_ee_fake.c index b0c1d61e..7fcfcab0 100644 --- a/src/core/ao_ee_fake.c +++ b/src/core/ao_ee_fake.c @@ -32,6 +32,6 @@ ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant uint8_t ao_ee_read_config(uint8_t *buf, uint16_t len) __reentrant { - memset(buf, '\0', len); + ao_xmemset(buf, '\0', len); return 1; } diff --git a/src/core/ao_gps_report.c b/src/core/ao_gps_report.c index e57f8744..c52ef621 100644 --- a/src/core/ao_gps_report.c +++ b/src/core/ao_gps_report.c @@ -27,7 +27,7 @@ ao_gps_report(void) for (;;) { ao_sleep(&ao_gps_data); ao_mutex_get(&ao_gps_mutex); - memcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); + ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data)); ao_mutex_put(&ao_gps_mutex); if (!(gps_data.flags & AO_GPS_VALID)) @@ -72,7 +72,7 @@ ao_gps_tracking_report(void) ao_sleep(&ao_gps_tracking_data); ao_mutex_get(&ao_gps_mutex); gps_log.tick = ao_gps_tick; - memcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data)); + ao_xmemcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data)); ao_mutex_put(&ao_gps_mutex); if (!(n = gps_tracking_data.channels)) diff --git a/src/core/ao_host.h b/src/core/ao_host.h index 65c25fe5..f2b2f0c9 100644 --- a/src/core/ao_host.h +++ b/src/core/ao_host.h @@ -125,3 +125,7 @@ struct ao_config { #define ao_config_get() struct ao_config ao_config = { 250, 16000 }; + +#define ao_xmemcpy(d,s,c) memcpy(d,s,c) +#define ao_xmemset(d,v,c) memset(d,v,c) +#define ao_xmemcmp(d,s,c) memcmp(d,s,c) diff --git a/src/core/ao_monitor.c b/src/core/ao_monitor.c index 56d7604d..1a8bb52a 100644 --- a/src/core/ao_monitor.c +++ b/src/core/ao_monitor.c @@ -94,7 +94,7 @@ ao_monitor_put(void) /* Typical RSSI offset for 38.4kBaud at 433 MHz is 74 */ rssi = (int16_t) (recv_orig.rssi >> 1) - 74; - memcpy(callsign, recv_orig.telemetry_orig.callsign, AO_MAX_CALLSIGN); + ao_xmemcpy(callsign, recv_orig.telemetry_orig.callsign, AO_MAX_CALLSIGN); if (state > ao_flight_invalid) state = ao_flight_invalid; if (recv_orig.status & PKT_APPEND_STATUS_1_CRC_OK) { @@ -171,7 +171,7 @@ ao_monitor_put(void) /* Typical RSSI offset for 38.4kBaud at 433 MHz is 74 */ rssi = (int16_t) (recv_tiny.rssi >> 1) - 74; - memcpy(callsign, recv_tiny.telemetry_tiny.callsign, AO_MAX_CALLSIGN); + ao_xmemcpy(callsign, recv_tiny.telemetry_tiny.callsign, AO_MAX_CALLSIGN); if (state > ao_flight_invalid) state = ao_flight_invalid; if (recv_tiny.status & PKT_APPEND_STATUS_1_CRC_OK) { diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index 26e4e2a0..95e53917 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -131,10 +131,10 @@ ao_send_configuration(void) telemetry.configuration.apogee_delay = ao_config.apogee_delay; telemetry.configuration.main_deploy = ao_config.main_deploy; telemetry.configuration.flight_log_max = ao_config.flight_log_max >> 10; - memcpy (telemetry.configuration.callsign, + ao_xmemcpy (telemetry.configuration.callsign, ao_config.callsign, AO_MAX_CALLSIGN); - memcpy (telemetry.configuration.version, + ao_xmemcpy (telemetry.configuration.version, ao_version, AO_MAX_VERSION); ao_radio_send(&telemetry, sizeof (telemetry)); @@ -150,7 +150,7 @@ ao_send_location(void) { telemetry.generic.type = AO_TELEMETRY_LOCATION; ao_mutex_get(&ao_gps_mutex); - memcpy(&telemetry.location.flags, + ao_xmemcpy(&telemetry.location.flags, &ao_gps_data.flags, 26); ao_mutex_put(&ao_gps_mutex); @@ -167,7 +167,7 @@ ao_send_satellite(void) telemetry.generic.type = AO_TELEMETRY_SATELLITE; ao_mutex_get(&ao_gps_mutex); telemetry.satellite.channels = ao_gps_tracking_data.channels; - memcpy(&telemetry.satellite.sats, + ao_xmemcpy(&telemetry.satellite.sats, &ao_gps_tracking_data.sats, AO_MAX_GPS_TRACKING * sizeof (struct ao_telemetry_satellite_info)); ao_mutex_put(&ao_gps_mutex); @@ -187,7 +187,7 @@ ao_send_companion(void) telemetry.companion.update_period = ao_companion_setup.update_period; telemetry.companion.channels = ao_companion_setup.channels; ao_mutex_get(&ao_companion_mutex); - memcpy(&telemetry.companion.companion_data, + ao_xmemcpy(&telemetry.companion.companion_data, ao_companion_data, ao_companion_setup.channels * 2); ao_mutex_put(&ao_companion_mutex); diff --git a/src/drivers/ao_25lc1024.c b/src/drivers/ao_25lc1024.c index 738f8ce6..2d047a44 100644 --- a/src/drivers/ao_25lc1024.c +++ b/src/drivers/ao_25lc1024.c @@ -167,7 +167,7 @@ ao_storage_device_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentra ao_ee_flush_internal(); ao_ee_block = block; } - memcpy(ao_ee_data + (uint16_t) (pos & 0xff), buf, len); + ao_xmemcpy(ao_ee_data + (uint16_t) (pos & 0xff), buf, len); ao_ee_block_dirty = 1; } ao_mutex_put(&ao_ee_mutex); return 1; @@ -181,7 +181,7 @@ ao_storage_device_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentran /* Transfer the data */ ao_mutex_get(&ao_ee_mutex); { ao_ee_fill(block); - memcpy(buf, ao_ee_data + (uint16_t) (pos & 0xff), len); + ao_xmemcpy(buf, ao_ee_data + (uint16_t) (pos & 0xff), len); } ao_mutex_put(&ao_ee_mutex); return 1; } @@ -200,7 +200,7 @@ ao_storage_erase(uint32_t pos) __reentrant ao_mutex_get(&ao_ee_mutex); { ao_ee_flush_internal(); ao_ee_block = (uint16_t) (pos >> EE_BLOCK_SHIFT); - memset(ao_ee_data, 0xff, EE_BLOCK_SIZE); + ao_xmemset(ao_ee_data, 0xff, EE_BLOCK_SIZE); ao_ee_block_dirty = 1; } ao_mutex_put(&ao_ee_mutex); return 1; diff --git a/src/drivers/ao_at45db161d.c b/src/drivers/ao_at45db161d.c index aee9877a..6cd689e5 100644 --- a/src/drivers/ao_at45db161d.c +++ b/src/drivers/ao_at45db161d.c @@ -245,7 +245,7 @@ ao_storage_device_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentra ao_flash_flush_internal(); ao_flash_block = block; } - memcpy(ao_flash_data + (uint16_t) (pos & ao_flash_block_mask), + ao_xmemcpy(ao_flash_data + (uint16_t) (pos & ao_flash_block_mask), buf, len); ao_flash_block_dirty = 1; @@ -261,7 +261,7 @@ ao_storage_device_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentran /* Transfer the data */ ao_mutex_get(&ao_flash_mutex); { ao_flash_fill(block); - memcpy(buf, + ao_xmemcpy(buf, ao_flash_data + (uint16_t) (pos & ao_flash_block_mask), len); } ao_mutex_put(&ao_flash_mutex); @@ -282,7 +282,7 @@ ao_storage_erase(uint32_t pos) __reentrant ao_mutex_get(&ao_flash_mutex); { ao_flash_flush_internal(); ao_flash_block = (uint16_t) (pos >> ao_flash_block_shift); - memset(ao_flash_data, 0xff, ao_flash_block_size); + ao_xmemset(ao_flash_data, 0xff, ao_flash_block_size); ao_flash_block_dirty = 1; } ao_mutex_put(&ao_flash_mutex); return 1; diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index 7ac26946..6e65d651 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -265,7 +265,7 @@ ao_nmea_gga() if (!ao_gps_error) { ao_mutex_get(&ao_gps_mutex); ao_gps_tick = ao_gps_next_tick; - memcpy(&ao_gps_data, &ao_gps_next, sizeof (ao_gps_data)); + ao_xmemcpy(&ao_gps_data, &ao_gps_next, sizeof (ao_gps_data)); ao_mutex_put(&ao_gps_mutex); ao_wakeup(&ao_gps_data); } @@ -327,7 +327,7 @@ ao_nmea_gsv(void) ao_gps_tracking_next.channels = 0; else if (done) { ao_mutex_get(&ao_gps_mutex); - memcpy(&ao_gps_tracking_data, &ao_gps_tracking_next, + ao_xmemcpy(&ao_gps_tracking_data, &ao_gps_tracking_next, sizeof(ao_gps_tracking_data)); ao_mutex_put(&ao_gps_mutex); ao_wakeup(&ao_gps_tracking_data); diff --git a/src/product/Makefile.telebt b/src/product/Makefile.telebt index 46c87db0..8f7c7429 100644 --- a/src/product/Makefile.telebt +++ b/src/product/Makefile.telebt @@ -41,6 +41,7 @@ CC1111_SRC = \ ao_radio_cmac.c \ ao_romconfig.c \ ao_serial.c \ + ao_string.c \ ao_timer.c \ ao_usb.c \ _bp.c diff --git a/src/product/Makefile.teledongle b/src/product/Makefile.teledongle index 56182b84..c1b422c0 100644 --- a/src/product/Makefile.teledongle +++ b/src/product/Makefile.teledongle @@ -43,6 +43,7 @@ CC1111_SRC = \ ao_radio.c \ ao_radio_cmac.c \ ao_romconfig.c \ + ao_string.c \ ao_timer.c \ ao_usb.c \ _bp.c diff --git a/src/product/Makefile.telelaunch b/src/product/Makefile.telelaunch index 5da42e46..b40f61a2 100644 --- a/src/product/Makefile.telelaunch +++ b/src/product/Makefile.telelaunch @@ -45,6 +45,7 @@ CC1111_SRC = \ ao_romconfig.c \ ao_serial.c \ ao_spi.c \ + ao_string.c \ ao_timer.c \ ao_usb.c \ _bp.c diff --git a/src/product/Makefile.telemetrum b/src/product/Makefile.telemetrum index 2759ac52..4f4195a9 100644 --- a/src/product/Makefile.telemetrum +++ b/src/product/Makefile.telemetrum @@ -54,6 +54,7 @@ CC1111_SRC = \ ao_radio.c \ ao_romconfig.c \ ao_serial.c \ + ao_string.c \ ao_spi.c \ ao_timer.c \ ao_usb.c \ diff --git a/src/product/Makefile.telemini b/src/product/Makefile.telemini index 7f251897..9f90b01f 100644 --- a/src/product/Makefile.telemini +++ b/src/product/Makefile.telemini @@ -45,6 +45,7 @@ CC1111_SRC = \ ao_packet_slave.c \ ao_radio.c \ ao_romconfig.c \ + ao_string.c \ ao_timer.c \ _bp.c diff --git a/src/product/Makefile.telenano b/src/product/Makefile.telenano index c47e95ff..eff3ea97 100644 --- a/src/product/Makefile.telenano +++ b/src/product/Makefile.telenano @@ -44,6 +44,7 @@ CC1111_SRC = \ ao_packet_slave.c \ ao_radio.c \ ao_romconfig.c \ + ao_string.c \ ao_timer.c \ _bp.c diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 56733c89..921d44e7 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -173,6 +173,10 @@ struct ao_cmds { const char *help; }; +#define ao_xmemcpy(d,s,c) memcpy(d,s,c) +#define ao_xmemset(d,v,c) memset(d,v,c) +#define ao_xmemcmp(d,s,c) memcmp(d,s,c) + #include "ao_convert.c" struct ao_config { @@ -542,7 +546,7 @@ ao_sleep(void *wchan) ao_flight_started = 1; } } else if (nword == 2 && strcmp(words[0], "TELEM") == 0) { - char *hex = words[1]; + __xdata char *hex = words[1]; char elt[3]; int i, len; uint8_t sum; @@ -574,7 +578,7 @@ ao_sleep(void *wchan) continue; } if (len == 36) { - memcpy(&telem, bytes + 1, 32); + ao_xmemcpy(&telem, bytes + 1, 32); tick = telem.generic.tick; switch (telem.generic.type) { case AO_TELEMETRY_SENSOR_TELEMETRUM: diff --git a/src/tidongle/Makefile b/src/tidongle/Makefile index 057e420b..58b9d735 100644 --- a/src/tidongle/Makefile +++ b/src/tidongle/Makefile @@ -38,6 +38,7 @@ CC1111_SRC = \ ao_radio.c \ ao_radio_cmac.c \ ao_romconfig.c \ + ao_string.c \ ao_timer.c \ ao_usb.c \ _bp.c -- cgit v1.2.3 From 2ba946fea29ff134ffaeaea9d7932f4bd4e953aa Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 12 Nov 2011 18:48:07 -0800 Subject: altos: Export 'ao_cmd_is_white' for use by other code This function tests the current input character. Signed-off-by: Keith Packard --- src/core/ao.h | 3 +++ src/core/ao_cmd.c | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/core/ao_cmd.c') diff --git a/src/core/ao.h b/src/core/ao.h index f57398ce..2139983c 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -349,6 +349,9 @@ ao_cmd_put8(uint8_t v); void ao_cmd_put16(uint16_t v); +uint8_t +ao_cmd_is_white(void); + void ao_cmd_white(void); diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 0c902f6b..14cb7569 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -121,10 +121,16 @@ ao_cmd_put8(uint8_t v) putnibble(v & 0xf); } +uint8_t +ao_cmd_is_white(void) +{ + return ao_cmd_lex_c == ' ' || ao_cmd_lex_c == '\t'; +} + void ao_cmd_white(void) { - while (ao_cmd_lex_c == ' ' || ao_cmd_lex_c == '\t') + while (ao_cmd_is_white()) ao_cmd_lex(); } -- cgit v1.2.3 From c1d12a117b36de7fe8dd992959b890bfd1163e81 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 26 Mar 2012 23:35:35 -0700 Subject: Do radio settings solely by frequency Compute the radio setting needed based on the calibration value provided and the requested frequency. Signed-off-by: Keith Packard --- src/core/ao.h | 8 ++++- src/core/ao_cmd.c | 6 ++-- src/core/ao_config.c | 68 ++++++++++++++++++++++------------------- src/core/ao_freq.c | 52 +++++++++++++++++++++++++++++++ src/product/Makefile.telebt | 3 +- src/product/Makefile.teledongle | 3 +- src/product/Makefile.telelaunch | 3 +- src/product/Makefile.telemetrum | 3 +- src/product/Makefile.telemini | 3 +- src/product/Makefile.telenano | 3 +- src/product/ao_terraui.c | 2 +- src/teleshield-v0.1/Makefile | 3 +- src/teleterra-v0.2/Makefile | 3 +- src/tidongle/Makefile | 3 +- 14 files changed, 117 insertions(+), 46 deletions(-) create mode 100644 src/core/ao_freq.c (limited to 'src/core/ao_cmd.c') diff --git a/src/core/ao.h b/src/core/ao.h index 8c5335c4..ce9a1f70 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -1539,7 +1539,6 @@ ao_igniter_init(void); struct ao_radio_channel { char name[AO_CHANNEL_NAME_LEN]; uint32_t kHz; - uint32_t radio_setting; }; #endif @@ -1559,6 +1558,7 @@ struct ao_config { uint32_t radio_setting; /* minor version 7 */ uint8_t radio_enable; /* minor version 8 */ uint8_t aes_key[AO_AES_LEN]; /* minor version 9 */ + uint32_t frequency; /* minor version 10 */ #if HAS_RADIO_CHANNELS struct ao_radio_channel radio_channels[AO_NUM_CHANNELS]; /* minor version 10 */ #endif @@ -1959,4 +1959,10 @@ ao_battery_init(void); uint32_t ao_sqrt(uint32_t op); +/* + * ao_freq.c + */ + +int32_t ao_freq_to_set(int32_t freq, int32_t cal); + #endif /* _AO_H_ */ diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 14cb7569..cde68b39 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -263,9 +263,9 @@ static __pdata uint8_t ao_ncmds; static void help(void) { - register uint8_t cmds; - register uint8_t cmd; - register __code struct ao_cmds * cs; + __pdata uint8_t cmds; + __pdata uint8_t cmd; + __code struct ao_cmds * __pdata cs; for (cmds = 0; cmds < ao_ncmds; cmds++) { cs = ao_cmds[cmds]; diff --git a/src/core/ao_config.c b/src/core/ao_config.c index 86bbc473..6fcebe1e 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -64,6 +64,12 @@ ao_config_put(void) } #endif +static void +ao_config_set_radio(void) +{ + ao_config.radio_setting = ao_freq_to_set(ao_config.frequency, ao_config.radio_cal); +} + static void _ao_config_get(void) { @@ -105,24 +111,23 @@ _ao_config_get(void) ao_config.ignite_mode = AO_CONFIG_DEFAULT_IGNITE_MODE; if (ao_config.minor < 6) ao_config.pad_orientation = AO_CONFIG_DEFAULT_PAD_ORIENTATION; - if (ao_config.minor < 7) - ao_config.radio_setting = ao_config.radio_cal; if (ao_config.minor < 8) ao_config.radio_enable = TRUE; if (ao_config.minor < 9) memset(&ao_config.aes_key, 0, AO_AES_LEN); -#if HAS_RADIO_CHANNELS if (ao_config.minor < 10) { + ao_config.frequency = 434550; +#if HAS_RADIO_CHANNELS ao_xmemset(&ao_config.radio_channels, '\0', sizeof (ao_config.radio_channels)); ao_xmemcpy(&ao_config.radio_channels[0].name[0], CODE_TO_XDATA("Channel 0"), sizeof("Channel 0")); ao_config.radio_channels[0].kHz = 434550; - ao_config.radio_channels[0].radio_setting = ao_config.radio_cal; - } #endif + } ao_config.minor = AO_CONFIG_MINOR; ao_config_dirty = 1; } + ao_config_set_radio(); ao_config_loaded = 1; } @@ -196,6 +201,26 @@ ao_config_radio_channel_set(void) __reentrant ao_radio_recv_abort(); } +void +ao_config_frequency_show(void) __reentrant +{ + printf("Frequency: %ld\n", + ao_config.frequency); +} + +void +ao_config_frequency_set(void) __reentrant +{ + ao_cmd_decimal(); + if (ao_cmd_status != ao_cmd_success) + return; + _ao_config_edit_start(); + ao_config.frequency = ao_cmd_lex_u32; + ao_config_set_radio(); + _ao_config_edit_finish(); + ao_radio_recv_abort(); +} + #if HAS_ADC void @@ -315,7 +340,8 @@ ao_config_radio_cal_set(void) __reentrant if (ao_cmd_status != ao_cmd_success) return; _ao_config_edit_start(); - ao_config.radio_setting = ao_config.radio_cal = ao_cmd_lex_u32; + ao_config.radio_cal = ao_cmd_lex_u32; + ao_config_set_radio(); _ao_config_edit_finish(); } @@ -394,25 +420,6 @@ ao_config_pad_orientation_set(void) __reentrant } #endif -void -ao_config_radio_setting_show(void) __reentrant -{ - printf("Radio setting: %ld\n", ao_config.radio_setting); -} - -void -ao_config_radio_setting_set(void) __reentrant -{ - ao_cmd_decimal(); - if (ao_cmd_status != ao_cmd_success) - return; - _ao_config_edit_start(); - ao_config.radio_setting = ao_cmd_lex_u32; - ao_config.radio_channel = 0; - _ao_config_edit_finish(); - ao_radio_recv_abort(); -} - void ao_config_radio_enable_show(void) __reentrant { @@ -464,11 +471,10 @@ ao_config_radio_config_show(void) __reentrant uint8_t i; for (i = 0; i < AO_NUM_CHANNELS; i++) if (ao_config.radio_channels[i].name[0]) { - printf("%2d %-16.16s %ld %ld\n", + printf("%2d %-16.16s %ld\n", i, ao_config.radio_channels[i].name, - ao_config.radio_channels[i].kHz, - ao_config.radio_channels[i].radio_setting); + ao_config.radio_channels[i].kHz); } } @@ -498,8 +504,6 @@ ao_config_radio_config_set(void) __reentrant } ao_cmd_decimal(); ch->kHz = ao_cmd_lex_u32; - ao_cmd_decimal(); - ch->radio_setting = ao_cmd_lex_u32; _ao_config_edit_finish(); } #endif @@ -528,10 +532,10 @@ __code struct ao_config_var ao_config_vars[] = { #endif /* HAS_ADC */ { "r \0Radio channel (freq = 434.550 + chan * .1)", ao_config_radio_channel_set, ao_config_radio_channel_show }, + { "F \0Frequency (kHz)", + ao_config_frequency_set, ao_config_frequency_show }, { "c \0Callsign (8 char max)", ao_config_callsign_set, ao_config_callsign_show }, - { "R \0Radio freq control (freq = 434.550 * setting/cal)", - ao_config_radio_setting_set, ao_config_radio_setting_show }, { "e <0 disable, 1 enable>\0Enable telemetry and RDF", ao_config_radio_enable_set, ao_config_radio_enable_show }, #if HAS_ACCEL diff --git a/src/core/ao_freq.c b/src/core/ao_freq.c new file mode 100644 index 00000000..13bcb383 --- /dev/null +++ b/src/core/ao_freq.c @@ -0,0 +1,52 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include + +/* + * The provided 'calibration' value is + * that needed to tune the radio to precisely 434550kHz. + * Use that to 'walk' to the target frequency by following + * a 'bresenham' line from 434550kHz to the target + * frequency, and updating the radio setting along the way + */ + +int32_t ao_freq_to_set(int32_t freq, int32_t cal) { + __pdata int32_t set = 0; + uint8_t neg = 0; + __pdata int32_t error = -434550 / 2; + + freq -= 434550; + if (freq < 0) { + neg = 1; + freq = -freq; + } + for (;;) { + if (freq == 0 && error <= 0) + break; + if (error > 0) { + error -= 434550; + set++; + } else { + error += cal; + freq--; + } + } + if (neg) + set = -set; + return cal + set; +} diff --git a/src/product/Makefile.telebt b/src/product/Makefile.telebt index ea18ff18..e53aa2c4 100644 --- a/src/product/Makefile.telebt +++ b/src/product/Makefile.telebt @@ -28,7 +28,8 @@ CORE_SRC = \ ao_panic.c \ ao_state.c \ ao_stdio.c \ - ao_task.c + ao_task.c \ + ao_freq.c CC1111_SRC = \ ao_aes.c \ diff --git a/src/product/Makefile.teledongle b/src/product/Makefile.teledongle index cf33d1f1..27e7d24b 100644 --- a/src/product/Makefile.teledongle +++ b/src/product/Makefile.teledongle @@ -31,7 +31,8 @@ CORE_SRC = \ ao_rssi.c \ ao_state.c \ ao_stdio.c \ - ao_task.c + ao_task.c \ + ao_freq.c CC1111_SRC = \ ao_aes.c \ diff --git a/src/product/Makefile.telelaunch b/src/product/Makefile.telelaunch index 97764517..8aab50e0 100644 --- a/src/product/Makefile.telelaunch +++ b/src/product/Makefile.telelaunch @@ -27,7 +27,8 @@ CORE_SRC = \ ao_panic.c \ ao_stdio.c \ ao_storage.c \ - ao_task.c + ao_task.c \ + ao_freq.c CC1111_SRC = \ ao_adc.c \ diff --git a/src/product/Makefile.telemetrum b/src/product/Makefile.telemetrum index 52c723ca..e4f55f88 100644 --- a/src/product/Makefile.telemetrum +++ b/src/product/Makefile.telemetrum @@ -40,7 +40,8 @@ CORE_SRC = \ ao_log.c \ ao_log_big.c \ ao_report.c \ - ao_telemetry.c + ao_telemetry.c \ + ao_freq.c CC1111_SRC = \ ao_adc.c \ diff --git a/src/product/Makefile.telemini b/src/product/Makefile.telemini index 75beeae4..82ec42a2 100644 --- a/src/product/Makefile.telemini +++ b/src/product/Makefile.telemini @@ -33,7 +33,8 @@ CORE_SRC = \ ao_stdio.c \ ao_storage.c \ ao_task.c \ - ao_telemetry.c + ao_telemetry.c \ + ao_freq.c CC1111_SRC = \ ao_adc.c \ diff --git a/src/product/Makefile.telenano b/src/product/Makefile.telenano index b30ca789..cf27527c 100644 --- a/src/product/Makefile.telenano +++ b/src/product/Makefile.telenano @@ -33,7 +33,8 @@ CORE_SRC = \ ao_stdio.c \ ao_storage.c \ ao_task.c \ - ao_telemetry.c + ao_telemetry.c \ + ao_freq.c CC1111_SRC = \ ao_adc.c \ diff --git a/src/product/ao_terraui.c b/src/product/ao_terraui.c index 05157cb1..9b40c42a 100644 --- a/src/product/ao_terraui.c +++ b/src/product/ao_terraui.c @@ -459,7 +459,7 @@ ao_terraui_config(void) __reentrant for (chan = 0; chan < AO_NUM_CHANNELS; chan++) - if (ao_config.radio_channels[chan].radio_setting == ao_config.radio_setting) + if (ao_config.radio_channels[chan].kHz == ao_config.frequency) break; if (chan == AO_NUM_CHANNELS) chan = 0; diff --git a/src/teleshield-v0.1/Makefile b/src/teleshield-v0.1/Makefile index a21a6052..44780476 100644 --- a/src/teleshield-v0.1/Makefile +++ b/src/teleshield-v0.1/Makefile @@ -41,7 +41,8 @@ CORE_SRC = \ ao_state.c \ ao_storage.c \ ao_stdio.c \ - ao_task.c + ao_task.c \ + ao_freq.c CC1111_SRC = \ ao_dbg.c \ diff --git a/src/teleterra-v0.2/Makefile b/src/teleterra-v0.2/Makefile index 0747bfbf..4967d187 100644 --- a/src/teleterra-v0.2/Makefile +++ b/src/teleterra-v0.2/Makefile @@ -28,7 +28,8 @@ CORE_SRC = \ ao_sqrt.c \ ao_stdio.c \ ao_storage.c \ - ao_task.c + ao_task.c \ + ao_freq.c CC1111_SRC = \ ao_battery.c \ diff --git a/src/tidongle/Makefile b/src/tidongle/Makefile index 698d612c..149b00c5 100644 --- a/src/tidongle/Makefile +++ b/src/tidongle/Makefile @@ -26,7 +26,8 @@ CORE_SRC = \ ao_rssi.c \ ao_state.c \ ao_stdio.c \ - ao_task.c + ao_task.c \ + ao_freq.c CC1111_SRC = \ ao_aes.c \ -- cgit v1.2.3 From 41a8383ccd29351f3a88a374f9456d6efb71b9a0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Apr 2012 00:22:41 -0700 Subject: altos: Save memory in ao_cmd.c Shrink a couple of help strings move a variable in ao_cmd from data to pdata. Signed-off-by: Keith Packard --- src/core/ao_cmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/ao_cmd.c') diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index cde68b39..fdc70007 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -300,7 +300,7 @@ ao_cmd_register(__code struct ao_cmds *cmds) void ao_cmd(void) { - char c; + __pdata char c; uint8_t cmd, cmds; __code struct ao_cmds * __xdata cs; void (*__xdata func)(void); @@ -336,8 +336,8 @@ __xdata struct ao_task ao_cmd_task; __code struct ao_cmds ao_base_cmds[] = { { help, "?\0Help" }, - { ao_task_info, "T\0Show tasks" }, - { echo, "E <0 off, 1 on>\0Set echo mode" }, + { ao_task_info, "T\0Tasks" }, + { echo, "E <0 off, 1 on>\0Echo" }, { ao_reboot, "r eboot\0Reboot" }, { version, "v\0Version" }, { 0, NULL }, -- cgit v1.2.3 From e687a9bafc696998b47fd0300fbc89dece09509c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 4 Jun 2012 20:52:38 -0700 Subject: altos: Make 'v' command dump pressure sensor ROM values Avoids needing a new command Signed-off-by: Keith Packard --- src/core/ao_cmd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/core/ao_cmd.c') diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index fdc70007..40bb476c 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -251,6 +251,9 @@ version(void) printf("serial-number %u\n", ao_serial_number); #if HAS_LOG printf("log-format %u\n", ao_log_format); +#endif +#if HAS_MS5607 + ao_ms5607_info(); #endif printf("software-version %s\n", ao_version); } -- cgit v1.2.3 From baf1be1def01266512e67068948bf19b04ead6aa Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 15 Jun 2012 22:23:10 -0700 Subject: Allow product to override maximum number of command lists (NUM_CMDS) Just in case some product wants to save memory, or have more. Signed-off-by: Keith Packard --- src/core/ao_cmd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/core/ao_cmd.c') diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 40bb476c..fbf0c347 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -258,7 +258,9 @@ version(void) printf("software-version %s\n", ao_version); } +#ifndef NUM_CMDS #define NUM_CMDS 11 +#endif static __code struct ao_cmds *__xdata (ao_cmds[NUM_CMDS]); static __pdata uint8_t ao_ncmds; -- cgit v1.2.3 From aafa8859ecb27383f697b98f6991643b44f4721a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 10 Jul 2012 20:32:31 -0700 Subject: altos: Save some memory. A few minor space savings in ao_cmd.c and ao_config.c. Don't build unused conversion functions ao_altitude_to_pres and ao_temp_to_dC Signed-off-by: Keith Packard --- src/core/ao_cmd.c | 24 +++++++++++++----------- src/core/ao_config.c | 26 ++++++++++++++------------ src/core/ao_convert.c | 4 ++++ src/core/ao_convert_test.c | 5 +++-- src/test/ao_flight_test.c | 1 + 5 files changed, 35 insertions(+), 25 deletions(-) (limited to 'src/core/ao_cmd.c') diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index fbf0c347..05dbfb51 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -36,10 +36,16 @@ put_string(__code char *s) putchar(c); } +static void +backspace(void) +{ + put_string ("\010 \010"); +} + static void readline(void) { - __pdata char c; + char c; if (ao_echo()) put_string("> "); cmd_len = 0; @@ -50,7 +56,7 @@ readline(void) if (c == '\010' || c == '\177') { if (cmd_len != 0) { if (ao_echo()) - put_string("\010 \010"); + backspace(); --cmd_len; } continue; @@ -60,7 +66,7 @@ readline(void) if (c == '\025') { while (cmd_len != 0) { if (ao_echo()) - put_string("\010 \010"); + backspace(); --cmd_len; } continue; @@ -76,11 +82,8 @@ readline(void) break; } - if (cmd_len >= CMD_LEN - 2) { - if (ao_echo()) - putchar('\007'); + if (cmd_len >= CMD_LEN - 2) continue; - } cmd_line[cmd_len++] = c; if (ao_echo()) putchar(c); @@ -271,13 +274,12 @@ help(void) __pdata uint8_t cmds; __pdata uint8_t cmd; __code struct ao_cmds * __pdata cs; + const char *h; for (cmds = 0; cmds < ao_ncmds; cmds++) { cs = ao_cmds[cmds]; - for (cmd = 0; cs[cmd].func; cmd++) - printf("%-45s %s\n", - cs[cmd].help, - cs[cmd].help+1+strlen(cs[cmd].help)); + for (cmd = 0; (h = cs[cmd].help); cmd++) + printf("%-45s %s\n", h, h + 1 + strlen(h)); } } diff --git a/src/core/ao_config.c b/src/core/ao_config.c index cc580d66..e0dabcd9 100644 --- a/src/core/ao_config.c +++ b/src/core/ao_config.c @@ -78,6 +78,8 @@ ao_config_set_radio(void) static void _ao_config_get(void) { + uint8_t minor; + if (ao_config_loaded) return; #if HAS_EEPROM @@ -97,37 +99,37 @@ _ao_config_get(void) ao_xmemset(&ao_config.callsign, '\0', sizeof (ao_config.callsign)); ao_xmemcpy(&ao_config.callsign, CODE_TO_XDATA(AO_CONFIG_DEFAULT_CALLSIGN), sizeof(AO_CONFIG_DEFAULT_CALLSIGN) - 1); - ao_config_dirty = 1; } - if (ao_config.minor != AO_CONFIG_MINOR) { + minor = ao_config.minor; + if (minor != AO_CONFIG_MINOR) { /* Fixups for minor version 1 */ - if (ao_config.minor < 1) + if (minor < 1) ao_config.apogee_delay = AO_CONFIG_DEFAULT_APOGEE_DELAY; /* Fixups for minor version 2 */ - if (ao_config.minor < 2) { + if (minor < 2) { ao_config.accel_plus_g = 0; ao_config.accel_minus_g = 0; } /* Fixups for minor version 3 */ #if HAS_RADIO - if (ao_config.minor < 3) + if (minor < 3) ao_config.radio_cal = ao_radio_cal; #endif /* Fixups for minor version 4 */ - if (ao_config.minor < 4) + if (minor < 4) ao_config.flight_log_max = AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX; /* Fixupes for minor version 5 */ - if (ao_config.minor < 5) + if (minor < 5) ao_config.ignite_mode = AO_CONFIG_DEFAULT_IGNITE_MODE; - if (ao_config.minor < 6) + if (minor < 6) ao_config.pad_orientation = AO_CONFIG_DEFAULT_PAD_ORIENTATION; - if (ao_config.minor < 8) + if (minor < 8) ao_config.radio_enable = TRUE; - if (ao_config.minor < 9) + if (minor < 9) ao_xmemset(&ao_config.aes_key, '\0', AO_AES_LEN); - if (ao_config.minor < 10) + if (minor < 10) ao_config.frequency = 434550; - if (ao_config.minor < 11) + if (minor < 11) ao_config.apogee_lockout = 0; ao_config.minor = AO_CONFIG_MINOR; ao_config_dirty = 1; diff --git a/src/core/ao_convert.c b/src/core/ao_convert.c index 0969f107..aa9b5f48 100644 --- a/src/core/ao_convert.c +++ b/src/core/ao_convert.c @@ -41,6 +41,7 @@ ao_pres_to_altitude(int16_t pres) __reentrant (int32_t) altitude_table[o+1] * part + (ALT_FRAC_SCALE >> 1)) >> ALT_FRAC_BITS; } +#if AO_NEED_ALTITUDE_TO_PRES int16_t ao_altitude_to_pres(int16_t alt) __reentrant { @@ -66,7 +67,9 @@ ao_altitude_to_pres(int16_t alt) __reentrant pres = 0; return (int16_t) pres; } +#endif +#if 0 int16_t ao_temp_to_dC(int16_t temp) __reentrant { @@ -83,3 +86,4 @@ ao_temp_to_dC(int16_t temp) __reentrant ret = ((temp - 19791) * 1012L) >> 16; return ret; } +#endif diff --git a/src/core/ao_convert_test.c b/src/core/ao_convert_test.c index e2c28b73..87e76841 100644 --- a/src/core/ao_convert_test.c +++ b/src/core/ao_convert_test.c @@ -17,14 +17,15 @@ #include #define AO_CONVERT_TEST +#define AO_NEED_ALTITUDE_TO_PRES 1 #include "ao_host.h" #include "ao_convert.c" #define STEP 1 -static inline i_abs(int i) { return i < 0 ? -i : i; } +static inline int i_abs(int i) { return i < 0 ? -i : i; } -main () +int main (int argc, char **argv) { int i; int16_t p_to_a, p_to_a_to_p; diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 9bb03d68..a4ef8dc0 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -180,6 +180,7 @@ struct ao_cmds { #define ao_xmemset(d,v,c) memset(d,v,c) #define ao_xmemcmp(d,s,c) memcmp(d,s,c) +#define AO_NEED_ALTITUDE_TO_PRES 1 #include "ao_convert.c" struct ao_config { -- cgit v1.2.3 From 726f47c8a07f060aed930e1d102a1e8b5a5c7aed Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 11 Jul 2012 13:47:25 -0700 Subject: altos: remove optimization for 'help' that confuses cc1111 compiler The cc1111 compiler gets this very wrong and prints piles of garbage Signed-off-by: Keith Packard --- src/core/ao_cmd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/core/ao_cmd.c') diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 05dbfb51..1814cecf 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -278,8 +278,10 @@ help(void) for (cmds = 0; cmds < ao_ncmds; cmds++) { cs = ao_cmds[cmds]; - for (cmd = 0; (h = cs[cmd].help); cmd++) + for (cmd = 0; cs[cmd].func; cmd++) { + h = cs[cmd].help; printf("%-45s %s\n", h, h + 1 + strlen(h)); + } } } -- cgit v1.2.3