From 65837616a6d073da8e3e2bf9da524a48cffb77c2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 9 Feb 2015 07:28:18 -0800 Subject: altos/stmf0: Add ao_crc_stm.c Tom discovered that this was missing Signed-off-by: Keith Packard --- src/stmf0/ao_crc_stm.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/stmf0/ao_crc_stm.c (limited to 'src') diff --git a/src/stmf0/ao_crc_stm.c b/src/stmf0/ao_crc_stm.c new file mode 100644 index 00000000..78efa93a --- /dev/null +++ b/src/stmf0/ao_crc_stm.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2015 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 + +#ifndef AO_CRC_WIDTH +#error "Must define AO_CRC_WIDTH" +#endif + +/* Only the STM32F07x and ST32F09x series have + * programmable CRC units. Others can only do the ANSI CRC-32 computation + */ + +#if !AO_HAVE_PROGRAMMABLE_CRC_UNIT && AO_CRC_WIDTH != 32 +#error "Target hardware does not have programmable CRC unit" +#endif + +#ifndef AO_CRC_POLY +#if AO_CRC_WIDTH == 16 +#define AO_CRC_POLY AO_CRC_16_DEFAULT +#endif +#if AO_CRC_WIDTH == 32 +#define AO_CRC_POLY AO_CRC_32_DEFAULT +#endif +#endif + +#if !AO_HAVE_PROGRAMMABLE_CRC_UNIT && (AO_CRC_WIDTH != 32 || AO_CRC_POLY != AO_CRC_32_ANSI) +#error "Target hardware does not have programmable CRC unit" +#endif + +#if AO_CRC_WIDTH == 32 +#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_32 +#endif + +#if AO_CRC_WIDTH == 16 +#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_16 +#endif + +#if AO_CRC_WIDTH == 8 +#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_8 +#endif + +#if AO_CRC_WIDTH == 7 +#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_7 +#endif + +#ifndef AO_CRC_INIT +#define AO_CRC_INIT 0xffffffff; +#endif + +void +ao_crc_reset(void) +{ + stm_crc.cr |= (1 << STM_CRC_CR_RESET); + while ((stm_crc.cr & (1 << STM_CRC_CR_RESET)) != 0) + ; +} + +void +ao_crc_init(void) +{ + /* Turn on the CRC clock */ + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_CRCEN); + + /* Need to initialize CR even on non-programmable hardware, + * the write to the POLYSIZE bits will be ignored in that + * case + */ + stm_crc.cr = (AO_CRC_CR_POLYSIZE << STM_CRC_CR_POLYSIZE); + stm_crc.init = AO_CRC_INIT; +#if AO_HAVE_PROGRAMMABLE_CRC_UNIT + stm_crc.pol = AO_CRC_POLY; +#endif + ao_crc_reset(); +} -- cgit v1.2.3 From f4c812bef76a2cd95f675cb27ea89059561ceec7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Feb 2015 23:51:10 -0800 Subject: altos: Replace ao_alarm/ao_clear_alarm with ao_sleep_for Having arbitrary alarms firing in the middle of complicated device logic makes no sense at all. Therefore only correct use of ao_alarm and ao_clear_alarm was around a specific ao_sleep call, with correct recovery in case the alarm fires. This patch replaces all uses of ao_alarm/ao_sleep/ao_clear_alarm with ao_sleep_for, a new function which takes the alarm timeout directly. A few cases which weren't simply calling ao_sleep have been reworked to pass the timeout value down to the place where sleep *is* being called, and having that code deal with the return correctly. Signed-off-by: Keith Packard --- src/cc1111/ao_arch.h | 2 +- src/cc1111/ao_button.c | 4 ++-- src/cc1111/ao_radio.c | 6 +----- src/drivers/ao_btm.c | 8 +++----- src/drivers/ao_cc1120.c | 16 +++------------- src/drivers/ao_cc1200.c | 8 +------- src/drivers/ao_companion.c | 3 +-- src/drivers/ao_hmc5883.c | 4 +--- src/drivers/ao_packet.c | 4 ++-- src/drivers/ao_packet_master.c | 8 ++------ src/drivers/ao_packet_slave.c | 2 +- src/kernel/ao_packet.h | 2 +- src/kernel/ao_pyro.c | 4 +--- src/kernel/ao_serial.h | 8 ++++---- src/kernel/ao_task.c | 20 +++++++++++++++----- src/kernel/ao_task.h | 10 ++++++++++ src/kernel/ao_telemetry.c | 4 +--- src/product/ao_terraui.c | 4 +--- src/stm/ao_i2c_stm.c | 18 +++++------------- src/stm/ao_serial_stm.c | 16 ++++++++-------- src/telebt-v3.0/ao_pins.h | 2 +- src/telelco-v0.1/ao_lco.c | 6 +----- src/telelco-v0.2/ao_lco.c | 4 +--- 23 files changed, 67 insertions(+), 96 deletions(-) (limited to 'src') diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index b3c6b5dc..6eb1a111 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -228,7 +228,7 @@ void ao_button_init(void); char -ao_button_get(void) __critical; +ao_button_get(uint16_t timeout) __critical; void ao_button_clear(void) __critical; diff --git a/src/cc1111/ao_button.c b/src/cc1111/ao_button.c index 69f3475f..a0f221c2 100644 --- a/src/cc1111/ao_button.c +++ b/src/cc1111/ao_button.c @@ -72,12 +72,12 @@ ao_button_mask(uint8_t reg) } char -ao_button_get(void) __critical +ao_button_get(uint16_t timeout) __critical { char b; while (ao_fifo_empty(ao_button_fifo)) - if (ao_sleep(&ao_button_fifo)) + if (ao_sleep_for(&ao_button_fifo, timeout)) return 0; ao_fifo_remove(ao_button_fifo, b); return b; diff --git a/src/cc1111/ao_radio.c b/src/cc1111/ao_radio.c index b9821a42..cead0364 100644 --- a/src/cc1111/ao_radio.c +++ b/src/cc1111/ao_radio.c @@ -451,13 +451,9 @@ ao_radio_recv(__xdata void *packet, uint8_t size, uint8_t timeout) __reentrant /* Wait for DMA to be done, for the radio receive process to * get aborted or for a receive timeout to fire */ - if (timeout) - ao_alarm(timeout); __critical while (!ao_radio_dma_done && !ao_radio_abort) - if (ao_sleep(&ao_radio_dma_done)) + if (ao_sleep_for(&ao_radio_dma_done, timeout)) break; - if (timeout) - ao_clear_alarm(); /* If recv was aborted, clean up by stopping the DMA engine * and idling the radio diff --git a/src/drivers/ao_btm.c b/src/drivers/ao_btm.c index e6b28688..93d9dd9d 100644 --- a/src/drivers/ao_btm.c +++ b/src/drivers/ao_btm.c @@ -23,7 +23,7 @@ #ifndef ao_serial_btm_getchar #define ao_serial_btm_putchar ao_serial1_putchar #define _ao_serial_btm_pollchar _ao_serial1_pollchar -#define _ao_serial_btm_sleep() ao_sleep((void *) &ao_serial1_rx_fifo) +#define _ao_serial_btm_sleep_for(timeout) ao_sleep_for((void *) &ao_serial1_rx_fifo, timeout) #define ao_serial_btm_set_speed ao_serial1_set_speed #define ao_serial_btm_drain ao_serial1_drain #endif @@ -111,7 +111,7 @@ ao_btm_do_echo(void) while (ao_btm_enable) { ao_arch_block_interrupts(); while ((c = _ao_serial_btm_pollchar()) == AO_READ_AGAIN && ao_btm_enable) - _ao_serial_btm_sleep(); + _ao_serial_btm_sleep_for(0); ao_arch_release_interrupts(); if (c != AO_READ_AGAIN) { putchar(c); @@ -166,9 +166,7 @@ ao_btm_getchar(void) ao_arch_block_interrupts(); while ((c = _ao_serial_btm_pollchar()) == AO_READ_AGAIN) { - ao_alarm(AO_MS_TO_TICKS(10)); - c = _ao_serial_btm_sleep(); - ao_clear_alarm(); + c = _ao_serial_btm_sleep_for(AO_MS_TO_TICKS(10)); if (c) { c = AO_READ_AGAIN; break; diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 90d6cc75..5b814667 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -837,15 +837,11 @@ ao_radio_test_cmd(void) static void ao_radio_wait_isr(uint16_t timeout) { - if (timeout) - ao_alarm(timeout); ao_arch_block_interrupts(); while (!ao_radio_wake && !ao_radio_mcu_wake && !ao_radio_abort) - if (ao_sleep(&ao_radio_wake)) + if (ao_sleep_for(&ao_radio_wake, timeout)) ao_radio_abort = 1; ao_arch_release_interrupts(); - if (timeout) - ao_clear_alarm(); if (ao_radio_mcu_wake) ao_radio_check_marc_status(); } @@ -1060,19 +1056,17 @@ ao_radio_rx_isr(void) static uint16_t ao_radio_rx_wait(void) { - ao_alarm(AO_MS_TO_TICKS(100)); ao_arch_block_interrupts(); rx_waiting = 1; while (rx_data_cur - rx_data_consumed < AO_FEC_DECODE_BLOCK && !ao_radio_abort && !ao_radio_mcu_wake) { - if (ao_sleep(&ao_radio_wake)) + if (ao_sleep_for(&ao_radio_wake, AO_MS_TO_TICKS(100))) ao_radio_abort = 1; } rx_waiting = 0; ao_arch_release_interrupts(); - ao_clear_alarm(); if (ao_radio_abort || ao_radio_mcu_wake) return 0; rx_data_consumed += AO_FEC_DECODE_BLOCK; @@ -1133,19 +1127,15 @@ ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout) ao_radio_strobe(CC1120_SRX); - if (timeout) - ao_alarm(timeout); ao_arch_block_interrupts(); while (rx_starting && !ao_radio_abort) { - if (ao_sleep(&ao_radio_wake)) + if (ao_sleep_for(&ao_radio_wake, timeout)) ao_radio_abort = 1; } uint8_t rx_task_id_save = rx_task_id; rx_task_id = 0; rx_starting = 0; ao_arch_release_interrupts(); - if (timeout) - ao_clear_alarm(); if (ao_radio_abort) { if (rx_task_id_save == 0) diff --git a/src/drivers/ao_cc1200.c b/src/drivers/ao_cc1200.c index 8546900e..df4bd335 100644 --- a/src/drivers/ao_cc1200.c +++ b/src/drivers/ao_cc1200.c @@ -715,17 +715,11 @@ ao_radio_show_state(char *where) static void ao_radio_wait_isr(uint16_t timeout) { - if (timeout) - ao_alarm(timeout); - ao_arch_block_interrupts(); while (!ao_radio_wake && !ao_radio_abort) - if (ao_sleep(&ao_radio_wake)) + if (ao_sleep_for(&ao_radio_wake, timeout)) ao_radio_abort = 1; ao_arch_release_interrupts(); - - if (timeout) - ao_clear_alarm(); } static void diff --git a/src/drivers/ao_companion.c b/src/drivers/ao_companion.c index 570b9e40..7e02939b 100644 --- a/src/drivers/ao_companion.c +++ b/src/drivers/ao_companion.c @@ -102,8 +102,7 @@ ao_companion(void) break; } while (ao_companion_running) { - ao_alarm(ao_companion_setup.update_period); - if (ao_sleep(DATA_TO_XDATA(&ao_flight_state))) + if (ao_sleep_for(DATA_TO_XDATA(&ao_flight_state), ao_companion_setup.update_period)) ao_companion_get_data(); else ao_companion_notify(); diff --git a/src/drivers/ao_hmc5883.c b/src/drivers/ao_hmc5883.c index 2d217bcf..f761671a 100644 --- a/src/drivers/ao_hmc5883.c +++ b/src/drivers/ao_hmc5883.c @@ -75,13 +75,11 @@ ao_hmc5883_sample(struct ao_hmc5883_sample *sample) ao_exti_enable(AO_HMC5883_INT_PORT, AO_HMC5883_INT_PIN); ao_hmc5883_reg_write(HMC5883_MODE, HMC5883_MODE_SINGLE); - ao_alarm(AO_MS_TO_TICKS(10)); ao_arch_block_interrupts(); while (!ao_hmc5883_done) - if (ao_sleep(&ao_hmc5883_done)) + if (ao_sleep_for(&ao_hmc5883_done, AO_MS_TO_TICKS(10))) ++ao_hmc5883_missed_irq; ao_arch_release_interrupts(); - ao_clear_alarm(); ao_hmc5883_read(HMC5883_X_MSB, (uint8_t *) sample, sizeof (struct ao_hmc5883_sample)); #if __BYTE_ORDER == __LITTLE_ENDIAN diff --git a/src/drivers/ao_packet.c b/src/drivers/ao_packet.c index 8cdf85a9..18330ead 100644 --- a/src/drivers/ao_packet.c +++ b/src/drivers/ao_packet.c @@ -54,14 +54,14 @@ ao_packet_send(void) } uint8_t -ao_packet_recv(void) +ao_packet_recv(uint16_t timeout) { uint8_t dma_done; #ifdef AO_LED_GREEN ao_led_on(AO_LED_GREEN); #endif - dma_done = ao_radio_recv(&ao_rx_packet, sizeof (struct ao_packet_recv), 0); + dma_done = ao_radio_recv(&ao_rx_packet, sizeof (struct ao_packet_recv), timeout); #ifdef AO_LED_GREEN ao_led_off(AO_LED_GREEN); #endif diff --git a/src/drivers/ao_packet_master.c b/src/drivers/ao_packet_master.c index 42a4f5bf..5e440db0 100644 --- a/src/drivers/ao_packet_master.c +++ b/src/drivers/ao_packet_master.c @@ -97,9 +97,7 @@ ao_packet_master(void) if (ao_tx_packet.len) ao_packet_master_busy(); ao_packet_master_check_busy(); - ao_alarm(AO_PACKET_MASTER_RECV_DELAY); - r = ao_packet_recv(); - ao_clear_alarm(); + r = ao_packet_recv(AO_PACKET_MASTER_RECV_DELAY); if (r) { /* if we can transmit data, do so */ if (ao_packet_tx_used && ao_tx_packet.len == 0) @@ -107,9 +105,7 @@ ao_packet_master(void) if (ao_rx_packet.packet.len) ao_packet_master_busy(); ao_packet_master_sleeping = 1; - ao_alarm(ao_packet_master_delay); - ao_sleep(&ao_packet_master_sleeping); - ao_clear_alarm(); + ao_sleep_for(&ao_packet_master_sleeping, ao_packet_master_delay); ao_packet_master_sleeping = 0; } } diff --git a/src/drivers/ao_packet_slave.c b/src/drivers/ao_packet_slave.c index e75df0d6..0872682f 100644 --- a/src/drivers/ao_packet_slave.c +++ b/src/drivers/ao_packet_slave.c @@ -24,7 +24,7 @@ ao_packet_slave(void) ao_tx_packet.len = AO_PACKET_SYN; ao_packet_restart = 1; while (ao_packet_enable) { - if (ao_packet_recv()) { + if (ao_packet_recv(0)) { ao_xmemcpy(&ao_tx_packet.callsign, &ao_rx_packet.packet.callsign, AO_MAX_CALLSIGN); #if HAS_FLIGHT ao_flight_force_idle = TRUE; diff --git a/src/kernel/ao_packet.h b/src/kernel/ao_packet.h index b8426cf9..136609c3 100644 --- a/src/kernel/ao_packet.h +++ b/src/kernel/ao_packet.h @@ -54,7 +54,7 @@ void ao_packet_send(void); uint8_t -ao_packet_recv(void); +ao_packet_recv(uint16_t timeout); void ao_packet_flush(void); diff --git a/src/kernel/ao_pyro.c b/src/kernel/ao_pyro.c index 3044d565..43e73de4 100644 --- a/src/kernel/ao_pyro.c +++ b/src/kernel/ao_pyro.c @@ -375,9 +375,7 @@ ao_pyro(void) ao_sleep(&ao_flight_state); for (;;) { - ao_alarm(AO_MS_TO_TICKS(100)); - ao_sleep(&ao_pyro_wakeup); - ao_clear_alarm(); + ao_sleep_for(&ao_pyro_wakeup, AO_MS_TO_TICKS(100)); if (ao_flight_state >= ao_flight_landed) break; any_waiting = ao_pyro_check(); diff --git a/src/kernel/ao_serial.h b/src/kernel/ao_serial.h index dbc9f8e4..e21643ac 100644 --- a/src/kernel/ao_serial.h +++ b/src/kernel/ao_serial.h @@ -35,7 +35,7 @@ int _ao_serial0_pollchar(void); uint8_t -_ao_serial0_sleep(void); +_ao_serial0_sleep_for(uint16_t timeout); void ao_serial0_putchar(char c); @@ -58,7 +58,7 @@ int _ao_serial1_pollchar(void); uint8_t -_ao_serial1_sleep(void); +_ao_serial1_sleep_for(uint16_t timeout); void ao_serial1_putchar(char c); @@ -81,7 +81,7 @@ int _ao_serial2_pollchar(void); uint8_t -_ao_serial2_sleep(void); +_ao_serial2_sleep_for(uint16_t timeout); void ao_serial2_putchar(char c); @@ -104,7 +104,7 @@ int _ao_serial3_pollchar(void); uint8_t -_ao_serial3_sleep(void); +_ao_serial3_sleep_for(uint16_t timeout); void ao_serial3_putchar(char c); diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c index bafb4943..1ecdd7dd 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -450,7 +450,7 @@ ao_wakeup(__xdata void *wchan) __reentrant ao_check_stack(); } -void +static void ao_alarm(uint16_t delay) { #if HAS_TASK_QUEUE @@ -468,7 +468,7 @@ ao_alarm(uint16_t delay) #endif } -void +static void ao_clear_alarm(void) { #if HAS_TASK_QUEUE @@ -483,14 +483,24 @@ ao_clear_alarm(void) #endif } +uint8_t +ao_sleep_for(__xdata void *wchan, uint16_t timeout) +{ + uint8_t ret; + if (timeout) + ao_alarm(timeout); + ret = ao_sleep(wchan); + if (timeout) + ao_clear_alarm(); + return ret; +} + static __xdata uint8_t ao_forever; void ao_delay(uint16_t ticks) { - ao_alarm(ticks); - ao_sleep(&ao_forever); - ao_clear_alarm(); + ao_sleep_for(&ao_forever, ticks); } void diff --git a/src/kernel/ao_task.h b/src/kernel/ao_task.h index 9c56b480..c6bec0e3 100644 --- a/src/kernel/ao_task.h +++ b/src/kernel/ao_task.h @@ -68,10 +68,19 @@ extern __data uint8_t ao_task_minimize_latency; /* Reduce IRQ latency */ uint8_t ao_sleep(__xdata void *wchan); +/* Suspend the current task until wchan is awoken or the timeout + * expires. returns: + * 0 on normal wake + * 1 on alarm + */ +uint8_t +ao_sleep_for(__xdata void *wchan, uint16_t timeout); + /* Wake all tasks sleeping on wchan */ void ao_wakeup(__xdata void *wchan) __reentrant; +#if 0 /* set an alarm to go off in 'delay' ticks */ void ao_alarm(uint16_t delay); @@ -79,6 +88,7 @@ ao_alarm(uint16_t delay); /* Clear any pending alarm */ void ao_clear_alarm(void); +#endif /* Yield the processor to another task */ void diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index e2197f7a..854ac898 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -486,9 +486,7 @@ ao_telemetry(void) #endif /* HAS_APRS */ delay = time - ao_time(); if (delay > 0) { - ao_alarm(delay); - ao_sleep(&telemetry); - ao_clear_alarm(); + ao_sleep_for(&telemetry, delay); } } } diff --git a/src/product/ao_terraui.c b/src/product/ao_terraui.c index 8fd97033..1e7b5dcd 100644 --- a/src/product/ao_terraui.c +++ b/src/product/ao_terraui.c @@ -539,9 +539,7 @@ ao_terraui(void) else ao_terraui_page[ao_current_page](); - ao_alarm(AO_SEC_TO_TICKS(1)); - b = ao_button_get(); - ao_clear_alarm(); + b = ao_button_get(AO_SEC_TO_TICKS(1)); if (b > 0) { ao_beep_for(AO_BEEP_HIGH, AO_MS_TO_TICKS(10)); diff --git a/src/stm/ao_i2c_stm.c b/src/stm/ao_i2c_stm.c index 1c90cdb8..158f5b21 100644 --- a/src/stm/ao_i2c_stm.c +++ b/src/stm/ao_i2c_stm.c @@ -195,15 +195,13 @@ ao_i2c_start(uint8_t index, uint16_t addr) if (!(stm_i2c->cr1 & (1 << STM_I2C_CR1_START))) break; } - ao_alarm(AO_MS_TO_TICKS(250)); ao_arch_block_interrupts(); stm_i2c->cr2 = AO_STM_I2C_CR2 | (1 << STM_I2C_CR2_ITEVTEN) | (1 << STM_I2C_CR2_ITERREN); ao_i2c_ev_isr(index); while (ao_i2c_state[index] == I2C_IDLE) - if (ao_sleep(&ao_i2c_state[index])) + if (ao_sleep_for(&ao_i2c_state[index], AO_MS_TO_TICKS(250))) break; ao_arch_release_interrupts(); - ao_clear_alarm(); return ao_i2c_state[index] == I2C_RUNNING; } @@ -258,16 +256,14 @@ ao_i2c_send(void *block, uint16_t len, uint8_t index, uint8_t stop) (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); ao_dma_start(tx_dma_index); - ao_alarm(1 + len); ao_arch_block_interrupts(); while (!ao_dma_done[tx_dma_index]) - if (ao_sleep(&ao_dma_done[tx_dma_index])) + if (ao_sleep_for(&ao_dma_done[tx_dma_index], 1 + len)) break; - ao_clear_alarm(); ao_dma_done_transfer(tx_dma_index); stm_i2c->cr2 = AO_STM_I2C_CR2 | (1 << STM_I2C_CR2_ITEVTEN) | (1 << STM_I2C_CR2_ITERREN); while ((stm_i2c->sr1 & (1 << STM_I2C_SR1_BTF)) == 0) - if (ao_sleep(&ao_i2c_state[index])) + if (ao_sleep_for(&ao_i2c_state[index], 1 + len)) break; stm_i2c->cr2 = AO_STM_I2C_CR2; ao_arch_release_interrupts(); @@ -321,14 +317,12 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t index, uint8_t stop) if (stop) stm_i2c->cr1 = AO_STM_I2C_CR1 | (1 << STM_I2C_CR1_STOP); - ao_alarm(1); ao_arch_block_interrupts(); while (ao_i2c_recv_len[index]) - if (ao_sleep(&ao_i2c_recv_len[index])) + if (ao_sleep_for(&ao_i2c_recv_len[index], 1)) break; ao_arch_release_interrupts(); ret = ao_i2c_recv_len[index] == 0; - ao_clear_alarm(); } else { uint8_t rx_dma_index = ao_i2c_stm_info[index].rx_dma_index; ao_dma_set_transfer(rx_dma_index, @@ -351,13 +345,11 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t index, uint8_t stop) ao_i2c_wait_addr(index); ao_dma_start(rx_dma_index); - ao_alarm(len); ao_arch_block_interrupts(); while (!ao_dma_done[rx_dma_index]) - if (ao_sleep(&ao_dma_done[rx_dma_index])) + if (ao_sleep_for(&ao_dma_done[rx_dma_index], len)) break; ao_arch_release_interrupts(); - ao_clear_alarm(); ret = ao_dma_done[rx_dma_index]; ao_dma_done_transfer(rx_dma_index); stm_i2c->cr1 = AO_STM_I2C_CR1 | (1 << STM_I2C_CR1_STOP); diff --git a/src/stm/ao_serial_stm.c b/src/stm/ao_serial_stm.c index 2568cf43..88f2d029 100644 --- a/src/stm/ao_serial_stm.c +++ b/src/stm/ao_serial_stm.c @@ -86,9 +86,9 @@ ao_usart_getchar(struct ao_stm_usart *usart) } static inline uint8_t -_ao_usart_sleep(struct ao_stm_usart *usart) +_ao_usart_sleep_for(struct ao_stm_usart *usart, uint16_t timeout) { - return ao_sleep(&usart->rx_fifo); + return ao_sleep_for(&usart->rx_fifo, timeout); } void @@ -217,9 +217,9 @@ _ao_serial1_pollchar(void) } uint8_t -_ao_serial1_sleep(void) +_ao_serial1_sleep_for(uint16_t timeout) { - return _ao_usart_sleep(&ao_stm_usart1); + return _ao_usart_sleep_for(&ao_stm_usart1, timeout); } void @@ -260,9 +260,9 @@ _ao_serial2_pollchar(void) } uint8_t -_ao_serial2_sleep(void) +_ao_serial2_sleep_for(uint16_t timeout) { - return _ao_usart_sleep(&ao_stm_usart2); + return _ao_usart_sleep_for(&ao_stm_usart2, timeout); } void @@ -303,9 +303,9 @@ _ao_serial3_pollchar(void) } uint8_t -_ao_serial3_sleep(void) +_ao_serial3_sleep_for(uint16_t timeout) { - return _ao_usart_sleep(&ao_stm_usart3); + return _ao_usart_sleep_for(&ao_stm_usart3, timeout); } void diff --git a/src/telebt-v3.0/ao_pins.h b/src/telebt-v3.0/ao_pins.h index 838f0dfc..6e90afcc 100644 --- a/src/telebt-v3.0/ao_pins.h +++ b/src/telebt-v3.0/ao_pins.h @@ -168,7 +168,7 @@ struct ao_adc { #define ao_serial_btm_getchar ao_serial2_getchar #define ao_serial_btm_putchar ao_serial2_putchar #define _ao_serial_btm_pollchar _ao_serial2_pollchar -#define _ao_serial_btm_sleep _ao_serial2_sleep +#define _ao_serial_btm_sleep_for _ao_serial2_sleep_for #define ao_serial_btm_set_speed ao_serial2_set_speed #define ao_serial_btm_drain ao_serial2_drain #define ao_serial_btm_rx_fifo (ao_stm_usart2.rx_fifo) diff --git a/src/telelco-v0.1/ao_lco.c b/src/telelco-v0.1/ao_lco.c index 79f3896b..cb2195ef 100644 --- a/src/telelco-v0.1/ao_lco.c +++ b/src/telelco-v0.1/ao_lco.c @@ -280,9 +280,7 @@ ao_lco_igniter_status(void) uint16_t delay; for (;;) { -// ao_alarm(delay); ao_sleep(&ao_pad_query); -// ao_clear_alarm(); if (!ao_lco_valid) { ao_led_on(AO_LED_RED); ao_led_off(AO_LED_GREEN); @@ -364,9 +362,7 @@ ao_lco_monitor(void) delay = AO_MS_TO_TICKS(100); else delay = AO_SEC_TO_TICKS(1); - ao_alarm(delay); - ao_sleep(&ao_lco_armed); - ao_clear_alarm(); + ao_sleep_for(&ao_lco_armed, delay); } } diff --git a/src/telelco-v0.2/ao_lco.c b/src/telelco-v0.2/ao_lco.c index 4b5f7a9b..12a247bf 100644 --- a/src/telelco-v0.2/ao_lco.c +++ b/src/telelco-v0.2/ao_lco.c @@ -369,9 +369,7 @@ ao_lco_monitor(void) delay = AO_MS_TO_TICKS(100); else delay = AO_SEC_TO_TICKS(1); - ao_alarm(delay); - ao_sleep(&ao_lco_armed); - ao_clear_alarm(); + ao_sleep_for(&ao_lco_armed, delay); } } -- cgit v1.2.3 From 9c75faf1ec51eb2f9a8dc9402653490143a784d9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 14 Feb 2015 08:35:47 -0800 Subject: altos: embed ao_alarm and ao_clear_alarm in ao_sleep_for sdcc won't embed these itself, and thus consumes too much flash for telemetrum-v1.0 Signed-off-by: Keith Packard --- src/kernel/ao_task.c | 54 +++++++++++++++++++++------------------------------- 1 file changed, 22 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c index 1ecdd7dd..55e423bb 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -450,48 +450,38 @@ ao_wakeup(__xdata void *wchan) __reentrant ao_check_stack(); } -static void -ao_alarm(uint16_t delay) +uint8_t +ao_sleep_for(__xdata void *wchan, uint16_t timeout) { + uint8_t ret; + if (timeout) { #if HAS_TASK_QUEUE - uint32_t flags; - /* Make sure we sleep *at least* delay ticks, which means adding - * one to account for the fact that we may be close to the next tick - */ - flags = ao_arch_irqsave(); + uint32_t flags; + /* Make sure we sleep *at least* delay ticks, which means adding + * one to account for the fact that we may be close to the next tick + */ + flags = ao_arch_irqsave(); #endif - if (!(ao_cur_task->alarm = ao_time() + delay + 1)) - ao_cur_task->alarm = 1; + if (!(ao_cur_task->alarm = ao_time() + timeout + 1)) + ao_cur_task->alarm = 1; #if HAS_TASK_QUEUE - ao_task_to_alarm_queue(ao_cur_task); - ao_arch_irqrestore(flags); + ao_task_to_alarm_queue(ao_cur_task); + ao_arch_irqrestore(flags); #endif -} - -static void -ao_clear_alarm(void) -{ + } + ret = ao_sleep(wchan); + if (timeout) { #if HAS_TASK_QUEUE - uint32_t flags; + uint32_t flags; - flags = ao_arch_irqsave(); + flags = ao_arch_irqsave(); #endif - ao_cur_task->alarm = 0; + ao_cur_task->alarm = 0; #if HAS_TASK_QUEUE - ao_task_from_alarm_queue(ao_cur_task); - ao_arch_irqrestore(flags); + ao_task_from_alarm_queue(ao_cur_task); + ao_arch_irqrestore(flags); #endif -} - -uint8_t -ao_sleep_for(__xdata void *wchan, uint16_t timeout) -{ - uint8_t ret; - if (timeout) - ao_alarm(timeout); - ret = ao_sleep(wchan); - if (timeout) - ao_clear_alarm(); + } return ret; } -- cgit v1.2.3 From 135abf0e7c5ceb5738a0b5f68fe2be4b7abdae5e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 14 Feb 2015 23:18:38 -0800 Subject: altos/cc1200: Adjust bit-sync configuration The default bit timing adjustment mechanism allows for only a 0.2% deviation from the programmed bit timing. I found one TeleMini device which is beyond that tolerance as it was built with an older crystal with more error. Switch to the more expensive synchronization mechanism which allows up to 2% timing error, but requires a multi-byte preamble (which we have). This fixes packet mode nicely. Signed-off-by: Keith Packard --- src/drivers/ao_cc1200.h | 32 ++++++++++++++++++++++++++++++++ src/drivers/ao_cc1200_CC1200.h | 9 +++++++++ src/drivers/ao_packet.c | 14 ++++++++++++-- 3 files changed, 53 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_cc1200.h b/src/drivers/ao_cc1200.h index b04775fd..b2b63cde 100644 --- a/src/drivers/ao_cc1200.h +++ b/src/drivers/ao_cc1200.h @@ -438,6 +438,38 @@ #define CC1200_IF_MIX_CFG (CC1200_EXTENDED_BIT | 0x00) #define CC1200_FREQOFF_CFG (CC1200_EXTENDED_BIT | 0x01) #define CC1200_TOC_CFG (CC1200_EXTENDED_BIT | 0x02) + +#define CC1200_TOC_CFG_TOC_LIMIT 6 +#define CC1200_TOC_CFG_TOC_LIMIT_0_2 0 +#define CC1200_TOC_CFG_TOC_LIMIT_2 1 +#define CC1200_TOC_CFG_TOC_LIMIT_12 3 + +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN 3 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_8 0 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_16 1 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_32 2 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_64 3 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_128 4 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_256 5 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_8_16 0 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_6_16 1 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_2_16 2 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_1_16 3 +#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_1_16_SYNC 4 + +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN 0 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_8 0 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_16 1 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_32 2 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_64 3 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_128 4 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_256 5 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_FREEZE 0 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_6_32 1 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_2_32 2 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_1_32 3 +#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_1_32_SYNC 4 + #define CC1200_MARC_SPARE (CC1200_EXTENDED_BIT | 0x03) #define CC1200_ECG_CFG (CC1200_EXTENDED_BIT | 0x04) #define CC1200_MDMCFG2 (CC1200_EXTENDED_BIT | 0x05) diff --git a/src/drivers/ao_cc1200_CC1200.h b/src/drivers/ao_cc1200_CC1200.h index 35673123..f0214c2a 100644 --- a/src/drivers/ao_cc1200_CC1200.h +++ b/src/drivers/ao_cc1200_CC1200.h @@ -101,6 +101,15 @@ (CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) | (CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) | (0 << CC1200_MDMCFG2_CFM_DATA_EN)), + CC1200_MDMCFG0, /* General Modem Parameter Configuration Reg. 0 */ + ((0 << CC1200_MDMCFG0_TRANSPARENT_MODE_EN) | + (0 << CC1200_MDMCFG0_TRANSPARENT_INTFACT) | + (0 << CC1200_MDMCFG0_DATA_FILTER_EN) | + (1 << CC1200_MDMCFG0_VITERBI_EN)), + CC1200_TOC_CFG, /* Timing Offset Correction Configuration */ + ((CC1200_TOC_CFG_TOC_LIMIT_2 << CC1200_TOC_CFG_TOC_LIMIT) | + (CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_6_16 << CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN)| + (CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_2_32 << CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN)), CC1200_FREQ2, 0x6c, /* Frequency Configuration [23:16] */ CC1200_FREQ1, 0xa3, /* Frequency Configuration [15:8] */ CC1200_FREQ0, 0x33, /* Frequency Configuration [7:0] */ diff --git a/src/drivers/ao_packet.c b/src/drivers/ao_packet.c index 18330ead..8c2db275 100644 --- a/src/drivers/ao_packet.c +++ b/src/drivers/ao_packet.c @@ -81,8 +81,16 @@ ao_packet_recv(uint16_t timeout) /* Check to see if we got a valid packet */ if (!dma_done) return 0; - if (!(ao_rx_packet.status & AO_RADIO_STATUS_CRC_OK)) + if (!(ao_rx_packet.status & AO_RADIO_STATUS_CRC_OK)) { + printf("bad crc addr %d len %d seq %d ack %d callsign %8.8s\n", + ao_rx_packet.packet.addr, + ao_rx_packet.packet.len, + ao_rx_packet.packet.seq, + ao_rx_packet.packet.ack, + ao_rx_packet.packet.callsign); + flush(); return 0; + } /* Accept packets with matching call signs, or any packet if * our callsign hasn't been configured @@ -90,8 +98,10 @@ ao_packet_recv(uint16_t timeout) if (ao_xmemcmp(ao_rx_packet.packet.callsign, ao_config.callsign, AO_MAX_CALLSIGN) != 0 && - ao_xmemcmp(ao_config.callsign, CODE_TO_XDATA("N0CALL"), 7) != 0) + ao_xmemcmp(ao_config.callsign, CODE_TO_XDATA("N0CALL"), 7) != 0) { + printf ("bad call\n"); flush(); return 0; + } /* SYN packets carry no data */ if (ao_rx_packet.packet.len == AO_PACKET_SYN) { -- cgit v1.2.3 From 2ebb4dff758058ae9512cf36518416eb69b928f0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 15 Feb 2015 08:57:55 -0800 Subject: altos: Remove some accidental debug printfs from ao_packet.c While fixing the cc1200 configuration, I added some debug printfs to this code. They were accidentally committed with the fix... Signed-off-by: Keith Packard --- src/drivers/ao_packet.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_packet.c b/src/drivers/ao_packet.c index 8c2db275..18330ead 100644 --- a/src/drivers/ao_packet.c +++ b/src/drivers/ao_packet.c @@ -81,16 +81,8 @@ ao_packet_recv(uint16_t timeout) /* Check to see if we got a valid packet */ if (!dma_done) return 0; - if (!(ao_rx_packet.status & AO_RADIO_STATUS_CRC_OK)) { - printf("bad crc addr %d len %d seq %d ack %d callsign %8.8s\n", - ao_rx_packet.packet.addr, - ao_rx_packet.packet.len, - ao_rx_packet.packet.seq, - ao_rx_packet.packet.ack, - ao_rx_packet.packet.callsign); - flush(); + if (!(ao_rx_packet.status & AO_RADIO_STATUS_CRC_OK)) return 0; - } /* Accept packets with matching call signs, or any packet if * our callsign hasn't been configured @@ -98,10 +90,8 @@ ao_packet_recv(uint16_t timeout) if (ao_xmemcmp(ao_rx_packet.packet.callsign, ao_config.callsign, AO_MAX_CALLSIGN) != 0 && - ao_xmemcmp(ao_config.callsign, CODE_TO_XDATA("N0CALL"), 7) != 0) { - printf ("bad call\n"); flush(); + ao_xmemcmp(ao_config.callsign, CODE_TO_XDATA("N0CALL"), 7) != 0) return 0; - } /* SYN packets carry no data */ if (ao_rx_packet.packet.len == AO_PACKET_SYN) { -- cgit v1.2.3 From ec2d758844202108b446e6b12ec1da8812ceb265 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 28 Feb 2015 15:07:16 -0800 Subject: altos: Allow software to offer other USB interface classes than CDC This lets some boards offer non-CDC class USB interfaces so that the modem driver doesn't pick them up. Signed-off-by: Keith Packard --- src/kernel/ao_product.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/kernel/ao_product.c b/src/kernel/ao_product.c index b9327bac..baee8dd6 100644 --- a/src/kernel/ao_product.c +++ b/src/kernel/ao_product.c @@ -33,6 +33,10 @@ const char ao_product[] = AO_iProduct_STRING; #define AO_USB_MAX_POWER 100 #endif +#ifndef AO_USB_INTERFACE_CLASS +#define AO_USB_INTERFACE_CLASS 0x02 +#endif + #include "ao_usb.h" /* USB descriptors in one giant block of bytes */ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] = @@ -69,7 +73,7 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] = 0x00, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x01, /* bNumEndPoints */ - 0x02, /* bInterfaceClass */ + AO_USB_INTERFACE_CLASS, /* bInterfaceClass */ 0x02, /* bInterfaceSubClass */ 0x01, /* bInterfaceProtocol, linux requires value of 1 for the cdc_acm module */ 0x00, /* iInterface */ -- cgit v1.2.3 From 27aef593fb4c037fdb65c9fb397829b42d72d0f2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 28 Feb 2015 15:59:30 -0800 Subject: altos/stmf0: Fix fast ADC interface This was configuring the hardware wrong, and wasn't keeping the output ring full. Signed-off-by: Keith Packard --- src/stmf0/ao_adc_fast.c | 31 ++++++++++++++++++++----------- src/stmf0/ao_adc_fast.h | 10 +++------- 2 files changed, 23 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/stmf0/ao_adc_fast.c b/src/stmf0/ao_adc_fast.c index be9b5986..7d2a4fd7 100644 --- a/src/stmf0/ao_adc_fast.c +++ b/src/stmf0/ao_adc_fast.c @@ -18,43 +18,52 @@ #include #include -uint16_t ao_adc_ring[AO_ADC_RING_SIZE]; +uint16_t ao_adc_ring[AO_ADC_RING_SIZE] __attribute__((aligned(4))); + +/* Maximum number of samples fetched per _ao_adc_start call */ +#define AO_ADC_RING_CHUNK (AO_ADC_RING_SIZE >> 1) uint16_t ao_adc_ring_head, ao_adc_ring_tail; -uint8_t ao_adc_running; +uint16_t ao_adc_running; /* * Callback from DMA ISR * - * Mark time in ring, shut down DMA engine + * Wakeup any waiting processes, mark the DMA as done, start the ADC + * if there's still lots of space in the ring */ static void ao_adc_dma_done(int index) { (void) index; - ao_adc_ring_head += AO_ADC_RING_CHUNK; + ao_adc_ring_head += ao_adc_running; if (ao_adc_ring_head == AO_ADC_RING_SIZE) ao_adc_ring_head = 0; ao_adc_running = 0; ao_wakeup(&ao_adc_ring_head); ao_dma_done_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1)); + _ao_adc_start(); } void _ao_adc_start(void) { uint16_t *buf; + uint16_t count; if (ao_adc_running) return; - if (_ao_adc_space() < AO_ADC_RING_CHUNK) + count = _ao_adc_space(); + if (count == 0) return; - ao_adc_running = 1; + if (count > AO_ADC_RING_CHUNK) + count = AO_ADC_RING_CHUNK; + ao_adc_running = count; buf = ao_adc_ring + ao_adc_ring_head; stm_adc.isr = 0; ao_dma_set_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1), &stm_adc.dr, buf, - AO_ADC_RING_CHUNK, + count, (0 << STM_DMA_CCR_MEM2MEM) | (STM_DMA_CCR_PL_HIGH << STM_DMA_CCR_PL) | (STM_DMA_CCR_MSIZE_16 << STM_DMA_CCR_MSIZE) | @@ -140,7 +149,6 @@ ao_adc_init(void) #if AO_NUM_ADC > 8 #error Need more ADC defines #endif - stm_adc.chselr = chselr; /* Set the clock */ stm_adc.cfgr2 = STM_ADC_CFGR2_CKMODE_PCLK_2 << STM_ADC_CFGR2_CKMODE; @@ -160,14 +168,16 @@ ao_adc_init(void) while ((stm_adc.isr & (1 << STM_ADC_ISR_ADRDY)) == 0) ; + stm_adc.chselr = chselr; + stm_adc.cfgr1 = ((0 << STM_ADC_CFGR1_AWDCH) | (0 << STM_ADC_CFGR1_AWDEN) | (0 << STM_ADC_CFGR1_AWDSGL) | (0 << STM_ADC_CFGR1_DISCEN) | (0 << STM_ADC_CFGR1_AUTOOFF) | - (1 << STM_ADC_CFGR1_WAIT) | + (0 << STM_ADC_CFGR1_WAIT) | (1 << STM_ADC_CFGR1_CONT) | - (0 << STM_ADC_CFGR1_OVRMOD) | + (1 << STM_ADC_CFGR1_OVRMOD) | (STM_ADC_CFGR1_EXTEN_DISABLE << STM_ADC_CFGR1_EXTEN) | (0 << STM_ADC_CFGR1_ALIGN) | (STM_ADC_CFGR1_RES_12 << STM_ADC_CFGR1_RES) | @@ -186,5 +196,4 @@ ao_adc_init(void) stm_syscfg.cfgr1 &= ~(1 << STM_SYSCFG_CFGR1_ADC_DMA_RMP); ao_dma_alloc(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1)); - ao_dma_set_isr(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1), ao_adc_dma_done); } diff --git a/src/stmf0/ao_adc_fast.h b/src/stmf0/ao_adc_fast.h index eec45505..ca5f7fb9 100644 --- a/src/stmf0/ao_adc_fast.h +++ b/src/stmf0/ao_adc_fast.h @@ -26,15 +26,13 @@ ao_adc_init(void); /* Total ring size in samples */ #define AO_ADC_RING_SIZE 256 -/* Number of samples fetched per ao_adc_start call */ -#define AO_ADC_RING_CHUNK (AO_ADC_RING_SIZE >> 1) extern uint16_t ao_adc_ring[AO_ADC_RING_SIZE]; #define ao_adc_ring_step(pos,inc) (((pos) + (inc)) & (AO_ADC_RING_SIZE - 1)) extern uint16_t ao_adc_ring_head, ao_adc_ring_tail; -extern uint8_t ao_adc_running; +extern uint16_t ao_adc_running; void _ao_adc_start(void); @@ -50,9 +48,7 @@ _ao_adc_remain(void) static inline uint16_t _ao_adc_space(void) { - if (ao_adc_ring_head == ao_adc_ring_tail) - return AO_ADC_RING_SIZE; - if (ao_adc_ring_head > ao_adc_ring_tail) + if (ao_adc_ring_head >= ao_adc_ring_tail) return AO_ADC_RING_SIZE - ao_adc_ring_head; return ao_adc_ring_tail - ao_adc_ring_head; } @@ -81,7 +77,7 @@ ao_adc_ack(uint16_t n) ao_adc_ring_tail += n; if (ao_adc_ring_tail == AO_ADC_RING_SIZE) ao_adc_ring_tail = 0; - if (!ao_adc_running && _ao_adc_space() >= AO_ADC_RING_CHUNK) + if (!ao_adc_running) _ao_adc_start(); ao_arch_release_interrupts(); } -- cgit v1.2.3 From e4b415cc8f839ceae48916b5e9d78f78589186cf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 28 Feb 2015 16:00:17 -0800 Subject: altos/stmf0: Typo in ao_crc_stm.c Extra semicolon Signed-off-by: Keith Packard --- src/stmf0/ao_crc_stm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/stmf0/ao_crc_stm.c b/src/stmf0/ao_crc_stm.c index 78efa93a..863f5ef5 100644 --- a/src/stmf0/ao_crc_stm.c +++ b/src/stmf0/ao_crc_stm.c @@ -60,7 +60,7 @@ #endif #ifndef AO_CRC_INIT -#define AO_CRC_INIT 0xffffffff; +#define AO_CRC_INIT 0xffffffff #endif void -- cgit v1.2.3 From 476c5b87ea0901f70fe98b581ecca9afaf957607 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 28 Feb 2015 16:00:45 -0800 Subject: altos/stmf0: Allocate USB buffers at startup This lets the extra allocations used from ao_usb_alloc_buffers be allocated before the first USB connection happens. Signed-off-by: Keith Packard --- src/stmf0/ao_usb_stm.c | 87 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c index 3ea7da5e..b8146c21 100644 --- a/src/stmf0/ao_usb_stm.c +++ b/src/stmf0/ao_usb_stm.c @@ -83,9 +83,13 @@ static uint16_t ao_usb_sram_addr; static uint16_t *ao_usb_ep0_tx_buffer; static uint16_t *ao_usb_ep0_rx_buffer; +/* Pointer to interrupt buffer in USB memory */ +static uint16_t ao_usb_int_tx_offset; + /* Pointer to bulk data tx/rx buffers in USB memory */ static uint16_t ao_usb_in_tx_offset; static uint16_t *ao_usb_in_tx_buffer; +static uint16_t ao_usb_out_rx_offset; static uint16_t *ao_usb_out_rx_buffer; /* System ram shadow of USB buffer; writing individual bytes is @@ -146,12 +150,10 @@ static inline uint16_t *ao_usb_packet_buffer_addr(uint16_t sram_addr) return (uint16_t *) (stm_usb_sram + sram_addr); } -#if AO_USB_DIRECTIO static inline uint16_t ao_usb_packet_buffer_offset(uint16_t *addr) { return (uint16_t) ((uint8_t *) addr - stm_usb_sram); } -#endif static inline uint32_t ao_usb_epr_stat_rx(uint32_t epr) { return (epr >> STM_USB_EPR_STAT_RX) & STM_USB_EPR_STAT_RX_MASK; @@ -323,27 +325,42 @@ ao_usb_init_ep(uint8_t ep, uint32_t addr, uint32_t type, uint32_t stat_rx, uint3 } static void -ao_usb_init_btable(void) +ao_usb_alloc_buffers(void) { ao_usb_sram_addr = 0; ao_usb_bdt = (void *) stm_usb_sram; - ao_usb_sram_addr += 8 * STM_USB_BDT_SIZE; - /* Set up EP 0 - a Control end point with 32 bytes of in and out buffers */ - - ao_usb_bdt[0].single.addr_tx = ao_usb_sram_addr; - ao_usb_bdt[0].single.count_tx = 0; ao_usb_ep0_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); ao_usb_sram_addr += AO_USB_CONTROL_SIZE; - ao_usb_bdt[0].single.addr_rx = ao_usb_sram_addr; - ao_usb_bdt[0].single.count_rx = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) | - (((AO_USB_CONTROL_SIZE / 32) - 1) << STM_USB_BDT_COUNT_RX_NUM_BLOCK)); ao_usb_ep0_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); ao_usb_sram_addr += AO_USB_CONTROL_SIZE; + ao_usb_int_tx_offset = ao_usb_sram_addr; + ao_usb_sram_addr += AO_USB_INT_SIZE; + + ao_usb_out_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); + ao_usb_out_rx_offset = ao_usb_sram_addr; + ao_usb_sram_addr += AO_USB_OUT_SIZE; + + ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); + ao_usb_in_tx_offset = ao_usb_sram_addr; + ao_usb_sram_addr += AO_USB_IN_SIZE; +} + +static void +ao_usb_init_btable(void) +{ + /* Set up EP 0 - a Control end point with 32 bytes of in and out buffers */ + + ao_usb_bdt[0].single.addr_tx = ao_usb_packet_buffer_offset(ao_usb_ep0_tx_buffer); + ao_usb_bdt[0].single.count_tx = 0; + + ao_usb_bdt[0].single.addr_rx = ao_usb_packet_buffer_offset(ao_usb_ep0_rx_buffer); + ao_usb_bdt[0].single.count_rx = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) | + (((AO_USB_CONTROL_SIZE / 32) - 1) << STM_USB_BDT_COUNT_RX_NUM_BLOCK)); } static void @@ -370,6 +387,8 @@ ao_usb_set_ep0(void) } ao_usb_set_address(0); + + ao_usb_running = 0; } static void @@ -378,9 +397,8 @@ ao_usb_set_configuration(void) debug ("ao_usb_set_configuration\n"); /* Set up the INT end point */ - ao_usb_bdt[AO_USB_INT_EPR].single.addr_tx = ao_usb_sram_addr; + ao_usb_bdt[AO_USB_INT_EPR].single.addr_tx = ao_usb_int_tx_offset; ao_usb_bdt[AO_USB_INT_EPR].single.count_tx = 0; - ao_usb_sram_addr += AO_USB_INT_SIZE; ao_usb_init_ep(AO_USB_INT_EPR, AO_USB_INT_EP, @@ -389,11 +407,9 @@ ao_usb_set_configuration(void) STM_USB_EPR_STAT_TX_NAK); /* Set up the OUT end point */ - ao_usb_bdt[AO_USB_OUT_EPR].single.addr_rx = ao_usb_sram_addr; + ao_usb_bdt[AO_USB_OUT_EPR].single.addr_rx = ao_usb_out_rx_offset; ao_usb_bdt[AO_USB_OUT_EPR].single.count_rx = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) | (((AO_USB_OUT_SIZE / 32) - 1) << STM_USB_BDT_COUNT_RX_NUM_BLOCK)); - ao_usb_out_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); - ao_usb_sram_addr += AO_USB_OUT_SIZE; ao_usb_init_ep(AO_USB_OUT_EPR, AO_USB_OUT_EP, @@ -402,11 +418,8 @@ ao_usb_set_configuration(void) STM_USB_EPR_STAT_TX_DISABLED); /* Set up the IN end point */ - ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_sram_addr; + ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_in_tx_offset; ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = 0; - ao_usb_in_tx_offset = ao_usb_sram_addr; - ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_in_tx_offset); - ao_usb_sram_addr += AO_USB_IN_SIZE; ao_usb_init_ep(AO_USB_IN_EPR, AO_USB_IN_EP, @@ -415,6 +428,9 @@ ao_usb_set_configuration(void) STM_USB_EPR_STAT_TX_NAK); ao_usb_running = 1; +#if AO_USB_DIRECTIO + ao_wakeup(&ao_usb_running); +#endif } static uint16_t control_count; @@ -916,8 +932,6 @@ ao_usb_alloc(void) { uint16_t *buffer; - if (!ao_usb_running) - return NULL; buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); ao_usb_sram_addr += AO_USB_IN_SIZE; return buffer; @@ -936,12 +950,28 @@ ao_usb_write(uint16_t *buffer, uint16_t len) { ao_arch_block_interrupts(); - /* Flush any pending regular */ - if (ao_usb_tx_count) - _ao_usb_in_send(); + /* Wait for everything to be ready at the same time */ + for (;;) { + /* Make sure USB is connected */ + if (!ao_usb_running) { + ao_sleep(&ao_usb_running); + continue; + } + + /* Flush any pending regular I/O */ + if (ao_usb_tx_count) { + _ao_usb_in_send(); + continue; + } + + /* Wait for an idle IN buffer */ + if (ao_usb_in_pending) { + ao_sleep(&ao_usb_in_pending); + continue; + } + break; + } - while (ao_usb_in_pending) - ao_sleep(&ao_usb_in_pending); ao_usb_in_pending = 1; ao_usb_in_flushed = (len != AO_USB_IN_SIZE); ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_packet_buffer_offset(buffer); @@ -1083,6 +1113,9 @@ ao_usb_init(void) debug ("ao_usb_init\n"); ao_usb_ep0_state = AO_USB_EP0_IDLE; + + ao_usb_alloc_buffers(); + #if USB_ECHO ao_add_task(&ao_usb_echo_task, ao_usb_echo, "usb echo"); #endif -- cgit v1.2.3 From a4c436a1c39da971b72d4302623f27af9d56cc38 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 28 Feb 2015 16:02:17 -0800 Subject: altos: Create chaoskey product Signed-off-by: Keith Packard --- src/chaoskey-v0.1/Makefile | 69 +++++++++++++++++++++++++++++++++++++++++ src/chaoskey-v0.1/ao_chaoskey.c | 41 ++++++++++++++++++++++++ src/chaoskey-v0.1/ao_pins.h | 67 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 src/chaoskey-v0.1/Makefile create mode 100644 src/chaoskey-v0.1/ao_chaoskey.c create mode 100644 src/chaoskey-v0.1/ao_pins.h (limited to 'src') diff --git a/src/chaoskey-v0.1/Makefile b/src/chaoskey-v0.1/Makefile new file mode 100644 index 00000000..bf4b3ca6 --- /dev/null +++ b/src/chaoskey-v0.1/Makefile @@ -0,0 +1,69 @@ +# +# AltOS build +# +# + +include ../stmf0/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_pins.h \ + ao_product.h \ + ao_task.h \ + ao_adc_fast.h \ + stm32f0.h + +# +# Common AltOS sources +# +ALTOS_SRC = \ + ao_interrupt.c \ + ao_timer.c \ + ao_panic.c \ + ao_mutex.c \ + ao_dma_stm.c \ + ao_adc_fast.c \ + ao_crc_stm.c \ + ao_stdio.c \ + ao_led.c \ + ao_romconfig.c \ + ao_boot_chain.c \ + ao_usb_stm.c \ + ao_trng_send.c \ + ao_task.c \ + ao_product.c + +PRODUCT=ChaosKey-v0.1 +PRODUCT_DEF=-DCHAOSKEY_V_0_1 +IDPRODUCT=0x0028 + +CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) -g -Os + +PROGNAME=chaoskey-v0.1 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) ao_chaoskey.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) $(HEX) + +$(PROG): Makefile $(OBJ) altos.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +$(OBJ): $(INC) + +distclean: clean + +clean: + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/chaoskey-v0.1/ao_chaoskey.c b/src/chaoskey-v0.1/ao_chaoskey.c new file mode 100644 index 00000000..48c8bf04 --- /dev/null +++ b/src/chaoskey-v0.1/ao_chaoskey.c @@ -0,0 +1,41 @@ +/* + * 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 + +void main(void) +{ + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_RED); + ao_clock_init(); + ao_task_init(); + ao_timer_init(); + ao_dma_init(); + ao_adc_init(); + ao_crc_init(); + + ao_usb_init(); + + ao_trng_send_init(); + + ao_led_off(AO_LED_RED); + + ao_start_scheduler(); +} diff --git a/src/chaoskey-v0.1/ao_pins.h b/src/chaoskey-v0.1/ao_pins.h new file mode 100644 index 00000000..72963dba --- /dev/null +++ b/src/chaoskey-v0.1/ao_pins.h @@ -0,0 +1,67 @@ +/* + * Copyright © 2015 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 LED_PORT_ENABLE STM_RCC_AHBENR_IOPAEN +#define LED_PORT (&stm_gpioa) +#define LED_PIN_RED 2 +#define LED_PIN_GREEN 3 +#define AO_LED_RED (1 << LED_PIN_RED) +#define AO_LED_GREEN (1 << LED_PIN_GREEN) + +#define LEDS_AVAILABLE (AO_LED_RED | AO_LED_GREEN) + +#define HAS_BEEP 0 + +/* 48MHz clock based on USB */ +#define AO_HSI48 1 + +/* HCLK = 48MHz */ +#define AO_AHB_PRESCALER 1 +#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1 + +/* APB = 48MHz */ +#define AO_APB_PRESCALER 1 +#define AO_RCC_CFGR_PPRE_DIV STM_RCC_CFGR_PPRE_DIV_1 + +#define HAS_USB 1 +#define AO_USB_DIRECTIO 1 +#define AO_PA11_PA12_RMP 0 +#define AO_USB_INTERFACE_CLASS 0xff + +#define IS_FLASH_LOADER 0 + +/* ADC */ + +#define AO_ADC_PIN0_PORT (&stm_gpioa) +#define AO_ADC_PIN0_PIN 6 +#define AO_ADC_PIN0_CH 6 + +#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_IOPAEN)) + +#define AO_NUM_ADC 1 + +/* CRC */ +#define AO_CRC_WIDTH 32 +#define AO_CRC_INIT 0xffffffff + +/* TRNG */ +#define AO_LED_TRNG_ACTIVE AO_LED_GREEN + +#endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From bd18bc5a42fcecfb710477371b9f62610a1ea640 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 28 Feb 2015 16:04:00 -0800 Subject: altos: Add chaoskey flash loader Signed-off-by: Keith Packard --- src/chaoskey-v0.1/flash-loader/.gitignore | 2 + src/chaoskey-v0.1/flash-loader/ao_pins.h | 36 ++++++++++++++++++ src/drivers/ao_trng_send.c | 62 +++++++++++++++++++++++++++++++ src/drivers/ao_trng_send.h | 24 ++++++++++++ 4 files changed, 124 insertions(+) create mode 100644 src/chaoskey-v0.1/flash-loader/.gitignore create mode 100644 src/chaoskey-v0.1/flash-loader/ao_pins.h create mode 100644 src/drivers/ao_trng_send.c create mode 100644 src/drivers/ao_trng_send.h (limited to 'src') diff --git a/src/chaoskey-v0.1/flash-loader/.gitignore b/src/chaoskey-v0.1/flash-loader/.gitignore new file mode 100644 index 00000000..32dbbbcf --- /dev/null +++ b/src/chaoskey-v0.1/flash-loader/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +usbtrng* diff --git a/src/chaoskey-v0.1/flash-loader/ao_pins.h b/src/chaoskey-v0.1/flash-loader/ao_pins.h new file mode 100644 index 00000000..295e0258 --- /dev/null +++ b/src/chaoskey-v0.1/flash-loader/ao_pins.h @@ -0,0 +1,36 @@ +/* + * 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 + +/* Pin 5 on debug connector */ + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO stm_gpioa +#define AO_BOOT_APPLICATION_PIN 15 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP + +/* USB */ +#define HAS_USB 1 +#define AO_USB_DIRECTIO 0 +#define AO_PA11_PA12_RMP 0 + +#endif /* _AO_PINS_H_ */ diff --git a/src/drivers/ao_trng_send.c b/src/drivers/ao_trng_send.c new file mode 100644 index 00000000..34a8a981 --- /dev/null +++ b/src/drivers/ao_trng_send.c @@ -0,0 +1,62 @@ +/* + * Copyright © 2015 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 + +static void +ao_trng_send(void) +{ + static uint16_t *buffer[2]; + int usb_buf_id; + uint16_t i; + uint16_t *buf; + uint32_t *rnd; + + if (!buffer[0]) { + buffer[0] = ao_usb_alloc(); + buffer[1] = ao_usb_alloc(); + if (!buffer[0]) + return; + } + + usb_buf_id = 0; + + ao_crc_reset(); + + for (;;) { + ao_led_on(AO_LED_TRNG_ACTIVE); + rnd = (uint32_t *) ao_adc_get(AO_USB_IN_SIZE); /* one 16-bit value per output byte */ + buf = buffer[usb_buf_id]; + for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++) + *buf++ = ao_crc_in_32_out_16(*rnd++); + ao_adc_ack(AO_USB_IN_SIZE); + ao_led_off(AO_LED_TRNG_ACTIVE); + ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE); + usb_buf_id = 1-usb_buf_id; + } +} + +static struct ao_task ao_trng_send_task; + +void +ao_trng_send_init(void) +{ + ao_add_task(&ao_trng_send_task, ao_trng_send, "trng_send"); +} diff --git a/src/drivers/ao_trng_send.h b/src/drivers/ao_trng_send.h new file mode 100644 index 00000000..83312d59 --- /dev/null +++ b/src/drivers/ao_trng_send.h @@ -0,0 +1,24 @@ +/* + * Copyright © 2015 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_TRNG_SEND_H_ +#define _AO_TRNG_SEND_H_ + +void +ao_trng_send_init(void); + +#endif /* _AO_TRNG_SEND_H_ */ -- cgit v1.2.3 From 0724cc334a3bd8d81bbd4641d90a7e4040330efe Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 28 Feb 2015 16:06:23 -0800 Subject: altos/usbtrng: Split out random number generating code to separate driver Signed-off-by: Keith Packard --- src/drivers/ao_trng.c | 76 +++++++++++++++++++++++++++++++++++++++++++ src/drivers/ao_trng.h | 24 ++++++++++++++ src/usbtrng-v2.0/Makefile | 2 ++ src/usbtrng-v2.0/ao_pins.h | 4 +++ src/usbtrng-v2.0/ao_usbtrng.c | 56 ++----------------------------- 5 files changed, 109 insertions(+), 53 deletions(-) create mode 100644 src/drivers/ao_trng.c create mode 100644 src/drivers/ao_trng.h (limited to 'src') diff --git a/src/drivers/ao_trng.c b/src/drivers/ao_trng.c new file mode 100644 index 00000000..db742928 --- /dev/null +++ b/src/drivers/ao_trng.c @@ -0,0 +1,76 @@ +/* + * Copyright © 2015 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 + +static void +ao_trng_fetch(void) +{ + static uint16_t *buffer[2]; + uint32_t kbytes = 1; + uint32_t count; + int usb_buf_id; + uint16_t i; + uint16_t *buf; + uint32_t *rnd; + + if (!buffer[0]) { + buffer[0] = ao_usb_alloc(); + buffer[1] = ao_usb_alloc(); + if (!buffer[0]) + return; + } + + ao_cmd_decimal(); + if (ao_cmd_status == ao_cmd_success) + kbytes = ao_cmd_lex_u32; + else + ao_cmd_status = ao_cmd_success; + usb_buf_id = 0; + count = kbytes * (1024/AO_USB_IN_SIZE); + + ao_crc_reset(); + + ao_led_on(AO_LED_TRNG_READ); + while (count--) { + rnd = (uint32_t *) ao_adc_get(AO_USB_IN_SIZE); /* one 16-bit value per output byte */ + buf = buffer[usb_buf_id]; + for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++) + *buf++ = ao_crc_in_32_out_16(*rnd++); + ao_adc_ack(AO_USB_IN_SIZE); + ao_led_toggle(AO_LED_TRNG_READ|AO_LED_TRNG_WRITE); + ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE); + ao_led_toggle(AO_LED_TRNG_READ|AO_LED_TRNG_WRITE); + usb_buf_id = 1-usb_buf_id; + } + ao_led_off(AO_LED_TRNG_READ|AO_LED_TRNG_WRITE); + flush(); +} + +static const struct ao_cmds ao_trng_cmds[] = { + { ao_trng_fetch, "f \0Fetch a block of numbers" }, + { 0, NULL }, +}; + +void +ao_trng_init(void) +{ + ao_cmd_register(ao_trng_cmds); +} diff --git a/src/drivers/ao_trng.h b/src/drivers/ao_trng.h new file mode 100644 index 00000000..78577428 --- /dev/null +++ b/src/drivers/ao_trng.h @@ -0,0 +1,24 @@ +/* + * Copyright © 2015 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_TRNG_H_ +#define _AO_TRNG_H_ + +void +ao_trng_init(void); + +#endif /* _AO_TRNG_H_ */ diff --git a/src/usbtrng-v2.0/Makefile b/src/usbtrng-v2.0/Makefile index abbdbbcc..49798f1c 100644 --- a/src/usbtrng-v2.0/Makefile +++ b/src/usbtrng-v2.0/Makefile @@ -12,6 +12,7 @@ INC = \ ao_pins.h \ ao_product.h \ ao_task.h \ + ao_adc_fast.h \ stm32f0.h # @@ -31,6 +32,7 @@ ALTOS_SRC = \ ao_boot_chain.c \ ao_cmd.c \ ao_usb_stm.c \ + ao_trng.c \ ao_task.c \ ao_product.c diff --git a/src/usbtrng-v2.0/ao_pins.h b/src/usbtrng-v2.0/ao_pins.h index 23759444..1997d205 100644 --- a/src/usbtrng-v2.0/ao_pins.h +++ b/src/usbtrng-v2.0/ao_pins.h @@ -60,4 +60,8 @@ #define AO_CRC_WIDTH 32 #define AO_CRC_INIT 0xffffffff +/* TRNG */ +#define AO_LED_TRNG_READ AO_LED_RED +#define AO_LED_TRNG_WRITE AO_LED_GREEN + #endif /* _AO_PINS_H_ */ diff --git a/src/usbtrng-v2.0/ao_usbtrng.c b/src/usbtrng-v2.0/ao_usbtrng.c index e1f43cdd..42713b6e 100644 --- a/src/usbtrng-v2.0/ao_usbtrng.c +++ b/src/usbtrng-v2.0/ao_usbtrng.c @@ -18,58 +18,7 @@ #include #include #include - -static void -ao_trng_fetch(void) -{ - static uint16_t *buffer[2]; - uint32_t kbytes = 1; - uint32_t count; - int usb_buf_id; - int i; - uint16_t *buf; - uint32_t *rnd; - - if (!buffer[0]) { - buffer[0] = ao_usb_alloc(); - buffer[1] = ao_usb_alloc(); - if (!buffer[0]) - return; - } - - ao_cmd_decimal(); - if (ao_cmd_status == ao_cmd_success) - kbytes = ao_cmd_lex_u32; - else - ao_cmd_status = ao_cmd_success; - usb_buf_id = 0; - count = kbytes * (1024/AO_USB_IN_SIZE); - - ao_crc_reset(); - - ao_led_on(AO_LED_GREEN); - while (count--) { - buf = buffer[usb_buf_id]; -// printf ("before get: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush(); - rnd = (uint32_t *) ao_adc_get(AO_USB_IN_SIZE); /* one 16-bit value per output byte */ -// printf ("after get: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush(); - for (i = 0; i < 32; i++) - *buf++ = ao_crc_in_32_out_16(*rnd++); - ao_adc_ack(AO_USB_IN_SIZE); -// printf ("after ack: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush(); - ao_led_toggle(AO_LED_GREEN|AO_LED_RED); - ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE); - ao_led_toggle(AO_LED_GREEN|AO_LED_RED); - usb_buf_id = 1-usb_buf_id; - } - ao_led_off(AO_LED_GREEN|AO_LED_RED); - flush(); -} - -static const struct ao_cmds usbtrng_cmds[] = { - { ao_trng_fetch, "f \0Fetch a block of numbers" }, - { 0, NULL }, -}; +#include void main(void) { @@ -86,7 +35,8 @@ void main(void) ao_usb_init(); - ao_cmd_register(usbtrng_cmds); + ao_trng_init(); + ao_led_off(AO_LED_RED); ao_start_scheduler(); -- cgit v1.2.3 From 2614d20b324ab215ef22f178e3635d48e757fa9b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 2 Mar 2015 21:02:31 -0800 Subject: altos: Make APRS format (compressed/uncompressed) configurable This provides a choice of compressed vs uncompressed when sending APRS packets to deal with receivers that still do not have support for the more useful compressed format. Signed-off-by: Keith Packard --- src/drivers/ao_aprs.c | 98 +++++++++++++++++++++++++++++++++++++++++--------- src/kernel/ao_config.c | 23 ++++++++++++ src/kernel/ao_config.h | 9 ++++- 3 files changed, 112 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index 19beb78f..2e977612 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -707,8 +707,7 @@ static int tncPositionPacket(void) static int32_t latitude; static int32_t longitude; static int32_t altitude; - int32_t lat, lon, alt; - uint8_t *buf; + uint8_t *buf; if (ao_gps_data.flags & AO_GPS_VALID) { latitude = ao_gps_data.latitude; @@ -719,28 +718,93 @@ static int tncPositionPacket(void) } buf = tncBuffer; - *buf++ = '!'; - /* Symbol table ID */ - *buf++ = '/'; + switch (ao_config.aprs_format) { + case AO_APRS_FORMAT_COMPRESSED: + default: + { + int32_t lat, lon, alt; + + *buf++ = '!'; + + /* Symbol table ID */ + *buf++ = '/'; + + lat = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000; + lon = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000; + + alt = ao_aprs_encode_altitude(altitude); + + tncCompressInt(buf, lat, 4); + buf += 4; + tncCompressInt(buf, lon, 4); + buf += 4; - lat = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000; - lon = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000; + /* Symbol code */ + *buf++ = '\''; - alt = ao_aprs_encode_altitude(altitude); + tncCompressInt(buf, alt, 2); + buf += 2; - tncCompressInt(buf, lat, 4); - buf += 4; - tncCompressInt(buf, lon, 4); - buf += 4; + *buf++ = 33 + ((1 << 5) | (2 << 3)); - /* Symbol code */ - *buf++ = '\''; + break; + } + case AO_APRS_FORMAT_UNCOMPRESSED: + { + char lat_sign = 'N', lon_sign = 'E'; + int32_t lat = latitude; + int32_t lon = longitude; + int32_t alt = altitude; + uint16_t lat_deg; + uint16_t lon_deg; + uint16_t lat_min; + uint16_t lat_frac; + uint16_t lon_min; + uint16_t lon_frac; + + if (lat < 0) { + lat_sign = 'S'; + lat = -lat; + } - tncCompressInt(buf, alt, 2); - buf += 2; + if (lon < 0) { + lon_sign = 'W'; + lon = -lon; + } - *buf++ = 33 + ((1 << 5) | (2 << 3)); + /* Round latitude and longitude by 0.005 minutes */ + lat = lat + 833; + if (lat > 900000000) + lat = 900000000; + lon = lon + 833; + if (lon > 1800000000) + lon = 1800000000; + + lat_deg = lat / 10000000; + lat -= lat_deg * 10000000; + lat *= 60; + lat_min = lat / 10000000; + lat -= lat_min * 10000000; + lat_frac = lat / 100000; + + lon_deg = lon / 10000000; + lon -= lon_deg * 10000000; + lon *= 60; + lon_min = lon / 10000000; + lon -= lon_min * 10000000; + lon_frac = lon / 100000; + + /* Convert from meters to feet */ + alt = (alt * 328 + 50) / 100; + + buf += sprintf((char *) tncBuffer, "!%02u%02u.%02u%c/%03u%02u.%02u%c'/A=%06u ", + lat_deg, lat_min, lat_frac, lat_sign, + lon_deg, lon_min, lon_frac, lon_sign, + alt); + break; + } + } buf += tncComment(buf); diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 8dab7c42..b0d3e541 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -219,6 +219,10 @@ _ao_config_get(void) #if HAS_RADIO_FORWARD if (minor < 21) ao_config.send_frequency = 434550; +#endif +#if HAS_APRS + if (minor < 22) + ao_config.aprs_format = AO_CONFIG_DEFAULT_APRS_FORMAT; #endif ao_config.minor = AO_CONFIG_MINOR; ao_config_dirty = 1; @@ -876,6 +880,23 @@ ao_config_aprs_ssid_set(void) ao_config.aprs_ssid = ao_cmd_lex_i; _ao_config_edit_finish(); } + +void +ao_config_aprs_format_set(void) +{ + ao_cmd_decimal(); + if (ao_cmd_status != ao_cmd_success) + return; + _ao_config_edit_start(); + ao_config.aprs_format = ao_cmd_lex_i != 0; + _ao_config_edit_finish(); +} + +void +ao_config_aprs_format_show(void) +{ + printf ("APRS format: %d\n", ao_config.aprs_format); +} #endif /* HAS_APRS */ struct ao_config_var { @@ -969,6 +990,8 @@ __code struct ao_config_var ao_config_vars[] = { #if HAS_APRS { "S \0Set APRS SSID (0-15)", ao_config_aprs_ssid_set, ao_config_aprs_ssid_show }, + { "C <0 compressed, 1 uncompressed>\0APRS format", + ao_config_aprs_format_set, ao_config_aprs_format_show }, #endif { "s\0Show", ao_config_show, 0 }, diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h index 164584a5..cfe8555c 100644 --- a/src/kernel/ao_config.h +++ b/src/kernel/ao_config.h @@ -57,7 +57,7 @@ #endif #define AO_CONFIG_MAJOR 1 -#define AO_CONFIG_MINOR 21 +#define AO_CONFIG_MINOR 22 #define AO_AES_LEN 16 @@ -115,8 +115,15 @@ struct ao_config { #if HAS_RADIO_FORWARD uint32_t send_frequency; /* minor version 21 */ #endif +#if HAS_APRS + uint8_t aprs_format; /* minor version 22 */ +#endif }; +#define AO_APRS_FORMAT_COMPRESSED 0 +#define AO_APRS_FORMAT_UNCOMPRESSED 1 +#define AO_CONFIG_DEFAULT_APRS_FORMAT AO_APRS_FORMAT_COMPRESSED + #if HAS_RADIO_FORWARD extern __xdata uint32_t ao_send_radio_setting; #endif -- cgit v1.2.3 From 3b133656df4698ceb7af5902711edf9253a29227 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 2 Mar 2015 21:11:33 -0800 Subject: altos: Wait for BT disconnect before sending command If AltosDroid manages to connect to the BT module before we've configured it, we won't be able to talk to it as we can't force the module to ignore connection attempts. Wait for AltosDroid to give up and let us configure the device. Eventually, we'll manage, if AltosDroid's delay interval is longer than the time it takes to configure the unit. Signed-off-by: Keith Packard --- src/drivers/ao_btm.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_btm.c b/src/drivers/ao_btm.c index 93d9dd9d..8e7052cb 100644 --- a/src/drivers/ao_btm.c +++ b/src/drivers/ao_btm.c @@ -263,6 +263,15 @@ uint8_t ao_btm_cmd(__code char *cmd) { ao_btm_drain(); + +#ifdef AO_BTM_INT_PORT + /* Trust that AltosDroid will eventually disconnect and let us + * get things set up. The BTM module doesn't appear to listen + * for +++, so we have no way to force a disconnect. + */ + while (ao_btm_connected) + ao_sleep(&ao_btm_connected); +#endif ao_btm_string(cmd); return ao_btm_wait_reply(); } @@ -350,6 +359,10 @@ __xdata struct ao_task ao_btm_task; void ao_btm(void) { +#ifdef AO_BTM_INT_PORT + ao_exti_enable(AO_BTM_INT_PORT, AO_BTM_INT_PIN); +#endif + /* * Wait for the bluetooth device to boot */ @@ -380,6 +393,8 @@ ao_btm(void) /* Turn off status reporting */ ao_btm_cmd("ATQ1\r"); + ao_btm_drain(); + ao_btm_stdio = ao_add_stdio(_ao_serial_btm_pollchar, ao_serial_btm_putchar, NULL); @@ -388,10 +403,6 @@ ao_btm(void) /* Check current pin state */ ao_btm_check_link(); -#ifdef AO_BTM_INT_PORT - ao_exti_enable(AO_BTM_INT_PORT, AO_BTM_INT_PIN); -#endif - for (;;) { while (!ao_btm_connected) ao_sleep(&ao_btm_connected); -- cgit v1.2.3 From bef7c89dac68956a94ae386fa6b87165ab6cb484 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 2 Mar 2015 21:16:06 -0800 Subject: altos: Missing pad field in TMv2 data packet The normal ARM padding would have filled this in correctly, but it's best to be explicit about the structure. This also adds a test to make sure the resulting telemetry declaration is exactly 32 bytes, Signed-off-by: Keith Packard --- src/kernel/ao_telemetry.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/kernel/ao_telemetry.h b/src/kernel/ao_telemetry.h index 711e0d36..672d2317 100644 --- a/src/kernel/ao_telemetry.h +++ b/src/kernel/ao_telemetry.h @@ -258,13 +258,14 @@ struct ao_telemetry_metrum_data { uint16_t serial; /* 0 */ uint16_t tick; /* 2 */ uint8_t type; /* 4 */ + uint8_t pad5[3]; /* 5 */ - int32_t ground_pres; /* 8 average pres on pad */ + int32_t ground_pres; /* 8 average pres on pad */ int16_t ground_accel; /* 12 average accel on pad */ int16_t accel_plus_g; /* 14 accel calibration at +1g */ int16_t accel_minus_g; /* 16 accel calibration at -1g */ - uint8_t pad[14]; /* 18 */ + uint8_t pad18[14]; /* 18 */ /* 32 */ }; @@ -332,6 +333,8 @@ union ao_telemetry_all { struct ao_telemetry_baro baro; }; +typedef char ao_check_telemetry_size[sizeof(union ao_telemetry_all) == 32 ? 1 : -1]; + struct ao_telemetry_all_recv { union ao_telemetry_all telemetry; int8_t rssi; -- cgit v1.2.3 From f3406f38d71d0c9b55c9a3ae2356a778328509a9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Mar 2015 12:36:57 -0800 Subject: altos: Add .gitignore for chaoskey Signed-off-by: Keith Packard --- src/chaoskey-v0.1/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/chaoskey-v0.1/.gitignore (limited to 'src') diff --git a/src/chaoskey-v0.1/.gitignore b/src/chaoskey-v0.1/.gitignore new file mode 100644 index 00000000..b0adba26 --- /dev/null +++ b/src/chaoskey-v0.1/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +chaoskey-* -- cgit v1.2.3 From 601f33f5e2f833fed9ab10b24a9df91905d7f766 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Mar 2015 12:38:08 -0800 Subject: altos: Build chaoskey by default Signed-off-by: Keith Packard --- src/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 05e99c7f..d4c8a86f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -40,7 +40,8 @@ ARMM3DIRS=\ telebt-v3.0 telebt-v3.0/flash-loader ARMM0DIRS=\ - easymini-v1.0 easymini-v1.0/flash-loader + easymini-v1.0 easymini-v1.0/flash-loader \ + chaoskey-v0.1 chaoskey-v0.1/flash-loader AVRDIRS=\ telescience-v0.1 telescience-pwm micropeak nanopeak-v0.1 microkite -- cgit v1.2.3 From 4e53a5da5a8921829a3bb290e7c051950a66ab75 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Mar 2015 16:40:30 -0800 Subject: altos: Add makefile for chaoskey flash loader Signed-off-by: Keith Packard --- src/chaoskey-v0.1/flash-loader/.gitignore | 2 +- src/chaoskey-v0.1/flash-loader/Makefile | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 src/chaoskey-v0.1/flash-loader/Makefile (limited to 'src') diff --git a/src/chaoskey-v0.1/flash-loader/.gitignore b/src/chaoskey-v0.1/flash-loader/.gitignore index 32dbbbcf..a60a4945 100644 --- a/src/chaoskey-v0.1/flash-loader/.gitignore +++ b/src/chaoskey-v0.1/flash-loader/.gitignore @@ -1,2 +1,2 @@ ao_product.h -usbtrng* +chaoskey* diff --git a/src/chaoskey-v0.1/flash-loader/Makefile b/src/chaoskey-v0.1/flash-loader/Makefile new file mode 100644 index 00000000..4f61a240 --- /dev/null +++ b/src/chaoskey-v0.1/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=chaoskey-v0.1 +include $(TOPDIR)/stmf0/Makefile-flash.defs -- cgit v1.2.3 From dec8de9c642fea1df924a667a4779a6c6c8c3453 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Mar 2015 16:53:58 -0800 Subject: altos/stmf0: Need ao_exti.h for pin configuration Flash loader uses pin configuration to set up GPIOs for boot selection Signed-off-by: Keith Packard --- src/stmf0/ao_exti.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/stmf0/ao_exti.h (limited to 'src') diff --git a/src/stmf0/ao_exti.h b/src/stmf0/ao_exti.h new file mode 100644 index 00000000..ebea224d --- /dev/null +++ b/src/stmf0/ao_exti.h @@ -0,0 +1,48 @@ +/* + * 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_EXTI_H_ +#define _AO_EXTI_H_ + +#define AO_EXTI_MODE_RISING 1 +#define AO_EXTI_MODE_FALLING 2 +#define AO_EXTI_MODE_PULL_UP 4 +#define AO_EXTI_MODE_PULL_DOWN 8 +#define AO_EXTI_PRIORITY_LOW 16 +#define AO_EXTI_PRIORITY_MED 0 +#define AO_EXTI_PRIORITY_HIGH 32 +#define AO_EXTI_PIN_NOCONFIGURE 64 + +void +ao_exti_setup(struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback)()); + +void +ao_exti_set_mode(struct stm_gpio *gpio, uint8_t pin, uint8_t mode); + +void +ao_exti_set_callback(struct stm_gpio *gpio, uint8_t pin, void (*callback)()); + +void +ao_exti_enable(struct stm_gpio *gpio, uint8_t pin); + +void +ao_exti_disable(struct stm_gpio *gpio, uint8_t pin); + +void +ao_exti_init(void); + +#endif /* _AO_EXTI_H_ */ -- cgit v1.2.3 From f92be7e22150b2de4c899e687d3bbfc1eb842f9e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 10 Mar 2015 09:32:20 -0600 Subject: altos/test: Make aprs test code compile again Adding the compressed/uncompressed config option broke the APRS test harness. Signed-off-by: Keith Packard --- src/drivers/ao_aprs.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index 2e977612..a8016673 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -719,7 +719,13 @@ static int tncPositionPacket(void) buf = tncBuffer; +#ifdef AO_APRS_TEST +#define AO_APRS_FORMAT_COMPRESSED 0 +#define AO_APRS_FORMAT_UNCOMPRESSED 1 + switch (AO_APRS_FORMAT_COMPRESSED) { +#else switch (ao_config.aprs_format) { +#endif case AO_APRS_FORMAT_COMPRESSED: default: { -- cgit v1.2.3 From ce99807ef942de54a3f934d321baf3c3d26442bb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 10 Mar 2015 09:34:01 -0600 Subject: altos/test: Support old telemega eeprom file formats in ao_flight_test The old eeprom format used different stoarge for the accel calibration data, which doesn't matter to this code, but the change in the format value does. Signed-off-by: Keith Packard --- src/test/ao_flight_test.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index fbbc4bd9..f71c3052 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -554,9 +554,9 @@ ao_insert(void) ao_quaternion_rotate(&ao_out, &ao_x, &ao_rotation); +#if 0 int out = floor (atan2(ao_out.y, ao_out.x) * 180 / M_PI); -#if 0 printf ("%7.2f state %-8.8s height %8.4f tilt %4d rot %4d mag_tilt %4d mag_rot %4d\n", time, ao_state_names[ao_flight_state], @@ -717,7 +717,7 @@ ao_sleep(void *wchan) break; } #if TELEMEGA - if (log_format == AO_LOG_FORMAT_TELEMEGA && nword == 30 && strlen(words[0]) == 1) { + if ((log_format == AO_LOG_FORMAT_TELEMEGA_OLD || log_format == AO_LOG_FORMAT_TELEMEGA) && nword == 30 && strlen(words[0]) == 1) { int i; struct ao_ms5607_value value; @@ -895,7 +895,6 @@ ao_sleep(void *wchan) ao_config.accel_zero_along = atoi(words[3]); ao_config.accel_zero_across = atoi(words[5]); ao_config.accel_zero_through = atoi(words[7]); - printf ("%d %d %d\n", ao_config.accel_zero_along, ao_config.accel_zero_across, ao_config.accel_zero_through); #endif } else if (nword >= 4 && strcmp(words[0], "Main") == 0) { ao_config.main_deploy = atoi(words[2]); -- cgit v1.2.3 From c3321bd9f73c89686fe983a8d99f4e54fa91550e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 19 Mar 2015 01:11:33 -0700 Subject: altos: Add the ability to configure a different USB vendor ID ChaosKey will use an OpenMoko vid/pid, so we need the ability to configure a different USB vendor ID for each product. Signed-off-by: Keith Packard --- src/kernel/ao_product.c | 2 +- src/util/ao-make-product.5c | 49 +++++++++++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/kernel/ao_product.c b/src/kernel/ao_product.c index baee8dd6..c711a4d2 100644 --- a/src/kernel/ao_product.c +++ b/src/kernel/ao_product.c @@ -49,7 +49,7 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] = 0x00, /* bDeviceSubClass */ 0x00, /* bDeviceProtocol */ AO_USB_CONTROL_SIZE, /* bMaxPacketSize */ - LE_WORD(0xFFFE), /* idVendor */ + LE_WORD(AO_idVendor_NUMBER), /* idVendor */ LE_WORD(AO_idProduct_NUMBER), /* idProduct */ LE_WORD(0x0100), /* bcdDevice */ 0x01, /* iManufacturer */ diff --git a/src/util/ao-make-product.5c b/src/util/ao-make-product.5c index 5f2eb8e8..3ab8d16e 100644 --- a/src/util/ao-make-product.5c +++ b/src/util/ao-make-product.5c @@ -1,54 +1,58 @@ -#!/bin/sh +#!/usr/bin/nickle autoimport ParseArgs; +file out = stdout; + void write_ucs2(string a, string description) { int len = String::length(a); - printf("/* %s */\n", description); - printf("#define AO_%s_LEN 0x%02x\n", description, len * 2 + 2); - printf("#define AO_%s_STRING \"%s\"\n", description, a); - printf("#define AO_%s_UCS2", description); + File::fprintf(out, "/* %s */\n", description); + File::fprintf(out, "#define AO_%s_LEN 0x%02x\n", description, len * 2 + 2); + File::fprintf(out, "#define AO_%s_STRING \"%s\"\n", description, a); + File::fprintf(out, "#define AO_%s_UCS2", description); for (int i = 0; i < len; i++) { int c = a[i]; if (i > 0) - printf(","); + File::fprintf(out, ","); if (0x20 <= c && c < 128) - printf(" '%c', 0", c); + File::fprintf(out, " '%c', 0", c); else - printf(" LE_WORD(0x%04x),", c); + File::fprintf(out, " LE_WORD(0x%04x),", c); } - printf("\n\n"); + File::fprintf(out, "\n\n"); } void write_string(string a, string description) { - printf ("/* %s */\n", description); - printf ("#define AO_%s_STRING \"%s\"\n", description, a); + File::fprintf(out, "/* %s */\n", description); + File::fprintf(out, "#define AO_%s_STRING \"%s\"\n", description, a); } void write_int(int a, string description) { - printf ("/* %s */\n", description); - printf ("#define AO_%s_NUMBER %d\n\n", description, a); + File::fprintf(out, "/* %s */\n", description); + File::fprintf(out, "#define AO_%s_NUMBER %d\n\n", description, a); } void write_hex(int a, string description) { - printf ("/* %s */\n", description); - printf ("#define AO_%s_NUMBER 0x%04x\n\n", description, a); + File::fprintf(out, "/* %s */\n", description); + File::fprintf(out, "#define AO_%s_NUMBER 0x%04x\n\n", description, a); } string manufacturer = "altusmetrum.org"; string product = "TeleMetrum"; string version = "0.0"; +string output = ""; int serial = 1; int user_argind = 0; +int id_vendor = 0xfffe; int id_product = 0x000a; argdesc argd = { @@ -65,6 +69,12 @@ argdesc argd = { .name = "product", .expr_name = "prod", .desc = "Product name." }, + { + .var = { .arg_int = &id_vendor }, + .abbr = 'V', + .name = "id_vendor", + .expr_name = "id_v", + .desc = "Vendor ID." }, { .var = { .arg_int = &id_product }, .abbr = 'i', @@ -83,6 +93,12 @@ argdesc argd = { .name = "version", .expr_name = "string", .desc = "Program version." }, + { + .var = { .arg_string = &output }, + .abbr = 'o', + .name = "output", + .expr_name = "out", + .desc = "Output file." }, }, .prog_name = "usb descriptors", }; @@ -92,11 +108,14 @@ main() { string[dim(argv)-1] nargv = {[n] = argv[n+1]}; parseargs(&argd, &nargv); + if (output != "") + out = File::open(output, "w"); write_ucs2(manufacturer, "iManufacturer"); write_ucs2(product, "iProduct"); write_ucs2(sprintf("%06d", serial), "iSerial"); write_int(serial, "iSerial"); write_hex(id_product, "idProduct"); + write_hex(id_vendor, "idVendor"); write_string(version, "iVersion"); } -- cgit v1.2.3 From 43b4044dc71d44cb25be6397b4d66fd792580eed Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 19 Mar 2015 01:12:24 -0700 Subject: altos/chaoskey: Set USB VID/PID to 0x1d50/0x60c6 These are allocated from the OpenMoko USB vendor ID page and offer a more 'official' number than from using the 0xfffe space. Signed-off-by: Keith Packard --- src/chaoskey-v0.1/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/chaoskey-v0.1/Makefile b/src/chaoskey-v0.1/Makefile index bf4b3ca6..ac4a6788 100644 --- a/src/chaoskey-v0.1/Makefile +++ b/src/chaoskey-v0.1/Makefile @@ -37,7 +37,8 @@ ALTOS_SRC = \ PRODUCT=ChaosKey-v0.1 PRODUCT_DEF=-DCHAOSKEY_V_0_1 -IDPRODUCT=0x0028 +IDVENDOR=0x1d50 +IDPRODUCT=0x60c6 CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) -g -Os @@ -54,7 +55,7 @@ $(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) ao_product.h: ao-make-product.5c ../Version - $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -V $(IDVENDOR) -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) -o $@ $(OBJ): $(INC) -- cgit v1.2.3 From b1b69c8b73cbffb56c688f6a968d144b642cdff2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 20 Mar 2015 15:09:20 -0700 Subject: altos/stmf0: Have fast ADC ring buffer code use wrap-around Instead of requiring that the whole set of returned values fit precisely in the ring, allow for wrap-around so that we can fetch an odd number of ADC values. The previous version required that the fetch amount always be a factor of the ADC buffer size. Signed-off-by: Keith Packard --- src/drivers/ao_trng.c | 11 +++++++---- src/drivers/ao_trng_send.c | 11 +++++++---- src/stmf0/ao_adc_fast.c | 3 ++- src/stmf0/ao_adc_fast.h | 41 +++++++++++++++++++++-------------------- 4 files changed, 37 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_trng.c b/src/drivers/ao_trng.c index db742928..e69cd30b 100644 --- a/src/drivers/ao_trng.c +++ b/src/drivers/ao_trng.c @@ -29,7 +29,8 @@ ao_trng_fetch(void) int usb_buf_id; uint16_t i; uint16_t *buf; - uint32_t *rnd; + uint16_t t; + uint32_t *rnd = (uint32_t *) ao_adc_ring; if (!buffer[0]) { buffer[0] = ao_usb_alloc(); @@ -50,10 +51,12 @@ ao_trng_fetch(void) ao_led_on(AO_LED_TRNG_READ); while (count--) { - rnd = (uint32_t *) ao_adc_get(AO_USB_IN_SIZE); /* one 16-bit value per output byte */ + t = ao_adc_get(AO_USB_IN_SIZE) >> 1; /* one 16-bit value per output byte */ buf = buffer[usb_buf_id]; - for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++) - *buf++ = ao_crc_in_32_out_16(*rnd++); + for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++) { + *buf++ = ao_crc_in_32_out_16(rnd[t]); + t = (t + 1) & ((AO_ADC_RING_SIZE>>1) - 1); + } ao_adc_ack(AO_USB_IN_SIZE); ao_led_toggle(AO_LED_TRNG_READ|AO_LED_TRNG_WRITE); ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE); diff --git a/src/drivers/ao_trng_send.c b/src/drivers/ao_trng_send.c index 34a8a981..bac6035c 100644 --- a/src/drivers/ao_trng_send.c +++ b/src/drivers/ao_trng_send.c @@ -27,7 +27,8 @@ ao_trng_send(void) int usb_buf_id; uint16_t i; uint16_t *buf; - uint32_t *rnd; + uint16_t t; + uint32_t *rnd = (uint32_t *) ao_adc_ring; if (!buffer[0]) { buffer[0] = ao_usb_alloc(); @@ -42,10 +43,12 @@ ao_trng_send(void) for (;;) { ao_led_on(AO_LED_TRNG_ACTIVE); - rnd = (uint32_t *) ao_adc_get(AO_USB_IN_SIZE); /* one 16-bit value per output byte */ + t = ao_adc_get(AO_USB_IN_SIZE) >> 1; /* one 16-bit value per output byte */ buf = buffer[usb_buf_id]; - for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++) - *buf++ = ao_crc_in_32_out_16(*rnd++); + for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++) { + *buf++ = ao_crc_in_32_out_16(rnd[t]); + t = (t + 1) & ((AO_ADC_RING_SIZE>>1) - 1); + } ao_adc_ack(AO_USB_IN_SIZE); ao_led_off(AO_LED_TRNG_ACTIVE); ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE); diff --git a/src/stmf0/ao_adc_fast.c b/src/stmf0/ao_adc_fast.c index 7d2a4fd7..26e6691c 100644 --- a/src/stmf0/ao_adc_fast.c +++ b/src/stmf0/ao_adc_fast.c @@ -23,7 +23,7 @@ uint16_t ao_adc_ring[AO_ADC_RING_SIZE] __attribute__((aligned(4))); /* Maximum number of samples fetched per _ao_adc_start call */ #define AO_ADC_RING_CHUNK (AO_ADC_RING_SIZE >> 1) -uint16_t ao_adc_ring_head, ao_adc_ring_tail; +uint16_t ao_adc_ring_head, ao_adc_ring_remain; uint16_t ao_adc_running; /* @@ -36,6 +36,7 @@ static void ao_adc_dma_done(int index) { (void) index; ao_adc_ring_head += ao_adc_running; + ao_adc_ring_remain += ao_adc_running; if (ao_adc_ring_head == AO_ADC_RING_SIZE) ao_adc_ring_head = 0; ao_adc_running = 0; diff --git a/src/stmf0/ao_adc_fast.h b/src/stmf0/ao_adc_fast.h index ca5f7fb9..c6903e9f 100644 --- a/src/stmf0/ao_adc_fast.h +++ b/src/stmf0/ao_adc_fast.h @@ -31,52 +31,53 @@ extern uint16_t ao_adc_ring[AO_ADC_RING_SIZE]; #define ao_adc_ring_step(pos,inc) (((pos) + (inc)) & (AO_ADC_RING_SIZE - 1)) -extern uint16_t ao_adc_ring_head, ao_adc_ring_tail; +extern uint16_t ao_adc_ring_head, ao_adc_ring_remain; extern uint16_t ao_adc_running; -void -_ao_adc_start(void); - +/* + * Place to start fetching values from + */ static inline uint16_t -_ao_adc_remain(void) +ao_adc_ring_tail(void) { - if (ao_adc_ring_tail > ao_adc_ring_head) - return AO_ADC_RING_SIZE - ao_adc_ring_tail; - return ao_adc_ring_head - ao_adc_ring_tail; + return (ao_adc_ring_head - ao_adc_ring_remain) & (AO_ADC_RING_SIZE - 1); } +void +_ao_adc_start(void); + +/* + * Space available to write ADC values into + */ static inline uint16_t _ao_adc_space(void) { - if (ao_adc_ring_head >= ao_adc_ring_tail) + /* Free to end of buffer? */ + if (ao_adc_ring_remain <= ao_adc_ring_head) return AO_ADC_RING_SIZE - ao_adc_ring_head; - return ao_adc_ring_tail - ao_adc_ring_head; + + /* no, return just the unused entries beyond head */ + return AO_ADC_RING_SIZE - ao_adc_ring_remain; } -static inline uint16_t * +static inline uint16_t ao_adc_get(uint16_t n) { - if (ao_adc_ring_tail + n > AO_ADC_RING_SIZE) - ao_panic(AO_PANIC_ADC); ao_arch_block_interrupts(); - while (_ao_adc_remain() < n) { + while (ao_adc_ring_remain < n) { if (!ao_adc_running) _ao_adc_start(); ao_sleep(&ao_adc_ring_head); } ao_arch_release_interrupts(); - return &ao_adc_ring[ao_adc_ring_tail]; + return ao_adc_ring_tail(); } static inline void ao_adc_ack(uint16_t n) { - if (ao_adc_ring_tail + n > AO_ADC_RING_SIZE) - ao_panic(AO_PANIC_ADC); ao_arch_block_interrupts(); - ao_adc_ring_tail += n; - if (ao_adc_ring_tail == AO_ADC_RING_SIZE) - ao_adc_ring_tail = 0; + ao_adc_ring_remain -= n; if (!ao_adc_running) _ao_adc_start(); ao_arch_release_interrupts(); -- cgit v1.2.3 From dba00b3d9102db99592f5822a703e64d98ace8bb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 May 2015 10:17:01 -0700 Subject: altos: Support 32MHz xtal on cc1200 I ended up building some cc1200-based boards with 32MHz xtals, so just make this an option when building the driver. Signed-off-by: Keith Packard --- src/drivers/ao_cc1200.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_cc1200.c b/src/drivers/ao_cc1200.c index df4bd335..6547be39 100644 --- a/src/drivers/ao_cc1200.c +++ b/src/drivers/ao_cc1200.c @@ -41,7 +41,11 @@ int8_t ao_radio_rssi; /* Last received RSSI value */ extern const uint32_t ao_radio_cal; +#ifdef AO_CC1200_FOSC +#define FOSC AO_CC1200_FOSC +#else #define FOSC 40000000 +#endif #define ao_radio_select() ao_spi_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_SPI_SPEED_FAST) #define ao_radio_deselect() ao_spi_put_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS) @@ -301,20 +305,28 @@ ao_radio_idle(void) * CHANBW = 5.0 (round to 9.5) */ +#if FOSC == 40000000 #define PACKET_SYMBOL_RATE_M 1013008 - #define PACKET_SYMBOL_RATE_E_384 8 +#define PACKET_SYMBOL_RATE_E_96 6 +#define PACKET_SYMBOL_RATE_E_24 4 +#endif + +#if FOSC == 32000000 +#define PACKET_SYMBOL_RATE_M 239914 +#define PACKET_SYMBOL_RATE_E_384 9 +#define PACKET_SYMBOL_RATE_E_96 7 +#define PACKET_SYMBOL_RATE_E_24 5 +#endif /* 200 / 2 = 100 */ #define PACKET_CHAN_BW_384 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_12 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ (16 << CC1200_CHAN_BW_BB_CIC_DECFACT)) -#define PACKET_SYMBOL_RATE_E_96 6 /* 200 / 10 = 20 */ #define PACKET_CHAN_BW_96 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ (16 << CC1200_CHAN_BW_BB_CIC_DECFACT)) -#define PACKET_SYMBOL_RATE_E_24 4 /* 200 / 25 = 8 */ #define PACKET_CHAN_BW_24 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \ (44 << CC1200_CHAN_BW_BB_CIC_DECFACT)) -- cgit v1.2.3 From eac71f2b871357ff69581c713059a3741a82a932 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 May 2015 10:22:10 -0700 Subject: microsplash: Add 'publish' target to Makefile This dumps the resulting binary and -load script into the Binaries directory of the altusmetrumllc repo Signed-off-by: Keith Packard --- src/microsplash/.gitignore | 3 ++- src/microsplash/Makefile | 43 +++++++++++++++++++++++------------ src/microsplash/microsplash-load.tmpl | 21 +++++++++++++++++ 3 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 src/microsplash/microsplash-load.tmpl (limited to 'src') diff --git a/src/microsplash/.gitignore b/src/microsplash/.gitignore index 5f6fe3b2..c2062c34 100644 --- a/src/microsplash/.gitignore +++ b/src/microsplash/.gitignore @@ -1,2 +1,3 @@ ao_product.h -microsplash-* +microsplash-v* +microsplash-load diff --git a/src/microsplash/Makefile b/src/microsplash/Makefile index 10cb825b..9bb636f1 100644 --- a/src/microsplash/Makefile +++ b/src/microsplash/Makefile @@ -8,8 +8,15 @@ vpath make-altitude-pa ../util include ../avr/Makefile.defs +PROGNAME=microsplash-v1.0 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SCRIPT=microsplash-load + PUBLISH_DIR=$(HOME)/altusmetrumllc/Binaries -PUBLISH_FILE=$(PUBLISH_DIR)/$(PROG)-$(VERSION).hex +PUBLISH_HEX=$(PUBLISH_DIR)/$(HEX) +PUBLISH_SCRIPT=$(PUBLISH_DIR)/$(SCRIPT) MCU=attiny85 DUDECPUTYPE=t85 @@ -48,15 +55,13 @@ INC=\ altitude-pa.h IDPRODUCT=0 -PRODUCT=MicroSplash-v0.1 +PRODUCT=MicroSplash-v1.0 PRODUCT_DEF=-DMICROPEAK CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../kernel -I.. -I../drivers -I../product CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTINY NICKLE=nickle -PROG=microsplash-v1.0 - SRC=$(ALTOS_SRC) OBJ=$(SRC:.c=.o) @@ -68,7 +73,7 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: $(PROG) $(PROG).hex +all: $(PROG) $(HEX) $(SCRIPT) CHECK=sh ../util/check-avr-mem @@ -76,16 +81,16 @@ $(PROG): Makefile $(OBJ) $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1) -$(PROG).hex: $(PROG) +$(HEX): $(PROG) avr-size $(PROG) $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@ -load: $(PROG).hex - $(LOADCMD) $(LOADARG)$(PROG).hex +load: $(HEX) + $(LOADCMD) $(LOADARG)$(HEX) -load-slow: $(PROG).hex - $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PROG).hex +load-slow: $(HEX) + $(LOADCMD) $(LOADSLOW) $(LOADARG)$(HEX) ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ @@ -98,22 +103,30 @@ ao_product.o: ao_product.c ao_product.h distclean: clean clean: - rm -f *.o $(PROG) $(PROG).hex + rm -f *.o $(PROG) $(HEX) $(SCRIPT) rm -f ao_product.h +publish: $(PUBLISH_HEX) $(PUBLISH_SCRIPT) -publish: $(PROG).hex - cp -a $(PROG).hex $(PUBLISH_FILE) +$(PUBLISH_HEX): $(HEX) + cp -a $(HEX) $@ + +$(PUBLISH_SCRIPT): $(SCRIPT) + cp -a $(SCRIPT) $@ load-product: - $(LOADCMD) $(LOADARG)$(PUBLISH_FILE) + ./$(SCRIPT) fast load-product-slow: - $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PUBLISH_FILE) + ./$(SCRIPT) slow ../altitude-pa.h: make-altitude-pa nickle $< > $@ +$(SCRIPT): $(SCRIPT).tmpl Makefile ../Version + sed -e 's/%HEX%/$(HEX)/' -e 's/%LOADCMD%/$(LOADCMD)/' -e 's/%LOADARG%/$(LOADARG)/' -e 's/%LOADSLOW%/$(LOADSLOW)/' $(SCRIPT).tmpl > $@ || (rm $@ && exit 1) + chmod +x $@ + install: uninstall: diff --git a/src/microsplash/microsplash-load.tmpl b/src/microsplash/microsplash-load.tmpl new file mode 100644 index 00000000..c061559d --- /dev/null +++ b/src/microsplash/microsplash-load.tmpl @@ -0,0 +1,21 @@ +#!/bin/sh +dir=`dirname $0` + +HEX="$dir"/"%HEX%" +LOADCMD="%LOADCMD%" +LOADARG="%LOADARG%" +LOADSLOW="%LOADSLOW%" +LOADFAST="" + +case "$1" in +slow) + LOADSPEED="$LOADSLOW" + ;; +*) + LOADSPEED="$LOADFAST" + ;; +esac + +echo ${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX} +${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX} +/usr/games/xcowsay --cow-size=large --at=1000,500 "${HEX} finished" -- cgit v1.2.3 From f3ddaae82215e365726f2a62a3dc46bfb29eb1b5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 May 2015 10:23:09 -0700 Subject: micropeak: Use fast load mode by default in -load script Speed up flashing in default config Signed-off-by: Keith Packard --- src/micropeak/micropeak-load.tmpl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/micropeak/micropeak-load.tmpl b/src/micropeak/micropeak-load.tmpl index 08236a15..c061559d 100644 --- a/src/micropeak/micropeak-load.tmpl +++ b/src/micropeak/micropeak-load.tmpl @@ -8,13 +8,14 @@ LOADSLOW="%LOADSLOW%" LOADFAST="" case "$1" in -fast) - LOADSPEED="$LOADFAST" +slow) + LOADSPEED="$LOADSLOW" ;; *) - LOADSPEED="$LOADSLOW" + LOADSPEED="$LOADFAST" ;; esac echo ${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX} ${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX} +/usr/games/xcowsay --cow-size=large --at=1000,500 "${HEX} finished" -- cgit v1.2.3 From e7c25e3ba04b1e9f8e6fa31e2d464fe96a074dad Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 May 2015 17:25:25 -0700 Subject: telefire: Make 'good' RSSI value configurable Different radios will have different 'good' RSSI values, so let each product configure it, leaving the default set to -90dBm, which is a solid signal value for the CC1111. Signed-off-by: Keith Packard --- src/drivers/ao_pad.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c index dc2c83fe..3ad239cc 100644 --- a/src/drivers/ao_pad.c +++ b/src/drivers/ao_pad.c @@ -29,6 +29,10 @@ static __pdata uint8_t ao_pad_box; static __xdata uint8_t ao_pad_disabled; static __pdata uint16_t ao_pad_packet_time; +#ifndef AO_PAD_RSSI_MINIMUM +#define AO_PAD_RSSI_MINIMUM -90 +#endif + #define DEBUG 1 #if DEBUG @@ -36,8 +40,8 @@ static __pdata uint8_t ao_pad_debug; #define PRINTD(...) (ao_pad_debug ? (printf(__VA_ARGS__), 0) : 0) #define FLUSHD() (ao_pad_debug ? (flush(), 0) : 0) #else -#define PRINTD(...) -#define FLUSHD() +#define PRINTD(...) +#define FLUSHD() #endif static void @@ -138,7 +142,7 @@ ao_pad_monitor(void) } if ((ao_time() - ao_pad_packet_time) > AO_SEC_TO_TICKS(2)) cur |= AO_LED_RED; - else if (ao_radio_cmac_rssi < -90) + else if (ao_radio_cmac_rssi < AO_PAD_RSSI_MINIMUM) cur |= AO_LED_AMBER; else cur |= AO_LED_GREEN; @@ -255,7 +259,7 @@ ao_pad(void) if (ret != AO_RADIO_CMAC_OK) continue; ao_pad_packet_time = ao_time(); - + ao_pad_box = ao_pad_read_box(); PRINTD ("tick %d box %d (me %d) cmd %d channels %02x\n", -- cgit v1.2.3 From 0e76cb2a7d5db24b6cecdccb6fb8d5bf5527fadf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 May 2015 17:28:07 -0700 Subject: altos: Only set CMAC RSSI value on valid packet received This ignores spurious packets for the purpose of showing the RSSI value in telelco/telefire, avoiding warning about 'low RSSI' when the radio receives noise. Signed-off-by: Keith Packard --- src/kernel/ao_radio_cmac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/kernel/ao_radio_cmac.c b/src/kernel/ao_radio_cmac.c index bff848f6..b6835346 100644 --- a/src/kernel/ao_radio_cmac.c +++ b/src/kernel/ao_radio_cmac.c @@ -91,7 +91,6 @@ radio_cmac_recv(uint8_t len, uint16_t timeout) __reentrant return AO_RADIO_CMAC_TIMEOUT; } - ao_radio_cmac_rssi = ao_radio_rssi; if (!(cmac_data[len + AO_CMAC_KEY_LEN +1] & AO_RADIO_STATUS_CRC_OK)) return AO_RADIO_CMAC_CRC_ERROR; @@ -114,13 +113,15 @@ radio_cmac_recv(uint8_t len, uint16_t timeout) __reentrant /* 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; } + ao_radio_cmac_rssi = ao_radio_rssi; + return AO_RADIO_CMAC_OK; } @@ -161,4 +162,3 @@ ao_radio_cmac_recv(__xdata void *packet, uint8_t len, uint16_t timeout) __reentr ao_mutex_put(&ao_radio_cmac_mutex); return i; } - -- cgit v1.2.3 From 9b268351aee44de959dcc4c792189c10a00428fe Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 25 May 2015 13:23:54 -0700 Subject: telefire: Report telefire battery voltage over telemetry link Signed-off-by: Keith Packard --- src/drivers/ao_pad.c | 2 ++ src/drivers/ao_pad.h | 1 + 2 files changed, 3 insertions(+) (limited to 'src') diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c index 3ad239cc..ffe46c68 100644 --- a/src/drivers/ao_pad.c +++ b/src/drivers/ao_pad.c @@ -127,6 +127,8 @@ ao_pad_monitor(void) #define VOLTS_TO_PYRO(x) ((int16_t) ((x) * 27.0 / 127.0 / 3.3 * 32767.0)) + /* convert ADC value to voltage in tenths, then add .2 for the diode drop */ + query.battery = (packet->adc.batt + 96) / 192 + 2; cur = 0; if (pyro > VOLTS_TO_PYRO(10)) { query.arm_status = AO_PAD_ARM_STATUS_ARMED; diff --git a/src/drivers/ao_pad.h b/src/drivers/ao_pad.h index 23062899..d77d105a 100644 --- a/src/drivers/ao_pad.h +++ b/src/drivers/ao_pad.h @@ -39,6 +39,7 @@ struct ao_pad_query { uint8_t channels; /* which chanels are present */ uint8_t armed; /* which channels are armed */ uint8_t arm_status; /* status of arming switch */ + uint8_t battery; /* battery voltage in decivolts */ uint8_t igniter_status[AO_PAD_MAX_CHANNELS]; /* status for each igniter */ }; -- cgit v1.2.3 From a54aac3361b7bd18f111e5ba06fb89015504b8a4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 25 May 2015 15:47:46 -0700 Subject: altos: Add telelco v0.3 (v0.2 with cc1200 instead of cc1120) Signed-off-by: Keith Packard --- src/Makefile | 1 + src/drivers/ao_lco.c | 399 ++++++++++++++++++++++++++++++++ src/drivers/ao_lco.h | 24 ++ src/telelco-v0.2/ao_lco.c | 399 -------------------------------- src/telelco-v0.2/ao_lco.h | 24 -- src/telelco-v0.3/.gitignore | 2 + src/telelco-v0.3/Makefile | 108 +++++++++ src/telelco-v0.3/ao_pins.h | 269 +++++++++++++++++++++ src/telelco-v0.3/ao_telelco.c | 70 ++++++ src/telelco-v0.3/flash-loader/Makefile | 8 + src/telelco-v0.3/flash-loader/ao_pins.h | 34 +++ 11 files changed, 915 insertions(+), 423 deletions(-) create mode 100644 src/drivers/ao_lco.c create mode 100644 src/drivers/ao_lco.h delete mode 100644 src/telelco-v0.2/ao_lco.c delete mode 100644 src/telelco-v0.2/ao_lco.h create mode 100644 src/telelco-v0.3/.gitignore create mode 100644 src/telelco-v0.3/Makefile create mode 100644 src/telelco-v0.3/ao_pins.h create mode 100644 src/telelco-v0.3/ao_telelco.c create mode 100644 src/telelco-v0.3/flash-loader/Makefile create mode 100644 src/telelco-v0.3/flash-loader/ao_pins.h (limited to 'src') diff --git a/src/Makefile b/src/Makefile index d4c8a86f..dc74bf8c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,6 +34,7 @@ ARMM3DIRS=\ telegps-v0.3 telegps-v0.3/flash-loader \ telegps-v1.0 telegps-v1.0/flash-loader \ telelco-v0.2 telelco-v0.2/flash-loader \ + telelco-v0.3 telelco-v0.3/flash-loader \ telescience-v0.2 telescience-v0.2/flash-loader \ teledongle-v3.0 teledongle-v3.0/flash-loader \ teleballoon-v2.0 \ diff --git a/src/drivers/ao_lco.c b/src/drivers/ao_lco.c new file mode 100644 index 00000000..12a247bf --- /dev/null +++ b/src/drivers/ao_lco.c @@ -0,0 +1,399 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#define DEBUG 1 + +#if DEBUG +static uint8_t ao_lco_debug; +#define PRINTD(...) do { if (!ao_lco_debug) break; printf ("\r%5u %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); flush(); } while(0) +#else +#define PRINTD(...) +#endif + +#define AO_LCO_PAD_DIGIT 0 +#define AO_LCO_BOX_DIGIT_1 1 +#define AO_LCO_BOX_DIGIT_10 2 + +static uint8_t ao_lco_min_box, ao_lco_max_box; +static uint8_t ao_lco_pad; +static uint8_t ao_lco_box; +static uint8_t ao_lco_armed; +static uint8_t ao_lco_firing; +static uint8_t ao_lco_valid; +static uint8_t ao_lco_got_channels; +static uint16_t ao_lco_tick_offset; + +static struct ao_pad_query ao_pad_query; + +static void +ao_lco_set_pad(uint8_t pad) +{ + ao_seven_segment_set(AO_LCO_PAD_DIGIT, pad + 1); +} + +static void +ao_lco_set_box(uint8_t box) +{ + ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, box % 10); + ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, box / 10); +} + +#define MASK_SIZE(n) (((n) + 7) >> 3) +#define MASK_ID(n) ((n) >> 3) +#define MASK_SHIFT(n) ((n) & 7) + +static uint8_t ao_lco_box_mask[MASK_SIZE(AO_PAD_MAX_BOXES)]; + +static uint8_t +ao_lco_box_present(uint8_t box) +{ + if (box >= AO_PAD_MAX_BOXES) + return 0; + return (ao_lco_box_mask[MASK_ID(box)] >> MASK_SHIFT(box)) & 1; +} + +static uint8_t +ao_lco_pad_present(uint8_t pad) +{ + if (!ao_lco_got_channels || !ao_pad_query.channels) + return pad == 0; + if (pad >= AO_PAD_MAX_CHANNELS) + return 0; + return (ao_pad_query.channels >> pad) & 1; +} + +static uint8_t +ao_lco_pad_first(void) +{ + uint8_t pad; + + for (pad = 0; pad < AO_PAD_MAX_CHANNELS; pad++) + if (ao_lco_pad_present(pad)) + return pad; + return 0; +} + +static void +ao_lco_input(void) +{ + static struct ao_event event; + int8_t dir, new_box, new_pad; + + ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); + for (;;) { + ao_event_get(&event); + PRINTD("event type %d unit %d value %d\n", + event.type, event.unit, event.value); + switch (event.type) { + case AO_EVENT_QUADRATURE: + switch (event.unit) { + case AO_QUADRATURE_PAD: + if (!ao_lco_armed) { + dir = (int8_t) event.value; + new_pad = ao_lco_pad; + do { + new_pad += dir; + if (new_pad > AO_PAD_MAX_CHANNELS) + new_pad = 0; + else if (new_pad < 0) + new_pad = AO_PAD_MAX_CHANNELS - 1; + if (new_pad == ao_lco_pad) + break; + } while (!ao_lco_pad_present(new_pad)); + if (new_pad != ao_lco_pad) { + ao_lco_pad = new_pad; + ao_lco_set_pad(ao_lco_pad); + } + } + break; + case AO_QUADRATURE_BOX: + if (!ao_lco_armed) { + dir = (int8_t) event.value; + new_box = ao_lco_box; + do { + new_box += dir; + if (new_box > ao_lco_max_box) + new_box = ao_lco_min_box; + else if (new_box < ao_lco_min_box) + new_box = ao_lco_max_box; + if (new_box == ao_lco_box) + break; + } while (!ao_lco_box_present(new_box)); + if (ao_lco_box != new_box) { + ao_lco_box = new_box; + ao_lco_got_channels = 0; + ao_lco_set_box(ao_lco_box); + } + } + break; + } + break; + case AO_EVENT_BUTTON: + switch (event.unit) { + case AO_BUTTON_ARM: + ao_lco_armed = event.value; + PRINTD("Armed %d\n", ao_lco_armed); + ao_wakeup(&ao_lco_armed); + break; + case AO_BUTTON_FIRE: + if (ao_lco_armed) { + ao_lco_firing = event.value; + PRINTD("Firing %d\n", ao_lco_firing); + ao_wakeup(&ao_lco_armed); + } + break; + } + break; + } + } +} + +static AO_LED_TYPE continuity_led[AO_LED_CONTINUITY_NUM] = { +#ifdef AO_LED_CONTINUITY_0 + AO_LED_CONTINUITY_0, +#endif +#ifdef AO_LED_CONTINUITY_1 + AO_LED_CONTINUITY_1, +#endif +#ifdef AO_LED_CONTINUITY_2 + AO_LED_CONTINUITY_2, +#endif +#ifdef AO_LED_CONTINUITY_3 + AO_LED_CONTINUITY_3, +#endif +#ifdef AO_LED_CONTINUITY_4 + AO_LED_CONTINUITY_4, +#endif +#ifdef AO_LED_CONTINUITY_5 + AO_LED_CONTINUITY_5, +#endif +#ifdef AO_LED_CONTINUITY_6 + AO_LED_CONTINUITY_6, +#endif +#ifdef AO_LED_CONTINUITY_7 + AO_LED_CONTINUITY_7, +#endif +}; + +static void +ao_lco_update(void) +{ + int8_t r; + uint8_t c; + + r = ao_lco_query(ao_lco_box, &ao_pad_query, &ao_lco_tick_offset); + if (r == AO_RADIO_CMAC_OK) { + c = ao_lco_got_channels; + ao_lco_got_channels = 1; + ao_lco_valid = 1; + if (!c) { + ao_lco_pad = ao_lco_pad_first(); + ao_lco_set_pad(ao_lco_pad); + } + } else + ao_lco_valid = 0; + +#if 0 + PRINTD("lco_query success arm_status %d i0 %d i1 %d i2 %d i3 %d\n", + query.arm_status, + query.igniter_status[0], + query.igniter_status[1], + query.igniter_status[2], + query.igniter_status[3]); +#endif + ao_wakeup(&ao_pad_query); +} + +static void +ao_lco_box_reset_present(void) +{ + ao_lco_min_box = 0xff; + ao_lco_max_box = 0x00; + memset(ao_lco_box_mask, 0, sizeof (ao_lco_box_mask)); +} + +static void +ao_lco_box_set_present(uint8_t box) +{ + if (box < ao_lco_min_box) + ao_lco_min_box = box; + if (box > ao_lco_max_box) + ao_lco_max_box = box; + if (box >= AO_PAD_MAX_BOXES) + return; + ao_lco_box_mask[MASK_ID(box)] |= 1 << MASK_SHIFT(box); +} + +static void +ao_lco_search(void) +{ + uint16_t tick_offset; + int8_t r; + int8_t try; + uint8_t box; + + ao_lco_box_reset_present(); + for (box = 0; box < AO_PAD_MAX_BOXES; box++) { + if ((box % 10) == 0) + ao_lco_set_box(box); + for (try = 0; try < 3; try++) { + tick_offset = 0; + r = ao_lco_query(box, &ao_pad_query, &tick_offset); + PRINTD("box %d result %d\n", box, r); + if (r == AO_RADIO_CMAC_OK) { + ao_lco_box_set_present(box); + ao_delay(AO_MS_TO_TICKS(30)); + break; + } + } + } + if (ao_lco_min_box <= ao_lco_max_box) + ao_lco_box = ao_lco_min_box; + else + ao_lco_min_box = ao_lco_max_box = ao_lco_box = 0; + ao_lco_valid = 0; + ao_lco_got_channels = 0; + ao_lco_pad = 0; + ao_lco_set_pad(ao_lco_pad); + ao_lco_set_box(ao_lco_box); +} + +static void +ao_lco_igniter_status(void) +{ + uint8_t c; + + for (;;) { + ao_sleep(&ao_pad_query); + if (!ao_lco_valid) { + ao_led_on(AO_LED_RED); + ao_led_off(AO_LED_GREEN|AO_LED_AMBER); + continue; + } + PRINTD("RSSI %d\n", ao_radio_cmac_rssi); + if (ao_radio_cmac_rssi < -90) { + ao_led_on(AO_LED_AMBER); + ao_led_off(AO_LED_RED|AO_LED_GREEN); + } else { + ao_led_on(AO_LED_GREEN); + ao_led_off(AO_LED_RED|AO_LED_AMBER); + } + if (ao_pad_query.arm_status) + ao_led_on(AO_LED_REMOTE_ARM); + else + ao_led_off(AO_LED_REMOTE_ARM); + for (c = 0; c < AO_LED_CONTINUITY_NUM; c++) { + uint8_t status; + + if (ao_pad_query.channels & (1 << c)) + status = ao_pad_query.igniter_status[c]; + else + status = AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN; + if (status == AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN) + ao_led_on(continuity_led[c]); + else + ao_led_off(continuity_led[c]); + } + } +} + +static void +ao_lco_arm_warn(void) +{ + for (;;) { + while (!ao_lco_armed) + ao_sleep(&ao_lco_armed); + ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); + ao_delay(AO_MS_TO_TICKS(200)); + } +} + +static struct ao_task ao_lco_input_task; +static struct ao_task ao_lco_monitor_task; +static struct ao_task ao_lco_arm_warn_task; +static struct ao_task ao_lco_igniter_status_task; + +static void +ao_lco_monitor(void) +{ + uint16_t delay; + + ao_lco_search(); + ao_add_task(&ao_lco_input_task, ao_lco_input, "lco input"); + ao_add_task(&ao_lco_arm_warn_task, ao_lco_arm_warn, "lco arm warn"); + ao_add_task(&ao_lco_igniter_status_task, ao_lco_igniter_status, "lco igniter status"); + for (;;) { + PRINTD("monitor armed %d firing %d offset %d\n", + ao_lco_armed, ao_lco_firing, ao_lco_tick_offset); + + if (ao_lco_armed && ao_lco_firing) { + PRINTD("Firing box %d pad %d: valid %d\n", + ao_lco_box, ao_lco_pad, ao_lco_valid); + if (!ao_lco_valid) + ao_lco_update(); + if (ao_lco_valid) + ao_lco_ignite(ao_lco_box, 1 << ao_lco_pad, ao_lco_tick_offset); + } else if (ao_lco_armed) { + PRINTD("Arming box %d pad %d\n", + ao_lco_box, ao_lco_pad); + if (!ao_lco_valid) + ao_lco_update(); + ao_lco_arm(ao_lco_box, 1 << ao_lco_pad, ao_lco_tick_offset); + ao_lco_update(); + } else { + ao_lco_update(); + } + if (ao_lco_armed && ao_lco_firing) + delay = AO_MS_TO_TICKS(100); + else + delay = AO_SEC_TO_TICKS(1); + ao_sleep_for(&ao_lco_armed, delay); + } +} + +#if DEBUG +void +ao_lco_set_debug(void) +{ + ao_cmd_decimal(); + if (ao_cmd_status == ao_cmd_success) + ao_lco_debug = ao_cmd_lex_i != 0; +} + +__code struct ao_cmds ao_lco_cmds[] = { + { ao_lco_set_debug, "D <0 off, 1 on>\0Debug" }, + { ao_lco_search, "s\0Search for pad boxes" }, + { 0, NULL } +}; +#endif + +void +ao_lco_init(void) +{ + ao_add_task(&ao_lco_monitor_task, ao_lco_monitor, "lco monitor"); +#if DEBUG + ao_cmd_register(&ao_lco_cmds[0]); +#endif +} diff --git a/src/drivers/ao_lco.h b/src/drivers/ao_lco.h new file mode 100644 index 00000000..253f9702 --- /dev/null +++ b/src/drivers/ao_lco.h @@ -0,0 +1,24 @@ +/* + * 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_LCO_H_ +#define _AO_LCO_H_ + +void +ao_lco_init(void); + +#endif /* _AO_LCO_H_ */ diff --git a/src/telelco-v0.2/ao_lco.c b/src/telelco-v0.2/ao_lco.c deleted file mode 100644 index 12a247bf..00000000 --- a/src/telelco-v0.2/ao_lco.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include - -#define DEBUG 1 - -#if DEBUG -static uint8_t ao_lco_debug; -#define PRINTD(...) do { if (!ao_lco_debug) break; printf ("\r%5u %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); flush(); } while(0) -#else -#define PRINTD(...) -#endif - -#define AO_LCO_PAD_DIGIT 0 -#define AO_LCO_BOX_DIGIT_1 1 -#define AO_LCO_BOX_DIGIT_10 2 - -static uint8_t ao_lco_min_box, ao_lco_max_box; -static uint8_t ao_lco_pad; -static uint8_t ao_lco_box; -static uint8_t ao_lco_armed; -static uint8_t ao_lco_firing; -static uint8_t ao_lco_valid; -static uint8_t ao_lco_got_channels; -static uint16_t ao_lco_tick_offset; - -static struct ao_pad_query ao_pad_query; - -static void -ao_lco_set_pad(uint8_t pad) -{ - ao_seven_segment_set(AO_LCO_PAD_DIGIT, pad + 1); -} - -static void -ao_lco_set_box(uint8_t box) -{ - ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, box % 10); - ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, box / 10); -} - -#define MASK_SIZE(n) (((n) + 7) >> 3) -#define MASK_ID(n) ((n) >> 3) -#define MASK_SHIFT(n) ((n) & 7) - -static uint8_t ao_lco_box_mask[MASK_SIZE(AO_PAD_MAX_BOXES)]; - -static uint8_t -ao_lco_box_present(uint8_t box) -{ - if (box >= AO_PAD_MAX_BOXES) - return 0; - return (ao_lco_box_mask[MASK_ID(box)] >> MASK_SHIFT(box)) & 1; -} - -static uint8_t -ao_lco_pad_present(uint8_t pad) -{ - if (!ao_lco_got_channels || !ao_pad_query.channels) - return pad == 0; - if (pad >= AO_PAD_MAX_CHANNELS) - return 0; - return (ao_pad_query.channels >> pad) & 1; -} - -static uint8_t -ao_lco_pad_first(void) -{ - uint8_t pad; - - for (pad = 0; pad < AO_PAD_MAX_CHANNELS; pad++) - if (ao_lco_pad_present(pad)) - return pad; - return 0; -} - -static void -ao_lco_input(void) -{ - static struct ao_event event; - int8_t dir, new_box, new_pad; - - ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); - for (;;) { - ao_event_get(&event); - PRINTD("event type %d unit %d value %d\n", - event.type, event.unit, event.value); - switch (event.type) { - case AO_EVENT_QUADRATURE: - switch (event.unit) { - case AO_QUADRATURE_PAD: - if (!ao_lco_armed) { - dir = (int8_t) event.value; - new_pad = ao_lco_pad; - do { - new_pad += dir; - if (new_pad > AO_PAD_MAX_CHANNELS) - new_pad = 0; - else if (new_pad < 0) - new_pad = AO_PAD_MAX_CHANNELS - 1; - if (new_pad == ao_lco_pad) - break; - } while (!ao_lco_pad_present(new_pad)); - if (new_pad != ao_lco_pad) { - ao_lco_pad = new_pad; - ao_lco_set_pad(ao_lco_pad); - } - } - break; - case AO_QUADRATURE_BOX: - if (!ao_lco_armed) { - dir = (int8_t) event.value; - new_box = ao_lco_box; - do { - new_box += dir; - if (new_box > ao_lco_max_box) - new_box = ao_lco_min_box; - else if (new_box < ao_lco_min_box) - new_box = ao_lco_max_box; - if (new_box == ao_lco_box) - break; - } while (!ao_lco_box_present(new_box)); - if (ao_lco_box != new_box) { - ao_lco_box = new_box; - ao_lco_got_channels = 0; - ao_lco_set_box(ao_lco_box); - } - } - break; - } - break; - case AO_EVENT_BUTTON: - switch (event.unit) { - case AO_BUTTON_ARM: - ao_lco_armed = event.value; - PRINTD("Armed %d\n", ao_lco_armed); - ao_wakeup(&ao_lco_armed); - break; - case AO_BUTTON_FIRE: - if (ao_lco_armed) { - ao_lco_firing = event.value; - PRINTD("Firing %d\n", ao_lco_firing); - ao_wakeup(&ao_lco_armed); - } - break; - } - break; - } - } -} - -static AO_LED_TYPE continuity_led[AO_LED_CONTINUITY_NUM] = { -#ifdef AO_LED_CONTINUITY_0 - AO_LED_CONTINUITY_0, -#endif -#ifdef AO_LED_CONTINUITY_1 - AO_LED_CONTINUITY_1, -#endif -#ifdef AO_LED_CONTINUITY_2 - AO_LED_CONTINUITY_2, -#endif -#ifdef AO_LED_CONTINUITY_3 - AO_LED_CONTINUITY_3, -#endif -#ifdef AO_LED_CONTINUITY_4 - AO_LED_CONTINUITY_4, -#endif -#ifdef AO_LED_CONTINUITY_5 - AO_LED_CONTINUITY_5, -#endif -#ifdef AO_LED_CONTINUITY_6 - AO_LED_CONTINUITY_6, -#endif -#ifdef AO_LED_CONTINUITY_7 - AO_LED_CONTINUITY_7, -#endif -}; - -static void -ao_lco_update(void) -{ - int8_t r; - uint8_t c; - - r = ao_lco_query(ao_lco_box, &ao_pad_query, &ao_lco_tick_offset); - if (r == AO_RADIO_CMAC_OK) { - c = ao_lco_got_channels; - ao_lco_got_channels = 1; - ao_lco_valid = 1; - if (!c) { - ao_lco_pad = ao_lco_pad_first(); - ao_lco_set_pad(ao_lco_pad); - } - } else - ao_lco_valid = 0; - -#if 0 - PRINTD("lco_query success arm_status %d i0 %d i1 %d i2 %d i3 %d\n", - query.arm_status, - query.igniter_status[0], - query.igniter_status[1], - query.igniter_status[2], - query.igniter_status[3]); -#endif - ao_wakeup(&ao_pad_query); -} - -static void -ao_lco_box_reset_present(void) -{ - ao_lco_min_box = 0xff; - ao_lco_max_box = 0x00; - memset(ao_lco_box_mask, 0, sizeof (ao_lco_box_mask)); -} - -static void -ao_lco_box_set_present(uint8_t box) -{ - if (box < ao_lco_min_box) - ao_lco_min_box = box; - if (box > ao_lco_max_box) - ao_lco_max_box = box; - if (box >= AO_PAD_MAX_BOXES) - return; - ao_lco_box_mask[MASK_ID(box)] |= 1 << MASK_SHIFT(box); -} - -static void -ao_lco_search(void) -{ - uint16_t tick_offset; - int8_t r; - int8_t try; - uint8_t box; - - ao_lco_box_reset_present(); - for (box = 0; box < AO_PAD_MAX_BOXES; box++) { - if ((box % 10) == 0) - ao_lco_set_box(box); - for (try = 0; try < 3; try++) { - tick_offset = 0; - r = ao_lco_query(box, &ao_pad_query, &tick_offset); - PRINTD("box %d result %d\n", box, r); - if (r == AO_RADIO_CMAC_OK) { - ao_lco_box_set_present(box); - ao_delay(AO_MS_TO_TICKS(30)); - break; - } - } - } - if (ao_lco_min_box <= ao_lco_max_box) - ao_lco_box = ao_lco_min_box; - else - ao_lco_min_box = ao_lco_max_box = ao_lco_box = 0; - ao_lco_valid = 0; - ao_lco_got_channels = 0; - ao_lco_pad = 0; - ao_lco_set_pad(ao_lco_pad); - ao_lco_set_box(ao_lco_box); -} - -static void -ao_lco_igniter_status(void) -{ - uint8_t c; - - for (;;) { - ao_sleep(&ao_pad_query); - if (!ao_lco_valid) { - ao_led_on(AO_LED_RED); - ao_led_off(AO_LED_GREEN|AO_LED_AMBER); - continue; - } - PRINTD("RSSI %d\n", ao_radio_cmac_rssi); - if (ao_radio_cmac_rssi < -90) { - ao_led_on(AO_LED_AMBER); - ao_led_off(AO_LED_RED|AO_LED_GREEN); - } else { - ao_led_on(AO_LED_GREEN); - ao_led_off(AO_LED_RED|AO_LED_AMBER); - } - if (ao_pad_query.arm_status) - ao_led_on(AO_LED_REMOTE_ARM); - else - ao_led_off(AO_LED_REMOTE_ARM); - for (c = 0; c < AO_LED_CONTINUITY_NUM; c++) { - uint8_t status; - - if (ao_pad_query.channels & (1 << c)) - status = ao_pad_query.igniter_status[c]; - else - status = AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN; - if (status == AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN) - ao_led_on(continuity_led[c]); - else - ao_led_off(continuity_led[c]); - } - } -} - -static void -ao_lco_arm_warn(void) -{ - for (;;) { - while (!ao_lco_armed) - ao_sleep(&ao_lco_armed); - ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); - ao_delay(AO_MS_TO_TICKS(200)); - } -} - -static struct ao_task ao_lco_input_task; -static struct ao_task ao_lco_monitor_task; -static struct ao_task ao_lco_arm_warn_task; -static struct ao_task ao_lco_igniter_status_task; - -static void -ao_lco_monitor(void) -{ - uint16_t delay; - - ao_lco_search(); - ao_add_task(&ao_lco_input_task, ao_lco_input, "lco input"); - ao_add_task(&ao_lco_arm_warn_task, ao_lco_arm_warn, "lco arm warn"); - ao_add_task(&ao_lco_igniter_status_task, ao_lco_igniter_status, "lco igniter status"); - for (;;) { - PRINTD("monitor armed %d firing %d offset %d\n", - ao_lco_armed, ao_lco_firing, ao_lco_tick_offset); - - if (ao_lco_armed && ao_lco_firing) { - PRINTD("Firing box %d pad %d: valid %d\n", - ao_lco_box, ao_lco_pad, ao_lco_valid); - if (!ao_lco_valid) - ao_lco_update(); - if (ao_lco_valid) - ao_lco_ignite(ao_lco_box, 1 << ao_lco_pad, ao_lco_tick_offset); - } else if (ao_lco_armed) { - PRINTD("Arming box %d pad %d\n", - ao_lco_box, ao_lco_pad); - if (!ao_lco_valid) - ao_lco_update(); - ao_lco_arm(ao_lco_box, 1 << ao_lco_pad, ao_lco_tick_offset); - ao_lco_update(); - } else { - ao_lco_update(); - } - if (ao_lco_armed && ao_lco_firing) - delay = AO_MS_TO_TICKS(100); - else - delay = AO_SEC_TO_TICKS(1); - ao_sleep_for(&ao_lco_armed, delay); - } -} - -#if DEBUG -void -ao_lco_set_debug(void) -{ - ao_cmd_decimal(); - if (ao_cmd_status == ao_cmd_success) - ao_lco_debug = ao_cmd_lex_i != 0; -} - -__code struct ao_cmds ao_lco_cmds[] = { - { ao_lco_set_debug, "D <0 off, 1 on>\0Debug" }, - { ao_lco_search, "s\0Search for pad boxes" }, - { 0, NULL } -}; -#endif - -void -ao_lco_init(void) -{ - ao_add_task(&ao_lco_monitor_task, ao_lco_monitor, "lco monitor"); -#if DEBUG - ao_cmd_register(&ao_lco_cmds[0]); -#endif -} diff --git a/src/telelco-v0.2/ao_lco.h b/src/telelco-v0.2/ao_lco.h deleted file mode 100644 index 253f9702..00000000 --- a/src/telelco-v0.2/ao_lco.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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_LCO_H_ -#define _AO_LCO_H_ - -void -ao_lco_init(void); - -#endif /* _AO_LCO_H_ */ diff --git a/src/telelco-v0.3/.gitignore b/src/telelco-v0.3/.gitignore new file mode 100644 index 00000000..a32ec26e --- /dev/null +++ b/src/telelco-v0.3/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +telelco*.elf diff --git a/src/telelco-v0.3/Makefile b/src/telelco-v0.3/Makefile new file mode 100644 index 00000000..83d3fc43 --- /dev/null +++ b/src/telelco-v0.3/Makefile @@ -0,0 +1,108 @@ +# +# AltOS build for TeleLCO +# +# + +include ../stm/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_boot.h \ + ao_companion.h \ + ao_data.h \ + ao_sample.h \ + ao_pins.h \ + ao_product.h \ + ao_seven_segment.h \ + ao_lco.h \ + ao_lco_cmd.h \ + ao_lco_func.h \ + ao_radio_spi.h \ + ao_radio_cmac.h \ + ao_cc1200_CC1200.h \ + ao_cc1200.h \ + ao_debounce.h \ + stm32l.h + +# +# Common AltOS sources +# + +#PROFILE=ao_profile.c +#PROFILE_DEF=-DAO_PROFILE=1 + +ALTOS_SRC = \ + ao_boot_chain.c \ + ao_interrupt.c \ + ao_product.c \ + ao_romconfig.c \ + ao_cmd.c \ + ao_config.c \ + ao_task.c \ + ao_led.c \ + ao_stdio.c \ + ao_panic.c \ + ao_timer.c \ + ao_mutex.c \ + ao_freq.c \ + ao_dma_stm.c \ + ao_spi_stm.c \ + ao_beep_stm.c \ + ao_eeprom_stm.c \ + ao_fast_timer.c \ + ao_lcd_stm.c \ + ao_usb_stm.c \ + ao_exti_stm.c \ + ao_cc1200.c \ + ao_radio_cmac.c \ + ao_aes.c \ + ao_aes_tables.c \ + ao_fec_tx.c \ + ao_fec_rx.c \ + ao_seven_segment.c \ + ao_debounce.c \ + ao_quadrature.c \ + ao_button.c \ + ao_event.c \ + ao_lco.c \ + ao_lco_cmd.c \ + ao_lco_func.c \ + ao_radio_cmac_cmd.c + +PRODUCT=TeleLCO-v0.3 +PRODUCT_DEF=-DTELELCO +IDPRODUCT=0x0023 + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) -Os -g + +PROGNAME=telelco-v0.3 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) ao_telelco.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) $(HEX) + +$(PROG): Makefile $(OBJ) altos.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +../altitude.h: make-altitude + nickle $< > $@ + +$(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 $(PROGNAME)-*.elf $(PROGNAME)-*.ihx + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/telelco-v0.3/ao_pins.h b/src/telelco-v0.3/ao_pins.h new file mode 100644 index 00000000..92095a7c --- /dev/null +++ b/src/telelco-v0.3/ao_pins.h @@ -0,0 +1,269 @@ +/* + * 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_ + +/* 8MHz High speed external crystal */ +#define AO_HSE 8000000 + +/* PLLVCO = 96MHz (so that USB will work) */ +#define AO_PLLMUL 12 +#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12) + +#define AO_CC1200_FOSC 40000000 + +/* SYSCLK = 32MHz (no need to go faster than CPU) */ +#define AO_PLLDIV 3 +#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_3) + +/* HCLK = 32MHz (CPU clock) */ +#define AO_AHB_PRESCALER 1 +#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at 16MHz (HCLK/2) */ +#define AO_APB1_PRESCALER 2 +#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +/* Run APB2 at 16MHz (HCLK/2) */ +#define AO_APB2_PRESCALER 2 +#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +#define HAS_EEPROM 1 +#define USE_INTERNAL_FLASH 1 +#define USE_EEPROM_CONFIG 1 +#define USE_STORAGE_CONFIG 0 +#define HAS_USB 1 +#define HAS_BEEP 1 +#define HAS_RADIO 1 +#define HAS_RADIO_RATE 1 +#define HAS_TELEMETRY 0 +#define HAS_AES 1 + +#define HAS_SPI_1 0 +#define SPI_1_PA5_PA6_PA7 0 +#define SPI_1_PB3_PB4_PB5 0 +#define SPI_1_PE13_PE14_PE15 0 + +#define HAS_SPI_2 1 /* CC1120 */ +#define SPI_2_PB13_PB14_PB15 0 +#define SPI_2_PD1_PD3_PD4 1 +#define SPI_2_GPIO (&stm_gpiod) +#define SPI_2_SCK 1 +#define SPI_2_MISO 3 +#define SPI_2_MOSI 4 +#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz + +#define HAS_I2C_1 0 + +#define HAS_I2C_2 0 + +#define PACKET_HAS_SLAVE 0 +#define PACKET_HAS_MASTER 0 + +#define FAST_TIMER_FREQ 10000 /* .1ms for debouncing */ + +/* + * Radio is a cc1200 connected via SPI + */ + +#define AO_RADIO_CAL_DEFAULT 5695733 + +#define AO_FEC_DEBUG 0 +#define AO_CC1200_SPI_CS_PORT (&stm_gpiod) +#define AO_CC1200_SPI_CS_PIN 0 +#define AO_CC1200_SPI_BUS AO_SPI_2_PD1_PD3_PD4 +#define AO_CC1200_SPI stm_spi2 + +#define AO_CC1200_INT_PORT (&stm_gpioc) +#define AO_CC1200_INT_PIN (15) + +#define AO_CC1200_INT_GPIO 2 +#define AO_CC1200_INT_GPIO_IOCFG CC1200_IOCFG2 + +#define LOW_LEVEL_DEBUG 0 + +#define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOCEN +#define LED_PORT (&stm_gpioc) +#define LED_PIN_RED 7 +#define LED_PIN_AMBER 8 +#define LED_PIN_GREEN 9 +#define LED_PIN_CONTINUITY_3 10 +#define LED_PIN_CONTINUITY_2 11 +#define LED_PIN_CONTINUITY_1 12 +#define LED_PIN_CONTINUITY_0 13 +#define LED_PIN_REMOTE_ARM 14 +#define AO_LED_RED (1 << LED_PIN_RED) +#define AO_LED_AMBER (1 << LED_PIN_AMBER) +#define AO_LED_GREEN (1 << LED_PIN_GREEN) +#define AO_LED_CONTINUITY_3 (1 << LED_PIN_CONTINUITY_3) +#define AO_LED_CONTINUITY_2 (1 << LED_PIN_CONTINUITY_2) +#define AO_LED_CONTINUITY_1 (1 << LED_PIN_CONTINUITY_1) +#define AO_LED_CONTINUITY_0 (1 << LED_PIN_CONTINUITY_0) + +#define AO_LED_CONTINUITY_NUM 4 + +#define AO_LED_REMOTE_ARM (1 << LED_PIN_REMOTE_ARM) + +#define LEDS_AVAILABLE (AO_LED_RED | \ + AO_LED_AMBER | \ + AO_LED_GREEN | \ + AO_LED_CONTINUITY_3 | \ + AO_LED_CONTINUITY_2 | \ + AO_LED_CONTINUITY_1 | \ + AO_LED_CONTINUITY_0 | \ + AO_LED_REMOTE_ARM) + +/* LCD displays */ + +#define LCD_DEBUG 0 +#define SEVEN_SEGMENT_DEBUG 0 + +#define AO_LCD_STM_SEG_ENABLED_0 ( \ + (1 << 0) | /* PA1 */ \ + (1 << 1) | /* PA2 */ \ + (1 << 2) | /* PA3 */ \ + (1 << 3) | /* PA6 */ \ + (1 << 4) | /* PA7 */ \ + (1 << 5) | /* PB0 */ \ + (1 << 6) | /* PB1 */ \ + (1 << 7) | /* PB3 */ \ + (1 << 8) | /* PB4 */ \ + (1 << 9) | /* PB5 */ \ + (1 << 10) | /* PB10 */ \ + (1 << 11) | /* PB11 */ \ + (1 << 12) | /* PB12 */ \ + (1 << 13) | /* PB13 */ \ + (1 << 14) | /* PB14 */ \ + (1 << 15) | /* PB15 */ \ + (1 << 16) | /* PB8 */ \ + (1 << 17) | /* PA15 */ \ + (1 << 18) | /* PC0 */ \ + (1 << 19) | /* PC1 */ \ + (1 << 20) | /* PC2 */ \ + (1 << 21) | /* PC3 */ \ + (1 << 22) | /* PC4 */ \ + (1 << 23) | /* PC5 */ \ + (0 << 24) | /* PC6 */ \ + (0 << 25) | /* PC7 */ \ + (0 << 26) | /* PC8 */ \ + (0 << 27) | /* PC9 */ \ + (0 << 28) | /* PC10 or PD8 */ \ + (0 << 29) | /* PC11 or PD9 */ \ + (0 << 30) | /* PC12 or PD10 */ \ + (0 << 31)) /* PD2 or PD11 */ + +#define AO_LCD_STM_SEG_ENABLED_1 ( \ + (0 << 0) | /* PD12 */ \ + (0 << 1) | /* PD13 */ \ + (0 << 2) | /* PD14 */ \ + (0 << 3) | /* PD15 */ \ + (0 << 4) | /* PE0 */ \ + (0 << 5) | /* PE1 */ \ + (0 << 6) | /* PE2 */ \ + (0 << 7)) /* PE3 */ + +#define AO_LCD_STM_COM_ENABLED ( \ + (1 << 0) | /* PA8 */ \ + (0 << 1) | /* PA9 */ \ + (0 << 2) | /* PA10 */ \ + (0 << 3) | /* PB9 */ \ + (0 << 4) | /* PC10 */ \ + (0 << 5) | /* PC11 */ \ + (0 << 6)) /* PC12 */ + +#define AO_LCD_28_ON_C 0 + +#define AO_LCD_DUTY STM_LCD_CR_DUTY_STATIC + +#define AO_LCD_PER_DIGIT 1 + +#define AO_LCD_DIGITS 3 +#define AO_LCD_SEGMENTS 8 + +#define AO_SEGMENT_MAP { \ + /* pad segments */ \ + { 0, 14 }, \ + { 0, 13 }, \ + { 0, 15 }, \ + { 0, 17 }, \ + { 0, 16 }, \ + { 0, 8 }, \ + { 0, 9 }, \ + { 0, 7 }, \ + /* box1 segments */ \ + { 0, 10 }, \ + { 0, 6 }, \ + { 0, 11 }, \ + { 0, 12 }, \ + { 0, 21 }, \ + { 0, 19 }, \ + { 0, 20 }, \ + { 0, 18 }, \ + /* box0 segments */ \ + { 0, 22 }, \ + { 0, 4 }, \ + { 0, 23 }, \ + { 0, 5 }, \ + { 0, 3 }, \ + { 0, 1 }, \ + { 0, 2 }, \ + { 0, 0 }, \ +} + +/* + * Use event queue for input devices + */ + +#define AO_EVENT 1 + +/* + * Knobs + */ + +#define AO_QUADRATURE_COUNT 2 + +#define AO_QUADRATURE_0_PORT &stm_gpioe +#define AO_QUADRATURE_0_A 3 +#define AO_QUADRATURE_0_B 2 + +#define AO_QUADRATURE_PAD 0 + +#define AO_QUADRATURE_1_PORT &stm_gpioe +#define AO_QUADRATURE_1_A 1 +#define AO_QUADRATURE_1_B 0 + +#define AO_QUADRATURE_BOX 1 + +/* + * Buttons + */ + +#define AO_BUTTON_COUNT 2 +#define AO_BUTTON_MODE AO_EXTI_MODE_PULL_UP + +#define AO_BUTTON_0_PORT &stm_gpioe +#define AO_BUTTON_0 4 + +#define AO_BUTTON_ARM 0 + +#define AO_BUTTON_1_PORT &stm_gpioe +#define AO_BUTTON_1 5 + +#define AO_BUTTON_FIRE 1 + +#endif /* _AO_PINS_H_ */ diff --git a/src/telelco-v0.3/ao_telelco.c b/src/telelco-v0.3/ao_telelco.c new file mode 100644 index 00000000..d9f7c693 --- /dev/null +++ b/src/telelco-v0.3/ao_telelco.c @@ -0,0 +1,70 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(void) +{ + ao_clock_init(); + + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_GREEN); + ao_task_init(); + + ao_timer_init(); + + ao_spi_init(); + ao_dma_init(); + ao_exti_init(); + + ao_beep_init(); + ao_cmd_init(); + + ao_lcd_stm_init(); + ao_seven_segment_init(); + ao_quadrature_init(); + ao_button_init(); + + ao_eeprom_init(); + + ao_radio_init(); + + ao_usb_init(); + + ao_config_init(); + + ao_lco_init(); + ao_lco_cmd_init(); +// ao_radio_cmac_cmd_init(); + + ao_start_scheduler(); + return 0; +} diff --git a/src/telelco-v0.3/flash-loader/Makefile b/src/telelco-v0.3/flash-loader/Makefile new file mode 100644 index 00000000..679e61ba --- /dev/null +++ b/src/telelco-v0.3/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=telelco-v0.2 +include $(TOPDIR)/stm/Makefile-flash.defs diff --git a/src/telelco-v0.3/flash-loader/ao_pins.h b/src/telelco-v0.3/flash-loader/ao_pins.h new file mode 100644 index 00000000..6c8ff7e2 --- /dev/null +++ b/src/telelco-v0.3/flash-loader/ao_pins.h @@ -0,0 +1,34 @@ +/* + * 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_ + +/* External crystal at 8MHz */ +#define AO_HSE 8000000 + +#include + +/* Arm switch. Press at power on to get boot loader */ + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO stm_gpioe +#define AO_BOOT_APPLICATION_PIN 4 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP + +#endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 91f617d450c187500593d1ae785958187f68ca14 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 25 May 2015 15:49:21 -0700 Subject: altos/telelco: Display telefire battery voltage When the firing button is pressed while unarmed, show the telefire battery voltage in the display. Signed-off-by: Keith Packard --- src/drivers/ao_lco.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_lco.c b/src/drivers/ao_lco.c index 12a247bf..9250d444 100644 --- a/src/drivers/ao_lco.c +++ b/src/drivers/ao_lco.c @@ -44,6 +44,7 @@ static uint8_t ao_lco_firing; static uint8_t ao_lco_valid; static uint8_t ao_lco_got_channels; static uint16_t ao_lco_tick_offset; +static uint8_t ao_lco_show_voltage; static struct ao_pad_query ao_pad_query; @@ -60,6 +61,19 @@ ao_lco_set_box(uint8_t box) ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, box / 10); } +static void +ao_lco_set_voltage(uint16_t decivolts) +{ + uint8_t tens, ones, tenths; + + tenths = decivolts % 10; + ones = (decivolts / 10) % 10; + tens = (decivolts / 100) % 10; + ao_seven_segment_set(AO_LCO_PAD_DIGIT, tenths); + ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, ones | 0x10); + ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, tens); +} + #define MASK_SIZE(n) (((n) + 7) >> 3) #define MASK_ID(n) ((n) >> 3) #define MASK_SHIFT(n) ((n) & 7) @@ -124,6 +138,7 @@ ao_lco_input(void) } while (!ao_lco_pad_present(new_pad)); if (new_pad != ao_lco_pad) { ao_lco_pad = new_pad; + ao_lco_set_box(ao_lco_box); ao_lco_set_pad(ao_lco_pad); } } @@ -145,6 +160,7 @@ ao_lco_input(void) ao_lco_box = new_box; ao_lco_got_channels = 0; ao_lco_set_box(ao_lco_box); + ao_lco_set_pad(ao_lco_pad); } } break; @@ -160,8 +176,18 @@ ao_lco_input(void) case AO_BUTTON_FIRE: if (ao_lco_armed) { ao_lco_firing = event.value; + ao_lco_show_voltage = 0; PRINTD("Firing %d\n", ao_lco_firing); ao_wakeup(&ao_lco_armed); + } else { + if (event.value) { + if (ao_lco_got_channels) + ao_lco_set_voltage(ao_pad_query.battery); + } else { + ao_lco_set_box(ao_lco_box); + ao_lco_set_pad(ao_lco_pad); + } + ao_lco_show_voltage = event.value; } break; } @@ -210,8 +236,11 @@ ao_lco_update(void) ao_lco_valid = 1; if (!c) { ao_lco_pad = ao_lco_pad_first(); - ao_lco_set_pad(ao_lco_pad); + if (!ao_lco_show_voltage) + ao_lco_set_pad(ao_lco_pad); } + if (ao_lco_show_voltage) + ao_lco_set_voltage(ao_pad_query.battery); } else ao_lco_valid = 0; @@ -223,6 +252,7 @@ ao_lco_update(void) query.igniter_status[2], query.igniter_status[3]); #endif + PRINTD("ao_lco_update valid %d\n", ao_lco_valid); ao_wakeup(&ao_pad_query); } @@ -253,8 +283,10 @@ ao_lco_search(void) int8_t r; int8_t try; uint8_t box; + uint8_t boxes = 0; ao_lco_box_reset_present(); + ao_lco_set_pad(-1); for (box = 0; box < AO_PAD_MAX_BOXES; box++) { if ((box % 10) == 0) ao_lco_set_box(box); @@ -263,7 +295,9 @@ ao_lco_search(void) r = ao_lco_query(box, &ao_pad_query, &tick_offset); PRINTD("box %d result %d\n", box, r); if (r == AO_RADIO_CMAC_OK) { + ++boxes; ao_lco_box_set_present(box); + ao_lco_set_pad((boxes % 10) - 1); ao_delay(AO_MS_TO_TICKS(30)); break; } @@ -287,12 +321,12 @@ ao_lco_igniter_status(void) for (;;) { ao_sleep(&ao_pad_query); + PRINTD("RSSI %d VALID %d\n", ao_radio_cmac_rssi, ao_lco_valid); if (!ao_lco_valid) { ao_led_on(AO_LED_RED); ao_led_off(AO_LED_GREEN|AO_LED_AMBER); continue; } - PRINTD("RSSI %d\n", ao_radio_cmac_rssi); if (ao_radio_cmac_rssi < -90) { ao_led_on(AO_LED_AMBER); ao_led_off(AO_LED_RED|AO_LED_GREEN); @@ -361,6 +395,7 @@ ao_lco_monitor(void) if (!ao_lco_valid) ao_lco_update(); ao_lco_arm(ao_lco_box, 1 << ao_lco_pad, ao_lco_tick_offset); + ao_delay(AO_MS_TO_TICKS(30)); ao_lco_update(); } else { ao_lco_update(); -- cgit v1.2.3 From dcbd87bc685924a6587a5f4dae47d34f417601b0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 25 May 2015 16:26:01 -0700 Subject: altos/telelco: Show box voltage with pad knob instead of firing button Turn left past '1' and see the firing box battery voltage instead of pushing the firing button with the box disarmed. This seems like a safer UI. Signed-off-by: Keith Packard --- src/drivers/ao_lco.c | 75 +++++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_lco.c b/src/drivers/ao_lco.c index 9250d444..b8698a80 100644 --- a/src/drivers/ao_lco.c +++ b/src/drivers/ao_lco.c @@ -44,14 +44,13 @@ static uint8_t ao_lco_firing; static uint8_t ao_lco_valid; static uint8_t ao_lco_got_channels; static uint16_t ao_lco_tick_offset; -static uint8_t ao_lco_show_voltage; static struct ao_pad_query ao_pad_query; static void ao_lco_set_pad(uint8_t pad) { - ao_seven_segment_set(AO_LCO_PAD_DIGIT, pad + 1); + ao_seven_segment_set(AO_LCO_PAD_DIGIT, pad); } static void @@ -74,6 +73,17 @@ ao_lco_set_voltage(uint16_t decivolts) ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, tens); } +static void +ao_lco_set_display(void) +{ + if (ao_lco_pad == 0) { + ao_lco_set_voltage(ao_pad_query.battery); + } else { + ao_lco_set_pad(ao_lco_pad); + ao_lco_set_box(ao_lco_box); + } +} + #define MASK_SIZE(n) (((n) + 7) >> 3) #define MASK_ID(n) ((n) >> 3) #define MASK_SHIFT(n) ((n) & 7) @@ -93,9 +103,12 @@ ao_lco_pad_present(uint8_t pad) { if (!ao_lco_got_channels || !ao_pad_query.channels) return pad == 0; - if (pad >= AO_PAD_MAX_CHANNELS) + /* voltage measurement is always valid */ + if (pad == 0) + return 1; + if (pad > AO_PAD_MAX_CHANNELS) return 0; - return (ao_pad_query.channels >> pad) & 1; + return (ao_pad_query.channels >> (pad - 1)) & 1; } static uint8_t @@ -103,7 +116,7 @@ ao_lco_pad_first(void) { uint8_t pad; - for (pad = 0; pad < AO_PAD_MAX_CHANNELS; pad++) + for (pad = 1; pad <= AO_PAD_MAX_CHANNELS; pad++) if (ao_lco_pad_present(pad)) return pad; return 0; @@ -131,15 +144,14 @@ ao_lco_input(void) new_pad += dir; if (new_pad > AO_PAD_MAX_CHANNELS) new_pad = 0; - else if (new_pad < 0) - new_pad = AO_PAD_MAX_CHANNELS - 1; + if (new_pad < 0) + new_pad = AO_PAD_MAX_CHANNELS; if (new_pad == ao_lco_pad) break; } while (!ao_lco_pad_present(new_pad)); if (new_pad != ao_lco_pad) { ao_lco_pad = new_pad; - ao_lco_set_box(ao_lco_box); - ao_lco_set_pad(ao_lco_pad); + ao_lco_set_display(); } } break; @@ -158,9 +170,9 @@ ao_lco_input(void) } while (!ao_lco_box_present(new_box)); if (ao_lco_box != new_box) { ao_lco_box = new_box; + ao_lco_pad = 1; ao_lco_got_channels = 0; - ao_lco_set_box(ao_lco_box); - ao_lco_set_pad(ao_lco_pad); + ao_lco_set_display(); } } break; @@ -176,18 +188,8 @@ ao_lco_input(void) case AO_BUTTON_FIRE: if (ao_lco_armed) { ao_lco_firing = event.value; - ao_lco_show_voltage = 0; PRINTD("Firing %d\n", ao_lco_firing); ao_wakeup(&ao_lco_armed); - } else { - if (event.value) { - if (ao_lco_got_channels) - ao_lco_set_voltage(ao_pad_query.battery); - } else { - ao_lco_set_box(ao_lco_box); - ao_lco_set_pad(ao_lco_pad); - } - ao_lco_show_voltage = event.value; } break; } @@ -235,12 +237,12 @@ ao_lco_update(void) ao_lco_got_channels = 1; ao_lco_valid = 1; if (!c) { - ao_lco_pad = ao_lco_pad_first(); - if (!ao_lco_show_voltage) - ao_lco_set_pad(ao_lco_pad); + if (ao_lco_pad != 0) + ao_lco_pad = ao_lco_pad_first(); + ao_lco_set_display(); } - if (ao_lco_show_voltage) - ao_lco_set_voltage(ao_pad_query.battery); + if (ao_lco_pad == 0) + ao_lco_set_display(); } else ao_lco_valid = 0; @@ -286,7 +288,7 @@ ao_lco_search(void) uint8_t boxes = 0; ao_lco_box_reset_present(); - ao_lco_set_pad(-1); + ao_lco_set_pad(0); for (box = 0; box < AO_PAD_MAX_BOXES; box++) { if ((box % 10) == 0) ao_lco_set_box(box); @@ -297,7 +299,7 @@ ao_lco_search(void) if (r == AO_RADIO_CMAC_OK) { ++boxes; ao_lco_box_set_present(box); - ao_lco_set_pad((boxes % 10) - 1); + ao_lco_set_pad(boxes % 10); ao_delay(AO_MS_TO_TICKS(30)); break; } @@ -309,9 +311,8 @@ ao_lco_search(void) ao_lco_min_box = ao_lco_max_box = ao_lco_box = 0; ao_lco_valid = 0; ao_lco_got_channels = 0; - ao_lco_pad = 0; - ao_lco_set_pad(ao_lco_pad); - ao_lco_set_box(ao_lco_box); + ao_lco_pad = 1; + ao_lco_set_display(); } static void @@ -387,16 +388,18 @@ ao_lco_monitor(void) ao_lco_box, ao_lco_pad, ao_lco_valid); if (!ao_lco_valid) ao_lco_update(); - if (ao_lco_valid) - ao_lco_ignite(ao_lco_box, 1 << ao_lco_pad, ao_lco_tick_offset); + if (ao_lco_valid && ao_lco_pad) + ao_lco_ignite(ao_lco_box, 1 << (ao_lco_pad - 1), ao_lco_tick_offset); } else if (ao_lco_armed) { PRINTD("Arming box %d pad %d\n", ao_lco_box, ao_lco_pad); if (!ao_lco_valid) ao_lco_update(); - ao_lco_arm(ao_lco_box, 1 << ao_lco_pad, ao_lco_tick_offset); - ao_delay(AO_MS_TO_TICKS(30)); - ao_lco_update(); + if (ao_lco_pad) { + ao_lco_arm(ao_lco_box, 1 << (ao_lco_pad - 1), ao_lco_tick_offset); + ao_delay(AO_MS_TO_TICKS(30)); + ao_lco_update(); + } } else { ao_lco_update(); } -- cgit v1.2.3 From ee1b0bd05bedb8a5a631cc79c77fde8fd920ac38 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 25 Jun 2015 18:42:29 -0700 Subject: altos/telebt-v3.0: Report battery voltage correctly There was an extra %d, and an extra ':' in the output, making the UI not parse the voltage correctly Signed-off-by: Keith Packard --- src/telebt-v3.0/ao_pins.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/telebt-v3.0/ao_pins.h b/src/telebt-v3.0/ao_pins.h index 6e90afcc..a6a01662 100644 --- a/src/telebt-v3.0/ao_pins.h +++ b/src/telebt-v3.0/ao_pins.h @@ -130,7 +130,7 @@ struct ao_adc { }; #define AO_ADC_DUMP(p) \ - printf("tick: %5u %5d batt: %5d\n", \ + printf("tick: %5u batt %5d\n", \ (p)->tick, \ (p)->adc.v_batt); -- cgit v1.2.3