diff options
| -rw-r--r-- | src/cc1111/ao_ignite.c | 22 | ||||
| -rw-r--r-- | src/cc1111/ao_launch.c | 209 | ||||
| -rw-r--r-- | src/cc1111/ao_pins.h | 39 | 
3 files changed, 247 insertions, 23 deletions
| diff --git a/src/cc1111/ao_ignite.c b/src/cc1111/ao_ignite.c index 0fd2b4bf..289263ab 100644 --- a/src/cc1111/ao_ignite.c +++ b/src/cc1111/ao_ignite.c @@ -17,28 +17,6 @@  #include "ao.h" -#if IGNITE_ON_P2 -#define AO_IGNITER_DROGUE	P2_3 -#define AO_IGNITER_MAIN		P2_4 -#define AO_IGNITER_DIR		P2DIR -#define AO_IGNITER_DROGUE_BIT	(1 << 3) -#define AO_IGNITER_MAIN_BIT	(1 << 4) -#endif - -#if IGNITE_ON_P0 -#define AO_IGNITER_DROGUE	P0_5 -#define AO_IGNITER_MAIN		P0_4 -#define AO_IGNITER_DIR		P0DIR -#define AO_IGNITER_DROGUE_BIT	(1 << 5) -#define AO_IGNITER_MAIN_BIT	(1 << 4) -#endif - -/* test these values with real igniters */ -#define AO_IGNITER_OPEN		1000 -#define AO_IGNITER_CLOSED	7000 -#define AO_IGNITER_FIRE_TIME	AO_MS_TO_TICKS(50) -#define AO_IGNITER_CHARGE_TIME	AO_MS_TO_TICKS(2000) -  __xdata struct ao_ignition ao_ignition[2];  void diff --git a/src/cc1111/ao_launch.c b/src/cc1111/ao_launch.c new file mode 100644 index 00000000..a593d0b2 --- /dev/null +++ b/src/cc1111/ao_launch.c @@ -0,0 +1,209 @@ +/* + * 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" + +__xdata uint16_t ao_launch_ignite; + +#if 0 +#define PRINTD(...) printf(__VA_ARGS__) +#else +#define PRINTD(...)  +#endif + +static void +ao_launch_run(void) +{ +	for (;;) { +		while (!ao_launch_ignite) +			ao_sleep(&ao_launch_ignite); +		ao_ignition[ao_igniter_drogue].firing = 1; +		ao_ignition[ao_igniter_main].firing = 1; +		AO_IGNITER_DIR |= AO_IGNITER_DROGUE_BIT | AO_IGNITER_MAIN_BIT; +		AO_IGNITER_DROGUE = 1; +		while (ao_launch_ignite) { +			ao_launch_ignite = 0; +			ao_delay(AO_MS_TO_TICKS(500)); +		} +		AO_IGNITER_DROGUE = 0; +		ao_ignition[ao_igniter_drogue].firing = 0; +		ao_ignition[ao_igniter_main].firing = 0; +	} +} + +static void +ao_launch_status(void) +{ +	uint8_t	i; +	for (;;) { +		ao_delay(AO_SEC_TO_TICKS(1)); +		if (ao_igniter_status(ao_igniter_drogue) == ao_igniter_ready) { +			if (ao_igniter_status(ao_igniter_main) == ao_igniter_ready) { +				for (i = 0; i < 5; i++) { +					ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(50)); +					ao_delay(AO_MS_TO_TICKS(100)); +				} +			} else { +				ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); +			} +		} +	} +} + +static __pdata uint8_t	ao_launch_armed; +static __pdata uint16_t	ao_launch_arm_time; + +static void +ao_launch(void) +{ +	static __xdata struct ao_launch_command	command; +	static __xdata struct ao_launch_query	query; +	int16_t	time_difference; + +	ao_led_off(AO_LED_RED); +	ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); +	for (;;) { +		flush(); +		if (ao_radio_cmac_recv(&command, sizeof (command), 0) != AO_RADIO_CMAC_OK) +			continue; +		 +		PRINTD ("tick %d serial %d cmd %d channel %d\n", +			command.tick, command.serial, command.cmd, command.channel); + +		switch (command.cmd) { +		case AO_LAUNCH_QUERY: +			if (command.serial != ao_serial_number) { +				PRINTD ("serial number mismatch\n"); +				break; +			} + +			if (command.channel == 0) { +				query.valid = 1; +				query.arm_status = ao_igniter_status(ao_igniter_drogue); +				query.igniter_status = ao_igniter_status(ao_igniter_main); +			} else { +				query.valid = 0; +			} +			query.tick = ao_time(); +			query.serial = ao_serial_number; +			query.channel = command.channel; +			PRINTD ("query tick %d serial %d channel %d valid %d arm %d igniter %d\n", +				query.tick, query.serial, query.channel, query.valid, query.arm_status, +				query.igniter_status); +			ao_radio_cmac_send(&query, sizeof (query)); +			break; +		case AO_LAUNCH_ARM: +			if (command.serial != ao_serial_number) { +				PRINTD ("serial number mismatch\n"); +				break; +			} + +			if (command.channel != 0) +				break; +			time_difference = command.tick - ao_time(); +			PRINTD ("arm tick %d local tick %d\n", command.tick, ao_time()); +			if (time_difference < 0) +				time_difference = -time_difference; +			if (time_difference > 10) { +				PRINTD ("time difference too large %d\n", time_difference); +				break; +			} +			PRINTD ("armed\n"); +			ao_launch_armed = 1; +			ao_launch_arm_time = ao_time(); +			break; +		case AO_LAUNCH_FIRE: +			if (!ao_launch_armed) { +				PRINTD ("not armed\n"); +				break; +			} +			if ((uint16_t) (ao_time() - ao_launch_arm_time) > AO_SEC_TO_TICKS(20)) { +				PRINTD ("late launch arm_time %d time %d\n", +					ao_launch_arm_time, ao_time()); +				break; +			} +			time_difference = command.tick - ao_time(); +			if (time_difference < 0) +				time_difference = -time_difference; +			if (time_difference > 10) { +				PRINTD ("time different too large %d\n", time_difference); +				break; +			} +			PRINTD ("ignite\n"); +			ao_launch_ignite = 1; +			ao_wakeup(&ao_launch_ignite); +			break; +		} +	} +} + +void +ao_launch_test(void) +{ +	switch (ao_igniter_status(ao_igniter_drogue)) { +	case ao_igniter_ready: +	case ao_igniter_active: +		printf ("Armed: "); +		switch (ao_igniter_status(ao_igniter_main)) { +		default: +			printf("unknown status\n"); +			break; +		case ao_igniter_ready: +			printf("igniter good\n"); +			break; +		case ao_igniter_open: +			printf("igniter bad\n"); +			break; +		} +		break; +	default: +		printf("Disarmed\n"); +	} +} + +void +ao_launch_manual(void) +{ +	ao_cmd_white(); +	if (!ao_match_word("DoIt")) +		return; +	ao_cmd_white(); +	ao_launch_ignite = 1; +	ao_wakeup(&ao_launch_ignite); +} + +static __xdata struct ao_task ao_launch_task; +static __xdata struct ao_task ao_launch_ignite_task; +static __xdata struct ao_task ao_launch_status_task; + +__code struct ao_cmds ao_launch_cmds[] = { +	{ ao_launch_test,	"t\0Test launch continuity" }, +	{ ao_launch_manual,	"i <key>\0Fire igniter. <key> is doit with D&I" }, +	{ 0, NULL } +}; + +void +ao_launch_init(void) +{ +	AO_IGNITER_DROGUE = 0; +	AO_IGNITER_MAIN = 0; +	AO_IGNITER_DIR |= AO_IGNITER_DROGUE_BIT | AO_IGNITER_MAIN_BIT; +	ao_cmd_register(&ao_launch_cmds[0]); +	ao_add_task(&ao_launch_task, ao_launch, "launch listener"); +	ao_add_task(&ao_launch_ignite_task, ao_launch_run, "launch igniter"); +	ao_add_task(&ao_launch_status_task, ao_launch_status, "launch status"); +} diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 819dc7df..91719b54 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -27,6 +27,7 @@  	#define HAS_ADC			1  	#define USE_SERIAL_STDIN	0  	#define HAS_EEPROM		1 +	#define HAS_LOG			1  	#define USE_INTERNAL_FLASH	0  	#define HAS_DBG			1  	#define DBG_ON_P1 		1 @@ -59,6 +60,7 @@  	#define USE_SERIAL_STDIN	0  	#define HAS_ADC			1  	#define HAS_EEPROM		1 +	#define HAS_LOG			1  	#define USE_INTERNAL_FLASH	0  	#define HAS_DBG			1  	#define DBG_ON_P1 		1 @@ -95,6 +97,7 @@  	#define HAS_ADC			0  	#define HAS_DBG			1  	#define HAS_EEPROM		0 +	#define HAS_LOG			0  	#define DBG_ON_P1		1  	#define DBG_ON_P0 		0  	#define IGNITE_ON_P2		0 @@ -120,6 +123,7 @@  	#define USE_SERIAL_STDIN	0  	#define HAS_ADC			1  	#define HAS_EEPROM		1 +	#define HAS_LOG			1  	#define USE_INTERNAL_FLASH	1  	#define HAS_DBG			0  	#define IGNITE_ON_P2		0 @@ -146,6 +150,7 @@  	#define USE_SERIAL_STDIN	0  	#define HAS_ADC			1  	#define HAS_EEPROM		1 +	#define HAS_LOG			1  	#define USE_INTERNAL_FLASH	1  	#define HAS_DBG			0  	#define IGNITE_ON_P2		0 @@ -172,6 +177,7 @@  	#define HAS_ADC			1  	#define HAS_DBG			0  	#define HAS_EEPROM		1 +	#define HAS_LOG			1  	#define USE_INTERNAL_FLASH	0  	#define DBG_ON_P1 		0  	#define DBG_ON_P0 		1 @@ -200,6 +206,7 @@  	#define HAS_ADC			0  	#define HAS_DBG			0  	#define HAS_EEPROM		0 +	#define HAS_LOG			0  	#define DBG_ON_P1		0  	#define DBG_ON_P0 		1  	#define IGNITE_ON_P2		0 @@ -225,6 +232,7 @@  	#define HAS_ADC			0  	#define HAS_DBG			1  	#define HAS_EEPROM		0 +	#define HAS_LOG			0  	#define DBG_ON_P1		0  	#define DBG_ON_P0		1  	#define IGNITE_ON_P2		0 @@ -249,6 +257,7 @@  	#define HAS_ADC			0  	#define HAS_DBG			1  	#define HAS_EEPROM		0 +	#define HAS_LOG			0  	#define HAS_BTM			1  	#define DBG_ON_P1 		0  	#define DBG_ON_P0 		1 @@ -282,6 +291,7 @@  	#define HAS_ADC			0  	#define HAS_DBG			1  	#define HAS_EEPROM		1 +	#define HAS_LOG			1  	#define USE_INTERNAL_FLASH	0  	#define HAS_BTM			1  	#define DBG_ON_P1 		1 @@ -317,7 +327,8 @@  	#define HAS_ADC			1  	#define HAS_DBG			0  	#define HAS_EEPROM		1 -	#define USE_INTERNAL_FLASH	0 +	#define HAS_LOG			0 +	#define USE_INTERNAL_FLASH	1  	#define DBG_ON_P1 		0  	#define DBG_ON_P0 		1  	#define IGNITE_ON_P2		1 @@ -415,6 +426,10 @@  #error Please define HAS_EEPROM  #endif +#ifndef HAS_LOG +#error Please define HAS_LOG +#endif +  #if HAS_EEPROM  #ifndef USE_INTERNAL_FLASH  #error Please define USE_INTERNAL_FLASH @@ -457,4 +472,26 @@  #endif /* HAS_ADC */ +#if IGNITE_ON_P2 +#define AO_IGNITER_DROGUE	P2_3 +#define AO_IGNITER_MAIN		P2_4 +#define AO_IGNITER_DIR		P2DIR +#define AO_IGNITER_DROGUE_BIT	(1 << 3) +#define AO_IGNITER_MAIN_BIT	(1 << 4) +#endif + +#if IGNITE_ON_P0 +#define AO_IGNITER_DROGUE	P0_5 +#define AO_IGNITER_MAIN		P0_4 +#define AO_IGNITER_DIR		P0DIR +#define AO_IGNITER_DROGUE_BIT	(1 << 5) +#define AO_IGNITER_MAIN_BIT	(1 << 4) +#endif + +/* test these values with real igniters */ +#define AO_IGNITER_OPEN		1000 +#define AO_IGNITER_CLOSED	7000 +#define AO_IGNITER_FIRE_TIME	AO_MS_TO_TICKS(50) +#define AO_IGNITER_CHARGE_TIME	AO_MS_TO_TICKS(2000) +  #endif /* _AO_PINS_H_ */ | 
