From a339a91d64d011add2dfeccd5402af57d932b41a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 21 May 2014 14:38:00 -0700 Subject: [PATCH] altos: Hacks to get telegps v1.0 running Mine is busted, and there are a lot of cc115l kludges in here Signed-off-by: Keith Packard --- src/Makefile | 2 +- src/drivers/ao_cc115l.c | 168 +++++++++++++++--------- src/kernel/ao_distance.c | 122 +++++++++++++++++ src/kernel/ao_distance.h | 25 ++++ src/kernel/ao_log.c | 8 +- src/kernel/ao_log_mega.c | 6 +- src/lpc/ao_spi_lpc.c | 4 +- src/product/ao_tracker.c | 164 +++++++++++++++++++++++ src/telegps-v1.0/.gitignore | 3 + src/telegps-v1.0/Makefile | 90 +++++++++++++ src/telegps-v1.0/ao_pins.h | 149 +++++++++++++++++++++ src/telegps-v1.0/ao_telegps.c | 66 ++++++++++ src/telegps-v1.0/flash-loader/Makefile | 8 ++ src/telegps-v1.0/flash-loader/ao_pins.h | 33 +++++ 14 files changed, 781 insertions(+), 67 deletions(-) create mode 100644 src/kernel/ao_distance.c create mode 100644 src/kernel/ao_distance.h create mode 100644 src/product/ao_tracker.c create mode 100644 src/telegps-v1.0/.gitignore create mode 100644 src/telegps-v1.0/Makefile create mode 100644 src/telegps-v1.0/ao_pins.h create mode 100644 src/telegps-v1.0/ao_telegps.c create mode 100644 src/telegps-v1.0/flash-loader/Makefile create mode 100644 src/telegps-v1.0/flash-loader/ao_pins.h diff --git a/src/Makefile b/src/Makefile index ae128b7c..87db6a68 100644 --- a/src/Makefile +++ b/src/Makefile @@ -30,7 +30,7 @@ ARMM3DIRS=\ telemega-v1.0 telemega-v1.0/flash-loader \ telemetrum-v2.0 telemetrum-v2.0/flash-loader \ megadongle-v0.1 megadongle-v0.1/flash-loader \ - telegps-v0.3 telegps-v0.3/flash-loader \ + telegps-v1.0 telegps-v1.0/flash-loader \ telelco-v0.2 telelco-v0.2/flash-loader \ telescience-v0.2 telescience-v0.2/flash-loader \ teleballoon-v2.0 diff --git a/src/drivers/ao_cc115l.c b/src/drivers/ao_cc115l.c index d9b9a89b..829ac60b 100644 --- a/src/drivers/ao_cc115l.c +++ b/src/drivers/ao_cc115l.c @@ -45,17 +45,70 @@ static uint8_t ao_radio_abort; /* radio operation should abort */ #define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC115L_SPI_BUS) #define ao_radio_duplex(o,i,l) ao_spi_duplex((o), (i), (l), AO_CC115L_SPI_BUS) +#if CC115L_DEBUG struct ao_cc115l_reg { uint16_t addr; char *name; }; -#if CC115L_TRACE +static const struct ao_cc115l_reg ao_cc115l_reg[] = { + { .addr = CC115L_IOCFG2, .name = "IOCFG2" }, + { .addr = CC115L_IOCFG1, .name = "IOCFG1" }, + { .addr = CC115L_IOCFG0, .name = "IOCFG0" }, + { .addr = CC115L_FIFOTHR, .name = "FIFOTHR" }, + { .addr = CC115L_SYNC1, .name = "SYNC1" }, + { .addr = CC115L_SYNC0, .name = "SYNC0" }, + { .addr = CC115L_PKTLEN, .name = "PKTLEN" }, + { .addr = CC115L_PKTCTRL0, .name = "PKTCTRL0" }, + { .addr = CC115L_CHANNR, .name = "CHANNR" }, + { .addr = CC115L_FSCTRL0, .name = "FSCTRL0" }, + { .addr = CC115L_FREQ2, .name = "FREQ2" }, + { .addr = CC115L_FREQ1, .name = "FREQ1" }, + { .addr = CC115L_FREQ0, .name = "FREQ0" }, + { .addr = CC115L_MDMCFG4, .name = "MDMCFG4" }, + { .addr = CC115L_MDMCFG3, .name = "MDMCFG3" }, + { .addr = CC115L_MDMCFG2, .name = "MDMCFG2" }, + { .addr = CC115L_MDMCFG1, .name = "MDMCFG1" }, + { .addr = CC115L_MDMCFG0, .name = "MDMCFG0" }, + { .addr = CC115L_DEVIATN, .name = "DEVIATN" }, + { .addr = CC115L_MCSM1, .name = "MCSM1" }, + { .addr = CC115L_MCSM0, .name = "MCSM0" }, + { .addr = CC115L_RESERVED_0X20, .name = "RESERVED_0X20" }, + { .addr = CC115L_FREND0, .name = "FREND0" }, + { .addr = CC115L_FSCAL3, .name = "FSCAL3" }, + { .addr = CC115L_FSCAL2, .name = "FSCAL2" }, + { .addr = CC115L_FSCAL1, .name = "FSCAL1" }, + { .addr = CC115L_FSCAL0, .name = "FSCAL0" }, + { .addr = CC115L_RESERVED_0X29, .name = "RESERVED_0X29" }, + { .addr = CC115L_RESERVED_0X2A, .name = "RESERVED_0X2A" }, + { .addr = CC115L_RESERVED_0X2B, .name = "RESERVED_0X2B" }, + { .addr = CC115L_TEST2, .name = "TEST2" }, + { .addr = CC115L_TEST1, .name = "TEST1" }, + { .addr = CC115L_TEST0, .name = "TEST0" }, + { .addr = CC115L_PARTNUM, .name = "PARTNUM" }, + { .addr = CC115L_VERSION, .name = "VERSION" }, + { .addr = CC115L_MARCSTATE, .name = "MARCSTATE" }, + { .addr = CC115L_PKTSTATUS, .name = "PKTSTATUS" }, + { .addr = CC115L_TXBYTES, .name = "TXBYTES" }, + { .addr = CC115L_PA, .name = "PA" }, +}; -static const struct ao_cc115l_reg ao_cc115l_reg[]; -static const char *cc115l_state_name[]; +#define AO_NUM_CC115L_REG (sizeof ao_cc115l_reg / sizeof ao_cc115l_reg[0]) + +static const char *cc115l_state_name[8] = { + [CC115L_STATUS_STATE_IDLE] = "IDLE", + [CC115L_STATUS_STATE_TX] = "TX", + [CC115L_STATUS_STATE_FSTXON] = "FSTXON", + [CC115L_STATUS_STATE_CALIBRATE] = "CALIBRATE", + [CC115L_STATUS_STATE_SETTLING] = "SETTLING", + [CC115L_STATUS_STATE_TX_FIFO_UNDERFLOW] = "TX_FIFO_UNDERFLOW", +}; +#endif + +#if CC115L_TRACE enum ao_cc115l_trace_type { + trace_empty, trace_strobe, trace_read, trace_write, @@ -63,14 +116,17 @@ enum ao_cc115l_trace_type { trace_line, }; +static const char trace_type_letter[] = "ESRWDL"; + struct ao_cc115l_trace { enum ao_cc115l_trace_type type; + int16_t time; int16_t addr; int16_t value; const char *comment; }; -#define NUM_TRACE 256 +#define NUM_TRACE 128 static struct ao_cc115l_trace trace[NUM_TRACE]; static int trace_i; @@ -78,12 +134,18 @@ static int trace_disable; static void trace_add(enum ao_cc115l_trace_type type, int16_t addr, int16_t value, const char *comment) { + unsigned int i; if (trace_disable) return; switch (type) { case trace_read: case trace_write: - comment = ao_cc115l_reg[addr].name; + comment = "UNKNOWN"; + for (i = 0; i < AO_NUM_CC115L_REG; i++) + if (ao_cc115l_reg[i].addr == addr) { + comment = ao_cc115l_reg[i].name; + break; + } break; case trace_strobe: comment = cc115l_state_name[(value >> 4) & 0x7]; @@ -91,6 +153,9 @@ static void trace_add(enum ao_cc115l_trace_type type, int16_t addr, int16_t valu default: break; } + if (comment == NULL) + comment = "no comment"; + trace[trace_i].time = ao_time(); trace[trace_i].type = type; trace[trace_i].addr = addr; trace[trace_i].value = value; @@ -98,6 +163,29 @@ static void trace_add(enum ao_cc115l_trace_type type, int16_t addr, int16_t valu if (++trace_i == NUM_TRACE) trace_i = 0; } + +static void +trace_dump(void) +{ + int i, j; + + for (j = 0; j < NUM_TRACE; j++) { + i = j + trace_i; + if (i >= NUM_TRACE) + i -= NUM_TRACE; + if (trace[i].type != trace_empty) { + printf ("%3d %5d %c addr %04x value %04x comment %s\n", + j, + trace[i].time, + trace_type_letter[trace[i].type], + trace[i].addr, + trace[i].value, + trace[i].comment); + flush(); + } + } +} + #else #define trace_add(t,a,v,c) #endif @@ -131,6 +219,9 @@ ao_radio_reg_write(uint8_t addr, uint8_t value) ao_radio_select(); ao_radio_spi_send(data, 2); ao_radio_deselect(); +#if CC115L_TRACE + (void) ao_radio_reg_read(addr); +#endif } #if UNUSED @@ -610,18 +701,25 @@ ao_radio_rdf_abort(void) ao_wakeup(&ao_radio_wake); } -#define POWER_STEP 0x08 +static uint8_t ao_cc115l_power_on[] = { 0x03, 0x17, 0x50, 0xc5, 0xc0 }; static void ao_radio_stx(void) { uint8_t power; +#if HAS_RADIO_POWER ao_radio_pa_on(); +#endif ao_radio_reg_write(CC115L_PA, 0); ao_radio_strobe(CC115L_STX); +#if HAS_RADIO_POWER for (power = POWER_STEP; power < ao_config.radio_power; power += POWER_STEP) ao_radio_reg_write(CC115L_PA, power); ao_radio_reg_write(CC115L_PA, ao_config.radio_power); +#else + for (power = 0; power < sizeof (ao_cc115l_power_on); power++) + ao_radio_reg_write(CC115L_PA, ao_cc115l_power_on[power]); +#endif } static void @@ -819,59 +917,6 @@ ao_radio_send_aprs(ao_radio_fill_func fill) } #if CC115L_DEBUG -static const char *cc115l_state_name[] = { - [CC115L_STATUS_STATE_IDLE] = "IDLE", - [CC115L_STATUS_STATE_TX] = "TX", - [CC115L_STATUS_STATE_FSTXON] = "FSTXON", - [CC115L_STATUS_STATE_CALIBRATE] = "CALIBRATE", - [CC115L_STATUS_STATE_SETTLING] = "SETTLING", - [CC115L_STATUS_STATE_TX_FIFO_UNDERFLOW] = "TX_FIFO_UNDERFLOW", -}; - -static const struct ao_cc115l_reg ao_cc115l_reg[] = { - { .addr = CC115L_IOCFG2, .name = "IOCFG2" }, - { .addr = CC115L_IOCFG1, .name = "IOCFG1" }, - { .addr = CC115L_IOCFG0, .name = "IOCFG0" }, - { .addr = CC115L_FIFOTHR, .name = "FIFOTHR" }, - { .addr = CC115L_SYNC1, .name = "SYNC1" }, - { .addr = CC115L_SYNC0, .name = "SYNC0" }, - { .addr = CC115L_PKTLEN, .name = "PKTLEN" }, - { .addr = CC115L_PKTCTRL0, .name = "PKTCTRL0" }, - { .addr = CC115L_CHANNR, .name = "CHANNR" }, - { .addr = CC115L_FSCTRL0, .name = "FSCTRL0" }, - { .addr = CC115L_FREQ2, .name = "FREQ2" }, - { .addr = CC115L_FREQ1, .name = "FREQ1" }, - { .addr = CC115L_FREQ0, .name = "FREQ0" }, - { .addr = CC115L_MDMCFG4, .name = "MDMCFG4" }, - { .addr = CC115L_MDMCFG3, .name = "MDMCFG3" }, - { .addr = CC115L_MDMCFG2, .name = "MDMCFG2" }, - { .addr = CC115L_MDMCFG1, .name = "MDMCFG1" }, - { .addr = CC115L_MDMCFG0, .name = "MDMCFG0" }, - { .addr = CC115L_DEVIATN, .name = "DEVIATN" }, - { .addr = CC115L_MCSM1, .name = "MCSM1" }, - { .addr = CC115L_MCSM0, .name = "MCSM0" }, - { .addr = CC115L_RESERVED_0X20, .name = "RESERVED_0X20" }, - { .addr = CC115L_FREND0, .name = "FREND0" }, - { .addr = CC115L_FSCAL3, .name = "FSCAL3" }, - { .addr = CC115L_FSCAL2, .name = "FSCAL2" }, - { .addr = CC115L_FSCAL1, .name = "FSCAL1" }, - { .addr = CC115L_FSCAL0, .name = "FSCAL0" }, - { .addr = CC115L_RESERVED_0X29, .name = "RESERVED_0X29" }, - { .addr = CC115L_RESERVED_0X2A, .name = "RESERVED_0X2A" }, - { .addr = CC115L_RESERVED_0X2B, .name = "RESERVED_0X2B" }, - { .addr = CC115L_TEST2, .name = "TEST2" }, - { .addr = CC115L_TEST1, .name = "TEST1" }, - { .addr = CC115L_TEST0, .name = "TEST0" }, - { .addr = CC115L_PARTNUM, .name = "PARTNUM" }, - { .addr = CC115L_VERSION, .name = "VERSION" }, - { .addr = CC115L_MARCSTATE, .name = "MARCSTATE" }, - { .addr = CC115L_PKTSTATUS, .name = "PKTSTATUS" }, - { .addr = CC115L_TXBYTES, .name = "TXBYTES" }, - { .addr = CC115L_PA, .name = "PA" }, -}; - -#define AO_NUM_CC115L_REG (sizeof ao_cc115l_reg / sizeof ao_cc115l_reg[0]) - static void ao_radio_show(void) { uint8_t status = ao_radio_status(); unsigned int i; @@ -931,6 +976,9 @@ static const struct ao_cmds ao_radio_cmds[] = { { ao_radio_show, "R\0Show CC115L status" }, { ao_radio_beep, "b\0Emit an RDF beacon" }, { ao_radio_packet, "p\0Send a test packet" }, +#if CC115L_TRACE + { trace_dump, "D\0Dump CC115L trace" }, +#endif #endif { 0, NULL } }; @@ -945,6 +993,8 @@ ao_radio_init(void) ao_radio_configured = 0; ao_spi_init_cs (AO_CC115L_SPI_CS_PORT, (1 << AO_CC115L_SPI_CS_PIN)); + ao_enable_output(0, 23, PIN, 1); + #if 0 AO_CC115L_SPI_CS_PORT->bsrr = ((uint32_t) (1 << AO_CC115L_SPI_CS_PIN)); for (i = 0; i < 10000; i++) { diff --git a/src/kernel/ao_distance.c b/src/kernel/ao_distance.c new file mode 100644 index 00000000..ba7d59fe --- /dev/null +++ b/src/kernel/ao_distance.c @@ -0,0 +1,122 @@ +/* + * Copyright © 2014 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 +#include + +static uint32_t +ao_dist(int32_t a, int32_t b) +{ + int32_t d = a - b; + if (d < 0) + d = -d; + return (uint32_t) ((int64_t) d * 111198 / 10000000); +} + +static uint32_t +ao_lat_dist(int32_t lat_a, int32_t lat_b) +{ + return ao_dist(lat_a, lat_b); +} + +static const uint8_t cos_table[] = { + 0, /* 0 */ + 0, /* 1 */ + 0, /* 2 */ + 255, /* 3 */ + 254, /* 4 */ + 253, /* 5 */ + 252, /* 6 */ + 251, /* 7 */ + 249, /* 8 */ + 247, /* 9 */ + 245, /* 10 */ + 243, /* 11 */ + 240, /* 12 */ + 238, /* 13 */ + 235, /* 14 */ + 232, /* 15 */ + 228, /* 16 */ + 225, /* 17 */ + 221, /* 18 */ + 217, /* 19 */ + 213, /* 20 */ + 209, /* 21 */ + 205, /* 22 */ + 200, /* 23 */ + 195, /* 24 */ + 190, /* 25 */ + 185, /* 26 */ + 180, /* 27 */ + 175, /* 28 */ + 169, /* 29 */ + 163, /* 30 */ + 158, /* 31 */ + 152, /* 32 */ + 145, /* 33 */ + 139, /* 34 */ + 133, /* 35 */ + 126, /* 36 */ + 120, /* 37 */ + 113, /* 38 */ + 106, /* 39 */ + 100, /* 40 */ + 93, /* 41 */ + 86, /* 42 */ + 79, /* 43 */ + 71, /* 44 */ + 64, /* 45 */ + 57, /* 46 */ + 49, /* 47 */ + 42, /* 48 */ + 35, /* 49 */ + 27, /* 50 */ + 20, /* 51 */ + 12, /* 52 */ + 5, /* 53 */ + 1, /* 54 */ +}; + +static uint32_t +ao_lon_dist(int32_t lon_a, int32_t lon_b) +{ + uint8_t c = cos_table[lon_a >> 24]; + uint32_t lon_dist; + + /* check if it's shorter to go the other way around */ + if (lon_a < lon_b - 1800000000) + lon_a += 3600000000; + lon_dist = ao_dist(lon_a, lon_b); + if (c) { + if (lon_dist & 0x7f800000) + lon_dist = (lon_dist >> 8) * c; + else + lon_dist = (lon_dist * (int16_t) c) >> 8; + } + return lon_dist; +} + +static uint32_t sqr(uint32_t x) { return x * x; } + +uint32_t +ao_distance(int32_t lat_a, int32_t lon_a, int32_t lat_b, int32_t lon_b) +{ + uint32_t lat_dist = ao_lat_dist(lat_a, lat_b); + uint32_t lon_dist = ao_lon_dist(lon_a, lon_b); + + return ao_sqrt (sqr(lat_dist) + sqr(lon_dist)); +} diff --git a/src/kernel/ao_distance.h b/src/kernel/ao_distance.h new file mode 100644 index 00000000..6762434e --- /dev/null +++ b/src/kernel/ao_distance.h @@ -0,0 +1,25 @@ +/* + * Copyright © 2014 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_DISTANCE_H_ +#define _AO_DISTANCE_H_ +#include + +uint32_t +ao_distance(int32_t lat_a, int32_t lon_a, int32_t lat_b, int32_t lon_b); + +#endif /* _AO_DISTANCE_H_ */ diff --git a/src/kernel/ao_log.c b/src/kernel/ao_log.c index 20febefe..d60485e0 100644 --- a/src/kernel/ao_log.c +++ b/src/kernel/ao_log.c @@ -196,7 +196,11 @@ ao_log_full(void) return ao_log_current_pos == ao_log_end_pos; } -#if HAS_ADC +#ifndef LOG_ADC +#define LOG_ADC HAS_ADC +#endif + +#if LOG_ADC static __xdata struct ao_task ao_log_task; #endif @@ -284,7 +288,7 @@ ao_log_init(void) #ifndef HAS_ADC #error Define HAS_ADC for ao_log.c #endif -#if HAS_ADC +#if LOG_ADC /* Create a task to log events to eeprom */ ao_add_task(&ao_log_task, ao_log, "log"); #endif diff --git a/src/kernel/ao_log_mega.c b/src/kernel/ao_log_mega.c index 768947d5..8997fd05 100644 --- a/src/kernel/ao_log_mega.c +++ b/src/kernel/ao_log_mega.c @@ -65,7 +65,7 @@ ao_log_dump_check_data(void) return 1; } -#if HAS_ADC +#if HAS_FLIGHT static __data uint8_t ao_log_data_pos; /* a hack to make sure that ao_log_megas fill the eeprom block in even units */ @@ -100,9 +100,9 @@ ao_log(void) log.u.flight.ground_accel_along = ao_ground_accel_along; log.u.flight.ground_accel_across = ao_ground_accel_across; log.u.flight.ground_accel_through = ao_ground_accel_through; + log.u.flight.ground_roll = ao_ground_roll; log.u.flight.ground_pitch = ao_ground_pitch; log.u.flight.ground_yaw = ao_ground_yaw; - log.u.flight.ground_roll = ao_ground_roll; #endif log.u.flight.ground_pres = ao_ground_pres; log.u.flight.flight = ao_flight_number; @@ -183,7 +183,7 @@ ao_log(void) ao_sleep(&ao_log_running); } } -#endif +#endif /* HAS_FLIGHT */ uint16_t ao_log_flight(uint8_t slot) diff --git a/src/lpc/ao_spi_lpc.c b/src/lpc/ao_spi_lpc.c index e72b8286..4c0f5714 100644 --- a/src/lpc/ao_spi_lpc.c +++ b/src/lpc/ao_spi_lpc.c @@ -103,8 +103,8 @@ ao_spi_channel_init(uint8_t id) lpc_ssp->cr0 = ((LPC_SSP_CR0_DSS_8 << LPC_SSP_CR0_DSS) | (LPC_SSP_CR0_FRF_SPI << LPC_SSP_CR0_FRF) | - (0 << LPC_SSP_CR0_CPOL) | - (0 << LPC_SSP_CR0_CPHA) | + (1 << LPC_SSP_CR0_CPOL) | + (1 << LPC_SSP_CR0_CPHA) | (0 << LPC_SSP_CR0_SCR)); /* Enable the device */ diff --git a/src/product/ao_tracker.c b/src/product/ao_tracker.c new file mode 100644 index 00000000..74372c3e --- /dev/null +++ b/src/product/ao_tracker.c @@ -0,0 +1,164 @@ +/* + * Copyright © 2014 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 +#include +#include +#include + +enum ao_flight_state ao_flight_state; + +/* Speeds for the various modes */ +#define AO_TRACKER_NOT_MOVING 100 + +static uint8_t ao_tracker_force_telem; + +#if HAS_USB_CONNECT +static inline uint8_t +ao_usb_connected(void) +{ + return ao_gpio_get(AO_USB_CONNECT_PORT, AO_USB_CONNECT_PIN, AO_USB_CONNECT) != 0; +} +#else +#define ao_usb_connected() 1 +#endif + +static void +ao_tracker(void) +{ + uint16_t telem_rate = AO_SEC_TO_TICKS(1), new_telem_rate; + uint8_t gps_rate = 1, new_gps_rate; + uint8_t telem_enabled = 1, new_telem_enabled; + int32_t start_latitude = 0, start_longitude = 0; + int16_t start_altitude = 0; + uint32_t ground_distance; + int16_t height; + uint16_t speed; + + ao_timer_set_adc_interval(100); + + ao_flight_state = ao_flight_startup; + for (;;) { + ao_sleep(&ao_gps_new); + + new_gps_rate = gps_rate; + new_telem_rate = telem_rate; + + new_telem_enabled = ao_tracker_force_telem || !ao_usb_connected(); + + ao_mutex_get(&ao_gps_mutex); + + /* Don't change anything if GPS isn't locked */ + if ((ao_gps_data.flags & (AO_GPS_VALID|AO_GPS_COURSE_VALID)) == + (AO_GPS_VALID|AO_GPS_COURSE_VALID)) + { + switch (ao_flight_state) { + case ao_flight_startup: + /* startup to pad when GPS locks */ + ao_flight_state = ao_flight_pad; + start_latitude = ao_gps_data.longitude; + start_longitude = ao_gps_data.latitude; + start_altitude = ao_gps_data.altitude; + break; + case ao_flight_pad: +#if 0 + ground_distance = ao_distance(ao_gps_data.latitude, + start_latitude, + ao_gps_data.longitude, + start_longitude); +#else + (void) start_latitude; + (void) start_longitude; + ground_distance = 0xffff; +#endif + height = ao_gps_data.altitude - start_altitude; + if (height < 0) + height = -height; + if (ground_distance >= ao_config.tracker_start_horiz || + height >= ao_config.tracker_start_vert) + { + ao_flight_state = ao_flight_drogue; + ao_log_start(); + } + break; + case ao_flight_drogue: + + /* Modulate data rates based on speed (in cm/s) */ + if (ao_gps_data.climb_rate < 0) + speed = -ao_gps_data.climb_rate; + else + speed = ao_gps_data.climb_rate; + speed += ao_gps_data.ground_speed; + + if (speed < AO_TRACKER_NOT_MOVING) { + new_telem_rate = AO_SEC_TO_TICKS(10); + new_gps_rate = 10; + } else { + new_telem_rate = AO_SEC_TO_TICKS(1); + new_gps_rate = 1; + } + break; + default: + break; + } + } + ao_mutex_put(&ao_gps_mutex); + + if (new_telem_rate != telem_rate || new_telem_enabled != telem_enabled) { +#if 0 + if (new_telem_enabled) + ao_telemetry_set_interval(new_telem_rate); + else + ao_telemetry_set_interval(0); +#endif + telem_rate = new_telem_rate; + telem_enabled = new_telem_enabled; + } + + if (new_gps_rate != gps_rate) { +#if 0 + ao_gps_set_rate(new_gps_rate); +#endif + gps_rate = new_gps_rate; + } + } +} + +static struct ao_task ao_tracker_task; + +static void +ao_tracker_set_telem(void) +{ + ao_cmd_hex(); + if (ao_cmd_status == ao_cmd_success) + ao_tracker_force_telem = ao_cmd_lex_i; +} + +static const struct ao_cmds ao_tracker_cmds[] = { + { ao_tracker_set_telem, "t \0Set telem on USB" }, + { 0, NULL }, +}; + +void +ao_tracker_init(void) +{ +#if HAS_USB_CONNECT + ao_enable_input(AO_USB_CONNECT_PORT, AO_USB_CONNECT_PIN, 0); +#endif + ao_cmd_register(&ao_tracker_cmds[0]); + ao_add_task(&ao_tracker_task, ao_tracker, "tracker"); +} diff --git a/src/telegps-v1.0/.gitignore b/src/telegps-v1.0/.gitignore new file mode 100644 index 00000000..892c3acc --- /dev/null +++ b/src/telegps-v1.0/.gitignore @@ -0,0 +1,3 @@ +ao_product.h +ao_serial_lpc.h +*.elf diff --git a/src/telegps-v1.0/Makefile b/src/telegps-v1.0/Makefile new file mode 100644 index 00000000..507ff650 --- /dev/null +++ b/src/telegps-v1.0/Makefile @@ -0,0 +1,90 @@ +# +# AltOS build +# +# + +include ../lpc/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_pins.h \ + ao_product.h \ + ao_task.h \ + ao_whiten.h \ + ao_cc115l.h \ + ao_fec.h \ + lpc.h \ + Makefile + + +ALTOS_SRC = \ + ao_interrupt.c \ + ao_boot_chain.c \ + ao_product.c \ + ao_romconfig.c \ + ao_cmd.c \ + ao_config.c \ + ao_task.c \ + ao_stdio.c \ + ao_panic.c \ + ao_timer_lpc.c \ + ao_data.c \ + ao_convert_volt.c \ + ao_mutex.c \ + ao_freq.c \ + ao_spi_lpc.c \ + ao_usb_lpc.c \ + ao_exti_lpc.c \ + ao_serial_lpc.c \ + ao_gps_ublox.c \ + ao_gps_show.c \ + ao_cc115l.c \ + ao_fec_tx.c \ + ao_aprs.c \ + ao_adc_lpc.c \ + ao_tracker.c \ + ao_telemetry.c \ + ao_storage.c \ + ao_m25.c \ + ao_log.c \ + ao_log_mega.c \ + ao_gps_report_mega.c \ + ao_distance.c \ + ao_sqrt.c \ + $(SAMPLE_PROFILE) + +PRODUCT=TeleGPS-v1.0 +PRODUCT_DEF=-DTELEGPS +IDPRODUCT=0x0025 + +CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) $(PROFILE_DEF) -Os -g + +PROGNAME=telegps-v1.0 +PROG=$(PROGNAME)-$(VERSION).elf + +SRC=$(ALTOS_SRC) ao_telegps.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) + +LDFLAGS=-L../lpc -Wl,-Taltos.ld + +$(PROG): Makefile $(OBJ) altos.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +$(OBJ): $(INC) + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +distclean: clean + +clean: + rm -f *.o ao_serial_lpc.h $(PROGNAME)-*.elf $(PROGNAME)-*.ihx + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/telegps-v1.0/ao_pins.h b/src/telegps-v1.0/ao_pins.h new file mode 100644 index 00000000..8392eeff --- /dev/null +++ b/src/telegps-v1.0/ao_pins.h @@ -0,0 +1,149 @@ +/* + * 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. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +#define AO_STACK_SIZE 448 + +#define IS_FLASH_LOADER 0 + +/* Crystal on the board */ +#define AO_LPC_CLKIN 12000000 + +/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */ +#define AO_LPC_CLKOUT 48000000 + +/* System clock frequency */ +#define AO_LPC_SYSCLK 24000000 + +#define HAS_SERIAL_0 1 +#define SERIAL_0_18_19 1 +#define USE_SERIAL_0_STDIN 0 + +#define ao_gps_getchar ao_serial0_getchar +#define ao_gps_putchar ao_serial0_putchar +#define ao_gps_set_speed ao_serial0_set_speed +#define ao_gps_fifo (ao_usart_rx_fifo) + +#define HAS_EEPROM 1 +#define USE_INTERNAL_FLASH 0 +#define HAS_USB 1 +#define HAS_BEEP 0 +#define HAS_RADIO 1 +#define HAS_TELEMETRY 1 +#define HAS_RDF 1 +#define HAS_APRS 1 +#define HAS_RADIO_RECV 0 +#define HAS_TRACKER 1 +#define HAS_TASK_QUEUE 0 + +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 7 +#define HAS_USB_CONNECT 1 +#define AO_USB_CONNECT_PORT 1 +#define AO_USB_CONNECT_PIN 19 + +/* Flash part */ +#define HAS_SPI_0 1 +#define SPI_SCK0_P0_6 1 +#define SPI_0_OSPEEDR AO_SPI_OSPEED_12MHz + +/* Radio */ +#define HAS_SPI_1 1 +#define SPI_SCK1_P1_15 1 +#define SPI_MISO1_P0_22 1 +#define SPI_MOSI1_P0_21 1 + +#define HAS_GPS 1 +#define HAS_FLIGHT 0 +#define HAS_LOG 1 + +#define AO_CONFIG_DEFAULT_APRS_INTERVAL 5 +#define AO_CONFIG_DEFAULT_RADIO_POWER 0xc0 + +/* + * GPS + */ + +#define AO_SERIAL_SPEED_UBLOX AO_SERIAL_SPEED_9600 + +/* + * Radio (cc115l) + */ + +/* gets pretty close to 434.550 */ + +#define AO_RADIO_CAL_DEFAULT 0x10b6a5 + +#define HAS_RADIO_POWER 0 +#define AO_FEC_DEBUG 0 +#define AO_CC115L_SPI_CS_PORT 0 +#define AO_CC115L_SPI_CS_PIN 3 +#define AO_CC115L_SPI_BUS 0 + +#define AO_CC115L_FIFO_INT_GPIO_IOCFG CC115L_IOCFG2 +#define AO_CC115L_FIFO_INT_PORT 0 +#define AO_CC115L_FIFO_INT_PIN 20 + +#define AO_CC115L_DONE_INT_GPIO_IOCFG CC115L_IOCFG0 +#define AO_CC115L_DONE_INT_PORT 0 +#define AO_CC115L_DONE_INT_PIN 2 + +/* + * Flash (M25) + */ +#define M25_MAX_CHIPS 1 +#define AO_M25_SPI_CS_PORT 0 +#define AO_M25_SPI_CS_MASK (1 << 23) +#define AO_M25_SPI_BUS 1 + +#define PACKET_HAS_SLAVE 0 + +/* + * ADC + */ + +#define HAS_ADC 1 +#define LOG_ADC 0 + +#define AO_DATA_RING 4 + +#define AO_ADC_3 1 + +struct ao_adc { + int16_t v_batt; +}; + +#define AO_ADC_DUMP(p) \ + printf("tick: %5u batt: %5d\n", \ + (p)->tick, \ + (p)->adc.v_batt) + +/* + * Voltage divider on ADC battery sampler + */ +#define AO_BATTERY_DIV_PLUS 56 /* 5.6k */ +#define AO_BATTERY_DIV_MINUS 100 /* 10k */ + +/* + * ADC reference in decivolts + */ +#define AO_ADC_REFERENCE_DV 33 + +#endif /* _AO_PINS_H_ */ diff --git a/src/telegps-v1.0/ao_telegps.c b/src/telegps-v1.0/ao_telegps.c new file mode 100644 index 00000000..d7dd90a2 --- /dev/null +++ b/src/telegps-v1.0/ao_telegps.c @@ -0,0 +1,66 @@ +/* + * Copyright © 2013 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 +#include +#include + +int +main(void) +{ + ao_clock_init(); + +#if HAS_STACK_GUARD + ao_mpu_init(); +#endif + + ao_task_init(); + ao_timer_init(); + + ao_spi_init(); + ao_exti_init(); + + ao_storage_init(); + + ao_serial_init(); + + ao_cmd_init(); + + ao_usb_init(); + ao_radio_init(); + + ao_adc_init(); + + ao_gps_init(); +#if HAS_LOG + ao_gps_report_mega_init(); + ao_log_init(); +#endif + + ao_tracker_init(); + + ao_telemetry_init(); + ao_telemetry_set_interval(AO_SEC_TO_TICKS(1)); + +#if HAS_SAMPLE_PROFILE + ao_sample_profile_init(); +#endif + ao_config_init(); + + ao_start_scheduler(); + return 0; +} diff --git a/src/telegps-v1.0/flash-loader/Makefile b/src/telegps-v1.0/flash-loader/Makefile new file mode 100644 index 00000000..5283f554 --- /dev/null +++ b/src/telegps-v1.0/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=telegps-v1.0 +include $(TOPDIR)/lpc/Makefile-flash.defs diff --git a/src/telegps-v1.0/flash-loader/ao_pins.h b/src/telegps-v1.0/flash-loader/ao_pins.h new file mode 100644 index 00000000..91097a25 --- /dev/null +++ b/src/telegps-v1.0/flash-loader/ao_pins.h @@ -0,0 +1,33 @@ +/* + * Copyright © 2013 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_PINS_H_ +#define _AO_PINS_H_ + +#include + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO 0 +#define AO_BOOT_APPLICATION_PIN 19 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP + +#define HAS_USB_PULLUP 1 +#define AO_USB_PULLUP_PORT 0 +#define AO_USB_PULLUP_PIN 7 + +#endif /* _AO_PINS_H_ */ -- 2.47.2