diff options
Diffstat (limited to 'src')
66 files changed, 1602 insertions, 326 deletions
| diff --git a/src/Makefile b/src/Makefile index 05e99c7f..dc74bf8c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,13 +34,15 @@ 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 \  	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 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/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-* diff --git a/src/chaoskey-v0.1/Makefile b/src/chaoskey-v0.1/Makefile new file mode 100644 index 00000000..ac4a6788 --- /dev/null +++ b/src/chaoskey-v0.1/Makefile @@ -0,0 +1,70 @@ +# +# 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 +IDVENDOR=0x1d50 +IDPRODUCT=0x60c6 + +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 -V $(IDVENDOR) -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) -o $@ + +$(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 <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <ao.h> +#include <ao_adc_fast.h> +#include <ao_crc.h> +#include <ao_trng_send.h> + +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 <keithp@keithp.com> + * + * 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_ */ diff --git a/src/chaoskey-v0.1/flash-loader/.gitignore b/src/chaoskey-v0.1/flash-loader/.gitignore new file mode 100644 index 00000000..a60a4945 --- /dev/null +++ b/src/chaoskey-v0.1/flash-loader/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +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 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 <keithp@keithp.com> + * + * 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 <ao_flash_stm_pins.h> + +/* 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_aprs.c b/src/drivers/ao_aprs.c index 19beb78f..a8016673 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,99 @@ static int tncPositionPacket(void)      }      buf = tncBuffer; -    *buf++ = '!'; -    /* Symbol table ID */ -    *buf++ = '/'; +#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: +    { +	    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); -    lat = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000; -    lon = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000; +	    tncCompressInt(buf, lat, 4); +	    buf += 4; +	    tncCompressInt(buf, lon, 4); +	    buf += 4; -    alt = ao_aprs_encode_altitude(altitude); +	    /* Symbol code */ +	    *buf++ = '\''; -    tncCompressInt(buf, lat, 4); -    buf += 4; -    tncCompressInt(buf, lon, 4); -    buf += 4; +	    tncCompressInt(buf, alt, 2); +	    buf += 2; -    /* Symbol code */ -    *buf++ = '\''; +	    *buf++ = 33 + ((1 << 5) | (2 << 3)); -    tncCompressInt(buf, alt, 2); -    buf += 2; +	    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; +	    } -    *buf++ = 33 + ((1 << 5) | (2 << 3)); +	    if (lon < 0) { +		    lon_sign = 'W'; +		    lon = -lon; +	    } + +	    /* 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/drivers/ao_btm.c b/src/drivers/ao_btm.c index e6b28688..8e7052cb 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; @@ -265,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();  } @@ -352,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  	 */ @@ -382,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); @@ -390,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); 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..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)) @@ -715,17 +727,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_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_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/telelco-v0.2/ao_lco.c b/src/drivers/ao_lco.c index 4b5f7a9b..b8698a80 100644 --- a/src/telelco-v0.2/ao_lco.c +++ b/src/drivers/ao_lco.c @@ -50,7 +50,7 @@ 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 @@ -60,6 +60,30 @@ 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); +} + +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) @@ -79,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 @@ -89,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; @@ -117,14 +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_pad(ao_lco_pad); +						ao_lco_set_display();  					}  				}  				break; @@ -143,8 +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_display();  					}  				}  				break; @@ -209,9 +237,12 @@ ao_lco_update(void)  		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); +			if (ao_lco_pad != 0) +				ao_lco_pad = ao_lco_pad_first(); +			ao_lco_set_display();  		} +		if (ao_lco_pad == 0) +			ao_lco_set_display();  	} else  		ao_lco_valid = 0; @@ -223,6 +254,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 +285,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(0);  	for (box = 0; box < AO_PAD_MAX_BOXES; box++) {  		if ((box % 10) == 0)  			ao_lco_set_box(box); @@ -263,7 +297,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);  				ao_delay(AO_MS_TO_TICKS(30));  				break;  			} @@ -275,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 @@ -287,12 +322,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); @@ -353,15 +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_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();  		} @@ -369,9 +407,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.h b/src/drivers/ao_lco.h index 253f9702..253f9702 100644 --- a/src/telelco-v0.2/ao_lco.h +++ b/src/drivers/ao_lco.h 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/drivers/ao_pad.c b/src/drivers/ao_pad.c index dc2c83fe..ffe46c68 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 @@ -123,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; @@ -138,7 +144,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 +261,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", 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 */  }; diff --git a/src/drivers/ao_trng.c b/src/drivers/ao_trng.c new file mode 100644 index 00000000..e69cd30b --- /dev/null +++ b/src/drivers/ao_trng.c @@ -0,0 +1,79 @@ +/* + * Copyright © 2015 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <ao.h> +#include <ao_adc_fast.h> +#include <ao_crc.h> +#include <ao_trng.h> + +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; +	uint16_t	t; +	uint32_t	*rnd = (uint32_t *) ao_adc_ring; + +	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--) { +		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[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); +		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 <kbytes>\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 <keithp@keithp.com> + * + * 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/drivers/ao_trng_send.c b/src/drivers/ao_trng_send.c new file mode 100644 index 00000000..bac6035c --- /dev/null +++ b/src/drivers/ao_trng_send.c @@ -0,0 +1,65 @@ +/* + * Copyright © 2015 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <ao.h> +#include <ao_adc_fast.h> +#include <ao_crc.h> +#include <ao_trng_send.h> + +static void +ao_trng_send(void) +{ +	static uint16_t	*buffer[2]; +	int		usb_buf_id; +	uint16_t	i; +	uint16_t	*buf; +	uint16_t	t; +	uint32_t	*rnd = (uint32_t *) ao_adc_ring; + +	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); +		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[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); +		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 <keithp@keithp.com> + * + * 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_ */ 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 @@ -220,6 +220,10 @@ _ao_config_get(void)  		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 <ssid>\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 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_product.c b/src/kernel/ao_product.c index b9327bac..c711a4d2 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 [] = @@ -45,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 */ @@ -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 */ 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_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;  } - 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..55e423bb 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -450,37 +450,39 @@ ao_wakeup(__xdata void *wchan) __reentrant  	ao_check_stack();  } -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 -} - -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 +	} +	return ret;  }  static __xdata uint8_t ao_forever; @@ -488,9 +490,7 @@ 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/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; 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" 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" 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/stmf0/ao_adc_fast.c b/src/stmf0/ao_adc_fast.c index be9b5986..26e6691c 100644 --- a/src/stmf0/ao_adc_fast.c +++ b/src/stmf0/ao_adc_fast.c @@ -18,43 +18,53 @@  #include <ao.h>  #include <ao_adc_fast.h> -uint16_t ao_adc_ring[AO_ADC_RING_SIZE]; +uint16_t ao_adc_ring[AO_ADC_RING_SIZE] __attribute__((aligned(4))); -uint16_t ao_adc_ring_head, ao_adc_ring_tail; -uint8_t ao_adc_running; +/* 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_remain; +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; +	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;  	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 +150,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 +169,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 +197,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..c6903e9f 100644 --- a/src/stmf0/ao_adc_fast.h +++ b/src/stmf0/ao_adc_fast.h @@ -26,62 +26,59 @@ 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; - -void -_ao_adc_start(void); +extern uint16_t	ao_adc_ring_head, ao_adc_ring_remain; +extern uint16_t	ao_adc_running; +/* + * 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) -		return AO_ADC_RING_SIZE; -	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; -	if (!ao_adc_running && _ao_adc_space() >= AO_ADC_RING_CHUNK) +	ao_adc_ring_remain -= n; +	if (!ao_adc_running)  		_ao_adc_start();  	ao_arch_release_interrupts();  } diff --git a/src/stmf0/ao_crc_stm.c b/src/stmf0/ao_crc_stm.c new file mode 100644 index 00000000..863f5ef5 --- /dev/null +++ b/src/stmf0/ao_crc_stm.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2015 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <ao.h> +#include <ao_crc.h> + +#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(); +} 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 <keithp@keithp.com> + * + * 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_ */ 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 diff --git a/src/telebt-v3.0/ao_pins.h b/src/telebt-v3.0/ao_pins.h index 838f0dfc..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); @@ -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.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 <keithp@keithp.com> + * + * 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 <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <ao.h> +#include <ao_exti.h> +#include <ao_packet.h> +#include <ao_companion.h> +#include <ao_profile.h> +#include <ao_pyro.h> +#include <ao_aes.h> +#include <ao_seven_segment.h> +#include <ao_quadrature.h> +#include <ao_button.h> +#include <ao_lco.h> +#include <ao_lco_cmd.h> +#include <ao_radio_cmac_cmd.h> +#include <ao_eeprom.h> + +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 <keithp@keithp.com> + * + * 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 <ao_flash_stm_pins.h> + +/* 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_ */ 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]); 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 <ao.h>  #include <ao_adc_fast.h>  #include <ao_crc.h> - -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 <kbytes>\0Fetch a block of numbers" }, -	{ 0, NULL }, -}; +#include <ao_trng.h>  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(); 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 = { @@ -66,6 +70,12 @@ argdesc argd = {  			.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',  			.name = "id_product", @@ -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");  } | 
