diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.proto | 6 | ||||
| -rw-r--r-- | src/ao.h | 72 | ||||
| -rw-r--r-- | src/ao_companion.c | 96 | ||||
| -rw-r--r-- | src/ao_ee.c | 14 | ||||
| -rw-r--r-- | src/ao_flash.c | 14 | ||||
| -rw-r--r-- | src/ao_m25.c | 4 | ||||
| -rw-r--r-- | src/ao_pins.h | 16 | ||||
| -rw-r--r-- | src/ao_spi.c | 8 | ||||
| -rw-r--r-- | src/ao_telemetrum.c | 3 | ||||
| -rw-r--r-- | src/ao_telemetry.c | 45 | ||||
| -rw-r--r-- | src/telemetrum-v1.0/Makefile.defs | 1 | ||||
| -rw-r--r-- | src/telemetrum-v1.1/Makefile.defs | 1 | 
12 files changed, 248 insertions, 32 deletions
diff --git a/src/Makefile.proto b/src/Makefile.proto index d4a8c4ea..8f98d354 100644 --- a/src/Makefile.proto +++ b/src/Makefile.proto @@ -151,6 +151,12 @@ BTM_DRIVER_SRC = \  	ao_btm.c  # +# Companion port driver source +# +COMPANION_SRC = \ +	ao_companion.c + +#  # Tasks run on TeleMetrum  #  TM_TASK_SRC = \ @@ -965,6 +965,34 @@ ao_serial_init(void);   * ao_spi.c   */ +extern __xdata uint8_t	ao_spi_mutex; + +#define ao_spi_get_mask(reg,mask) do {\ +	ao_mutex_get(&ao_spi_mutex); \ +	(reg) &= ~(mask); \ +	} while (0) + +#define ao_spi_put_mask(reg,mask) do { \ +	(reg) |= (mask); \ +	ao_mutex_put(&ao_spi_mutex); \ +	} while (0) + +#define ao_spi_get_bit(bit) do {\ +	ao_mutex_get(&ao_spi_mutex); \ +	(bit) = 0; \ +	} while (0) + +#define ao_spi_put_bit(bit) do { \ +	(bit) = 1; \ +	ao_mutex_put(&ao_spi_mutex); \ +	} while (0) + +/* + * The SPI mutex must be held to call either of these + * functions -- this mutex covers the entire SPI operation, + * from chip select low to chip select high + */ +  void  ao_spi_send(void __xdata *block, uint16_t len) __reentrant; @@ -1089,12 +1117,29 @@ struct ao_telemetry_satellite {  	/* 32 */  }; +#define AO_TELEMETRY_COMPANION		0x07 + +#define AO_COMPANION_MAX_CHANNELS	12 + +struct ao_telemetry_companion { +	uint16_t				serial;		/*  0 */ +	uint16_t				tick;		/*  2 */ +	uint8_t					type;		/*  4 */ +	uint8_t					board_id;	/*  5 */ + +	uint8_t					update_period;	/*  6 */ +	uint8_t					channels;	/*  7 */ +	uint16_t				companion_data[AO_COMPANION_MAX_CHANNELS];	/*  8 */ +	/* 32 */ +}; +	  union ao_telemetry_all {  	struct ao_telemetry_generic		generic;  	struct ao_telemetry_sensor		sensor;  	struct ao_telemetry_configuration	configuration;  	struct ao_telemetry_location		location;  	struct ao_telemetry_satellite		satellite; +	struct ao_telemetry_companion		companion;  };  /* @@ -1529,8 +1574,33 @@ ao_btm_isr(void)  #endif  	; -  void  ao_btm_init(void); +/* ao_companion.c */ + +#define AO_COMPANION_SETUP		1 +#define AO_COMPANION_FETCH		2 + +struct ao_companion_command { +	uint8_t		command; +	uint8_t		flight_state; +	uint16_t	tick; +}; + +struct ao_companion_setup { +	uint16_t	board_id; +	uint16_t	board_id_inverse; +	uint8_t		update_period; +	uint8_t		channels; +}; + +extern __pdata uint8_t				ao_companion_running; +extern __xdata struct ao_companion_setup	ao_companion_setup; +extern __xdata uint8_t				ao_companion_mutex; +extern __xdata uint16_t				ao_companion_data[AO_COMPANION_MAX_CHANNELS]; + +void +ao_companion_init(void); +  #endif /* _AO_H_ */ diff --git a/src/ao_companion.c b/src/ao_companion.c new file mode 100644 index 00000000..8db3273e --- /dev/null +++ b/src/ao_companion.c @@ -0,0 +1,96 @@ +/* + * 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" + +#define COMPANION_SELECT()	ao_spi_get_bit(COMPANION_CS) +#define COMPANION_DESELECT()	ao_spi_put_bit(COMPANION_CS) + +static __xdata struct ao_companion_command	ao_companion_command; +__xdata struct ao_companion_setup		ao_companion_setup; + +__xdata uint16_t	ao_companion_data[AO_COMPANION_MAX_CHANNELS]; +__pdata uint8_t		ao_companion_running; +__xdata uint8_t		ao_companion_mutex; + +static void +ao_companion_send_command(uint8_t command) +{ +	ao_companion_command.command = command; +	ao_companion_command.flight_state = ao_flight_state; +	ao_companion_command.tick = ao_time(); +	ao_spi_send(&ao_companion_command, sizeof (ao_companion_command)); +} + +static uint8_t +ao_companion_get_setup(void) +{ +	COMPANION_SELECT(); +	ao_companion_send_command(AO_COMPANION_SETUP); +	ao_spi_recv(&ao_companion_setup, sizeof (ao_companion_setup)); +	COMPANION_DESELECT(); +	if (ao_companion_setup.board_id != ~ao_companion_setup.board_id) +		return 0; +	return 1; +} + +static void +ao_companion_get_data(void) +{ +	COMPANION_SELECT(); +	ao_companion_send_command(AO_COMPANION_FETCH); +	ao_mutex_get(&ao_companion_mutex); +	ao_spi_recv(&ao_companion_data, ao_companion_setup.channels * 2); +	ao_mutex_put(&ao_companion_mutex); +	COMPANION_DESELECT(); +} + +void +ao_companion(void) +{ +	if (!ao_companion_get_setup()) +		ao_exit(); +	ao_companion_running = 1; +	for (;;) { +		ao_delay(ao_companion_setup.update_period); +		ao_companion_get_data(); +	} +} + +void +ao_companion_status(void) __reentrant +{ +} + +__code struct ao_cmds ao_companion_cmds[] = { +	{ ao_companion_status,	"L\0Companion link status" }, +	{ 0, NULL }, +}; + +static __xdata struct ao_task ao_companion_task; + +void +ao_companion_init(void) +{ +	COMPANION_CS_PORT |= COMPANION_CS_MASK;	/* raise all CS pins */ +	COMPANION_CS_DIR |= COMPANION_CS_MASK;	/* set CS pins as outputs */ +	COMPANION_CS_SEL &= ~COMPANION_CS_MASK;	/* set CS pins as GPIO */ + +	ao_cmd_register(&ao_companion_cmds[0]); + +	ao_add_task(&ao_companion_task, ao_companion, "companion"); +} diff --git a/src/ao_ee.c b/src/ao_ee.c index 83863af5..a2fe8dc1 100644 --- a/src/ao_ee.c +++ b/src/ao_ee.c @@ -49,19 +49,9 @@ static __xdata uint8_t ao_ee_mutex;  	_asm nop _endasm; \  } while(0) -static void ao_ee_cs_low(void) -{ -	ao_ee_delay(); -	EE_CS = 0; -	ao_ee_delay(); -} +#define ao_ee_cs_low()	ao_spi_get_bit(EE_CS) -static void ao_ee_cs_high(void) -{ -	ao_ee_delay(); -	EE_CS = 1; -	ao_ee_delay(); -} +#define ao_ee_cs_high()	ao_spi_put_bit(EE_CS)  struct ao_ee_instruction {  	uint8_t	instruction; diff --git a/src/ao_flash.c b/src/ao_flash.c index 00e96398..bb40f6f7 100644 --- a/src/ao_flash.c +++ b/src/ao_flash.c @@ -43,19 +43,9 @@ __xdata uint8_t ao_flash_mutex;  	_asm nop _endasm; \  } while(0) -void ao_flash_cs_low(void) -{ -	ao_flash_delay(); -	FLASH_CS = 0; -	ao_flash_delay(); -} +#define ao_flash_cs_low()	ao_spi_get_bit(FLASH_CS) -void ao_flash_cs_high(void) -{ -	ao_flash_delay(); -	FLASH_CS = 1; -	ao_flash_delay(); -} +#define ao_flash_cs_high()	ao_spi_put_bit(FLASH_CS)  struct ao_flash_instruction {  	uint8_t	instruction; diff --git a/src/ao_m25.c b/src/ao_m25.c index 208c69ba..d7208273 100644 --- a/src/ao_m25.c +++ b/src/ao_m25.c @@ -99,8 +99,8 @@ static __xdata uint8_t ao_m25_mutex;  static __xdata uint8_t	ao_m25_instruction[4]; -#define M25_SELECT(cs)			(SPI_CS_PORT &= ~(cs)) -#define M25_DESELECT(cs)		(SPI_CS_PORT |= (cs)) +#define M25_SELECT(cs)		ao_spi_get_mask(SPI_CS_PORT,cs) +#define M25_DESELECT(cs)	ao_spi_put_mask(SPI_CS_PORT,cs)  #define M25_BLOCK_SHIFT			16  #define M25_BLOCK			65536L diff --git a/src/ao_pins.h b/src/ao_pins.h index 89907b9c..e1f5459f 100644 --- a/src/ao_pins.h +++ b/src/ao_pins.h @@ -36,6 +36,11 @@  	#define PACKET_HAS_MASTER	0  	#define PACKET_HAS_SLAVE	1 +	#define HAS_COMPANION		1 +	#define COMPANION_CS_ON_P1	1 +	#define COMPANION_CS_MASK	0x4	/* CS1 is P1_2 */ +	#define COMPANION_CS		P1_2 +  	#define AO_LED_RED		1  	#define LEDS_AVAILABLE		(AO_LED_RED)  	#define HAS_EXTERNAL_TEMP	0 @@ -63,6 +68,11 @@  	#define PACKET_HAS_MASTER	0  	#define PACKET_HAS_SLAVE	1 +	#define HAS_COMPANION		1 +	#define COMPANION_CS_ON_P1	1 +	#define COMPANION_CS_MASK	0x4	/* CS1 is P1_2 */ +	#define COMPANION_CS		P1_2 +  	#define AO_LED_RED		1  	#define LEDS_AVAILABLE		(AO_LED_RED)  	#define HAS_EXTERNAL_TEMP	0 @@ -328,6 +338,12 @@  #endif /* DBG_ON_P0 */ +#if COMPANION_CS_ON_P1 +	#define COMPANION_CS_PORT	P1 +	#define COMPANION_CS_SEL	P1SEL +	#define COMPANION_CS_DIR	P1DIR +#endif +  #if SPI_CS_ON_P1  	#define SPI_CS_PORT	P1  	#define SPI_CS_SEL	P1SEL diff --git a/src/ao_spi.c b/src/ao_spi.c index bd52a0d4..fbe613c7 100644 --- a/src/ao_spi.c +++ b/src/ao_spi.c @@ -17,6 +17,10 @@  #include "ao.h" +/* Shared mutex to protect SPI bus, must cover the entire + * operation, from CS low to CS high. This means that any SPI + * user must protect the SPI bus with this mutex + */  __xdata uint8_t	ao_spi_mutex;  __xdata uint8_t ao_spi_dma_in_done;  __xdata uint8_t ao_spi_dma_out_done; @@ -36,7 +40,6 @@ static __xdata uint8_t ao_spi_const = 0xff;  void  ao_spi_send(void __xdata *block, uint16_t len) __reentrant  { -	ao_mutex_get(&ao_spi_mutex);  	ao_dma_set_transfer(ao_spi_dma_in_id,  			    &U0DBUFXADDR,  			    &ao_spi_const, @@ -64,7 +67,6 @@ ao_spi_send(void __xdata *block, uint16_t len) __reentrant  	ao_dma_trigger(ao_spi_dma_out_id);  	__critical while (!ao_spi_dma_in_done)  		ao_sleep(&ao_spi_dma_in_done); -	ao_mutex_put(&ao_spi_mutex);  }  /* Receive bytes over SPI. @@ -76,7 +78,6 @@ ao_spi_send(void __xdata *block, uint16_t len) __reentrant  void  ao_spi_recv(void __xdata *block, uint16_t len) __reentrant  { -	ao_mutex_get(&ao_spi_mutex);  	ao_dma_set_transfer(ao_spi_dma_in_id,  			    &U0DBUFXADDR,  			    block, @@ -104,7 +105,6 @@ ao_spi_recv(void __xdata *block, uint16_t len) __reentrant  	ao_dma_trigger(ao_spi_dma_out_id);  	__critical while (!ao_spi_dma_in_done)  		ao_sleep(&ao_spi_dma_in_done); -	ao_mutex_put(&ao_spi_mutex);  }  /* diff --git a/src/ao_telemetrum.c b/src/ao_telemetrum.c index 6fa70b3a..f560740a 100644 --- a/src/ao_telemetrum.c +++ b/src/ao_telemetrum.c @@ -62,6 +62,9 @@ main(void)  #if HAS_DBG  	ao_dbg_init();  #endif +#if HAS_COMPANION +	ao_companion_init(); +#endif  	ao_config_init();  	ao_start_scheduler();  } diff --git a/src/ao_telemetry.c b/src/ao_telemetry.c index 52f818ed..15ba4302 100644 --- a/src/ao_telemetry.c +++ b/src/ao_telemetry.c @@ -25,6 +25,10 @@ static __pdata int8_t ao_telemetry_config_cur;  static __pdata int8_t ao_telemetry_loc_cur;  static __pdata int8_t ao_telemetry_sat_cur;  #endif +#if HAS_COMPANION +static __pdata int8_t ao_telemetry_companion_max; +static __pdata int8_t ao_telemetry_companion_cur; +#endif  static __pdata uint8_t ao_rdf = 0;  static __pdata uint16_t ao_rdf_time; @@ -149,6 +153,26 @@ ao_send_satellite(void)  }  #endif +#if HAS_COMPANION +static void +ao_send_companion(void) +{ +	if (--ao_telemetry_companion_cur <= 0) { +		telemetry.generic.type = AO_TELEMETRY_COMPANION; +		telemetry.companion.board_id = ao_companion_setup.board_id; +		telemetry.companion.update_period = ao_companion_setup.update_period; +		telemetry.companion.channels = ao_companion_setup.channels; +		ao_mutex_get(&ao_companion_mutex); +		memcpy(&telemetry.companion.companion_data, +		       ao_companion_data, +		       ao_companion_setup.channels * 2); +		ao_mutex_put(&ao_companion_mutex); +		ao_radio_send(&telemetry, sizeof (telemetry)); +		ao_telemetry_companion_cur = ao_telemetry_companion_max; +	} +} +#endif +  void  ao_telemetry(void)  { @@ -168,6 +192,10 @@ ao_telemetry(void)  			ao_send_sensor(); +#if HAS_COMPANION +			if (ao_companion_running) +				ao_send_companion(); +#endif  			ao_send_configuration();  #if HAS_GPS  			ao_send_location(); @@ -193,10 +221,25 @@ void  ao_telemetry_set_interval(uint16_t interval)  {  	ao_telemetry_interval = interval; + +#if HAS_COMPANION +	if (!ao_companion_setup.update_period) +		ao_companion_setup.update_period = AO_SEC_TO_TICKS(1); +	ao_telemetry_companion_max = ao_companion_setup.update_period / interval; +	ao_telemetry_companion_cur = 1; +#endif +  	ao_telemetry_config_max = AO_SEC_TO_TICKS(1) / interval; +#if HAS_COMPANION +	ao_telemetry_config_cur = ao_telemetry_companion_cur; +	if (ao_telemetry_config_max > ao_telemetry_config_cur) +		ao_telemetry_config_cur++; +#else  	ao_telemetry_config_cur = 1; +#endif +  #if HAS_GPS -	ao_telemetry_loc_cur = 1; +	ao_telemetry_loc_cur = ao_telemetry_config_cur;  	if (ao_telemetry_config_max > ao_telemetry_loc_cur)  		ao_telemetry_loc_cur++;  	ao_telemetry_sat_cur = ao_telemetry_loc_cur; diff --git a/src/telemetrum-v1.0/Makefile.defs b/src/telemetrum-v1.0/Makefile.defs index a60a501a..5eefc392 100644 --- a/src/telemetrum-v1.0/Makefile.defs +++ b/src/telemetrum-v1.0/Makefile.defs @@ -5,6 +5,7 @@ SRC = \  	$(SPI_DRIVER_SRC) \  	$(FLASH_DRIVER_SRC) \  	$(SKY_DRIVER_SRC) \ +	$(COMPANION_SRC) \  	$(DBG_SRC)  PRODUCT=TeleMetrum-v1.0 diff --git a/src/telemetrum-v1.1/Makefile.defs b/src/telemetrum-v1.1/Makefile.defs index f38226c6..3c8b8793 100644 --- a/src/telemetrum-v1.1/Makefile.defs +++ b/src/telemetrum-v1.1/Makefile.defs @@ -5,6 +5,7 @@ SRC = \  	$(SPI_DRIVER_SRC) \  	$(M25_DRIVER_SRC) \  	$(SKY_DRIVER_SRC) \ +	$(COMPANION_SRC) \  	$(DBG_SRC)  PRODUCT=TeleMetrum-v1.1  | 
