diff options
| author | Keith Packard <keithp@keithp.com> | 2012-08-26 09:47:05 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2012-08-26 09:47:05 -0700 | 
| commit | 1c9baa88d6cd931c66d453674322908eb267ba4c (patch) | |
| tree | d06823b71d78aa540f6e9df80db4531069e1dc62 /src/drivers/ao_pad.c | |
| parent | ea4db73328e865fd658b573da256ca0004c69c61 (diff) | |
altos: Make 'pad' driver useful with telefire v0.1
This reports correct status bits over the radio and to the LEDs for
all four channels, and also makes the firing test command control all
four relays.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/drivers/ao_pad.c')
| -rw-r--r-- | src/drivers/ao_pad.c | 108 | 
1 files changed, 69 insertions, 39 deletions
| diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c index dfa5f9f5..791c9a47 100644 --- a/src/drivers/ao_pad.c +++ b/src/drivers/ao_pad.c @@ -19,15 +19,16 @@  #include <ao_pad.h>  #include <ao_74hc497.h> -__xdata uint8_t ao_pad_ignite; - -#define ao_pad_igniter_status(c)	AO_PAD_IGNITER_STATUS_UNKNOWN -#define ao_pad_arm_status()		AO_PAD_ARM_STATUS_UNKNOWN +static __xdata uint8_t ao_pad_ignite; +static __xdata struct ao_pad_command	command; +static __xdata struct ao_pad_query	query;  #if 0  #define PRINTD(...) printf(__VA_ARGS__) +#define FLUSHD()    flush()  #else  #define PRINTD(...)  +#define FLUSHD()      #endif  static void @@ -49,12 +50,12 @@ ao_pad_run(void)  }  static void -ao_pad_status(void) +ao_pad_monitor(void)  {  	uint8_t			c;  	uint8_t			sample; -	__pdata uint8_t			prev = 0, cur = 0; -	__pdata uint8_t			beeping = 0; +	__pdata uint8_t		prev = 0, cur = 0; +	__pdata uint8_t		beeping = 0;  	__xdata struct ao_data	*packet;  	sample = ao_data_head; @@ -73,13 +74,45 @@ ao_pad_status(void)  #define VOLTS_TO_PYRO(x) ((int16_t) ((x) * 27.0 / 127.0 / 3.3 * 32767.0))  		cur = 0; -		if (pyro > VOLTS_TO_PYRO(4)) { -			for (c = 0; c < AO_PAD_NUM; c++) { -				int16_t		sense = packet->adc.sense[c]; +		if (pyro > VOLTS_TO_PYRO(4)) +			query.arm_status = AO_PAD_ARM_STATUS_ARMED; +		else if (pyro < VOLTS_TO_PYRO(1)) +			query.arm_status = AO_PAD_ARM_STATUS_DISARMED; +		else +			query.arm_status = AO_PAD_ARM_STATUS_UNKNOWN; + +		for (c = 0; c < AO_PAD_NUM; c++) { +			int16_t		sense = packet->adc.sense[c]; +			uint8_t	status = AO_PAD_IGNITER_STATUS_UNKNOWN; + +			if (query.arm_status == AO_PAD_ARM_STATUS_ARMED) { +				/* +				 *	pyro is run through a divider, so pyro = v_pyro * 27 / 127 ~= v_pyro / 20 +				 *	v_pyro = pyro * 127 / 27 +				 * +				 *		v_pyro \ +				 *	100k		igniter +				 *		output /	 +				 *	100k           \ +				 *		sense   relay +				 *	27k            /  +				 *		gnd ---    +				 * +				 *	If the relay is closed, then sense will be 0 +				 *	If no igniter is present, then sense will be v_pyro * 27k/227k = pyro * 127 / 227 ~= pyro/2 +				 *	If igniter is present, then sense will be v_pyro * 27k/127k ~= v_pyro / 20 = pyro +				 */ -				if (sense >= pyro / 4 * 3) +				if (sense <= pyro / 8) +					status = AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_CLOSED; +				else if (pyro / 8 * 3 <= sense && sense <= pyro / 8 * 5) +					status = AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN; +				else if (pyro / 8 * 7 <= sense) { +					status = AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN;  					cur |= AO_LED_CONTINUITY(c); +				}  			} +			query.igniter_status[c] = status;  		}  		if (cur != prev) {  			ao_led_set_mask(cur, AO_LED_CONTINUITY_MASK); @@ -120,17 +153,14 @@ ao_pad_enable(void)  static void  ao_pad(void)  { -	static __xdata struct ao_pad_command	command; -	static __xdata struct ao_pad_query	query;  	int16_t	time_difference; -	uint8_t	c;  	ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200));  	ao_pad_box = ao_74hc497_read();  	ao_led_set(0);  	ao_led_on(AO_LED_POWER);  	for (;;) { -		flush(); +		FLUSHD();  		while (ao_pad_disabled)  			ao_sleep(&ao_pad_disabled);  		if (ao_radio_cmac_recv(&command, sizeof (command), 0) != AO_RADIO_CMAC_OK) @@ -173,9 +203,6 @@ ao_pad(void)  			query.box = ao_pad_box;  			query.channels = AO_PAD_ALL_PINS;  			query.armed = ao_pad_armed; -			query.arm_status = ao_pad_arm_status(); -			for (c = 0; c < AO_PAD_NUM; c++) -				query.igniter_status[c] = ao_pad_igniter_status(c);  			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); @@ -209,27 +236,30 @@ ao_pad(void)  void  ao_pad_test(void)  { -#if 0 -	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; -		} +	uint8_t	c; + +	printf ("Arm switch: "); +	switch (query.arm_status) { +	case AO_PAD_ARM_STATUS_ARMED: +		printf ("Armed\n"); +		break; +	case AO_PAD_ARM_STATUS_DISARMED: +		printf ("Disarmed\n"); +		break; +	case AO_PAD_ARM_STATUS_UNKNOWN: +		printf ("Unknown\n");  		break; -	default: -		printf("Disarmed\n");  	} -#endif + +	for (c = 0; c < AO_PAD_NUM; c++) { +		printf ("Pad %d: "); +		switch (query.igniter_status[c]) { +		case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_CLOSED:	printf ("No igniter. Relay closed\n"); break; +		case AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN:	printf ("No igniter. Relay open\n"); break; +		case AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN:	printf ("Good igniter. Relay open\n"); break; +		case AO_PAD_IGNITER_STATUS_UNKNOWN:			printf ("Unknown\n"); break; +		} +	}  }  void @@ -247,7 +277,7 @@ ao_pad_manual(void)  static __xdata struct ao_task ao_pad_task;  static __xdata struct ao_task ao_pad_ignite_task; -static __xdata struct ao_task ao_pad_status_task; +static __xdata struct ao_task ao_pad_monitor_task;  __code struct ao_cmds ao_pad_cmds[] = {  	{ ao_pad_test,	"t\0Test pad continuity" }, @@ -273,5 +303,5 @@ ao_pad_init(void)  	ao_cmd_register(&ao_pad_cmds[0]);  	ao_add_task(&ao_pad_task, ao_pad, "pad listener");  	ao_add_task(&ao_pad_ignite_task, ao_pad_run, "pad igniter"); -	ao_add_task(&ao_pad_status_task, ao_pad_status, "pad status"); +	ao_add_task(&ao_pad_monitor_task, ao_pad_monitor, "pad monitor");  } | 
