diff options
Diffstat (limited to 'src/kernel')
| -rw-r--r-- | src/kernel/ao.h | 12 | ||||
| -rw-r--r-- | src/kernel/ao_config.c | 48 | ||||
| -rw-r--r-- | src/kernel/ao_config.h | 6 | ||||
| -rw-r--r-- | src/kernel/ao_data.h | 4 | ||||
| -rw-r--r-- | src/kernel/ao_fast_timer.h | 34 | ||||
| -rw-r--r-- | src/kernel/ao_flight.c | 2 | ||||
| -rw-r--r-- | src/kernel/ao_log.h | 1 | ||||
| -rw-r--r-- | src/kernel/ao_log_mini.c | 2 | ||||
| -rw-r--r-- | src/kernel/ao_panic.c | 11 | ||||
| -rw-r--r-- | src/kernel/ao_power.c | 80 | ||||
| -rw-r--r-- | src/kernel/ao_power.h | 53 | ||||
| -rw-r--r-- | src/kernel/ao_product.c | 67 | ||||
| -rw-r--r-- | src/kernel/ao_task.c | 4 | ||||
| -rw-r--r-- | src/kernel/ao_task.h | 4 | ||||
| -rw-r--r-- | src/kernel/ao_usb.h | 17 | 
15 files changed, 325 insertions, 20 deletions
diff --git a/src/kernel/ao.h b/src/kernel/ao.h index 59a469ae..6ed0299e 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -124,6 +124,16 @@ ao_timer_init(void);  void  ao_clock_init(void); +#if AO_POWER_MANAGEMENT +/* Go to low power clock */ +void +ao_clock_suspend(void); + +/* Restart full-speed clock */ +void +ao_clock_resume(void); +#endif +  /*   * ao_mutex.c   */ @@ -810,6 +820,8 @@ struct ao_fifo {  } while(0)  #define ao_fifo_full(f)		((((f).insert + 1) & (AO_FIFO_SIZE-1)) == (f).remove) +#define ao_fifo_mostly(f)	((((f).insert - (f).remove) & (AO_FIFO_SIZE-1)) >= (AO_FIFO_SIZE * 3 / 4)) +#define ao_fifo_barely(f)	((((f).insert - (f).remove) & (AO_FIFO_SIZE-1)) >= (AO_FIFO_SIZE * 1 / 4))  #define ao_fifo_empty(f)	((f).insert == (f).remove)  #if PACKET_HAS_MASTER || PACKET_HAS_SLAVE diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index b0d3e541..f95ca893 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -224,6 +224,12 @@ _ao_config_get(void)  		if (minor < 22)  			ao_config.aprs_format = AO_CONFIG_DEFAULT_APRS_FORMAT;  #endif +#if HAS_FIXED_PAD_BOX +		if (minor < 22) +			ao_config.pad_box = 1; +		if (minor < 23) +			ao_config.pad_idle = 120; +#endif  		ao_config.minor = AO_CONFIG_MINOR;  		ao_config_dirty = 1;  	} @@ -899,6 +905,42 @@ ao_config_aprs_format_show(void)  }  #endif /* HAS_APRS */ +#if HAS_FIXED_PAD_BOX +void +ao_config_pad_box_show(void) +{ +	printf ("Pad box: %d\n", ao_config.pad_box); +} + +void +ao_config_pad_box_set(void) +{ +	ao_cmd_decimal(); +	if (ao_cmd_status != ao_cmd_success) +		return; +	_ao_config_edit_start(); +	ao_config.pad_box = ao_cmd_lex_i; +	_ao_config_edit_finish(); +} + +void +ao_config_pad_idle_show(void) +{ +	printf ("Idle timeout: %d\n", ao_config.pad_idle); +} + +void +ao_config_pad_idle_set(void) +{ +	ao_cmd_decimal(); +	if (ao_cmd_status != ao_cmd_success) +		return; +	_ao_config_edit_start(); +	ao_config.pad_idle = ao_cmd_lex_i; +	_ao_config_edit_finish(); +} +#endif +  struct ao_config_var {  	__code char	*str;  	void		(*set)(void) __reentrant; @@ -993,6 +1035,12 @@ __code struct ao_config_var ao_config_vars[] = {  	{ "C <0 compressed, 1 uncompressed>\0APRS format",  	  ao_config_aprs_format_set, ao_config_aprs_format_show },  #endif +#if HAS_FIXED_PAD_BOX +	{ "B <box>\0Set pad box (1-99)", +	  ao_config_pad_box_set, ao_config_pad_box_show }, +	{ "i <seconds>\0Set idle timeout (0 disable)", +	  ao_config_pad_idle_set, ao_config_pad_idle_show }, +#endif  	{ "s\0Show",  	  ao_config_show,		0 },  #if HAS_EEPROM diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h index cfe8555c..3c73ea49 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	22 +#define AO_CONFIG_MINOR	23  #define AO_AES_LEN 16 @@ -118,6 +118,10 @@ struct ao_config {  #if HAS_APRS  	uint8_t		aprs_format;		/* minor version 22 */  #endif +#if HAS_FIXED_PAD_BOX +	uint8_t		pad_box;		/* minor version 22 */ +	uint8_t		pad_idle;		/* minor version 23 */ +#endif  };  #define AO_APRS_FORMAT_COMPRESSED	0 diff --git a/src/kernel/ao_data.h b/src/kernel/ao_data.h index 8f75ad87..6ee0965d 100644 --- a/src/kernel/ao_data.h +++ b/src/kernel/ao_data.h @@ -269,6 +269,10 @@ typedef int16_t accel_t;  #define AO_ACCEL_INVERT		4095 +#ifndef AO_MMA655X_INVERT +#error AO_MMA655X_INVERT not defined +#endif +  #define ao_data_accel(packet)			((packet)->mma655x)  #if AO_MMA655X_INVERT  #define ao_data_accel_cook(packet)		(AO_ACCEL_INVERT - (packet)->mma655x) diff --git a/src/kernel/ao_fast_timer.h b/src/kernel/ao_fast_timer.h new file mode 100644 index 00000000..90fb3930 --- /dev/null +++ b/src/kernel/ao_fast_timer.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_FAST_TIMER_H_ +#define _AO_FAST_TIMER_H_ + +void +ao_fast_timer_init(void); + +#ifndef AO_FAST_TIMER_MAX +#define AO_FAST_TIMER_MAX	2 +#endif + +void +ao_fast_timer_on(void (*callback)(void)); + +void +ao_fast_timer_off(void (*callback)(void)); + +#endif /* _AO_FAST_TIMER_H_ */ diff --git a/src/kernel/ao_flight.c b/src/kernel/ao_flight.c index 251dbc02..9ba02bb8 100644 --- a/src/kernel/ao_flight.c +++ b/src/kernel/ao_flight.c @@ -370,8 +370,10 @@ ao_flight(void)  				{  					ao_flight_state = ao_flight_landed; +#if HAS_ADC  					/* turn off the ADC capture */  					ao_timer_set_adc_interval(0); +#endif  					ao_wakeup(DATA_TO_XDATA(&ao_flight_state));  				} diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h index f86fb359..fdd428c2 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -49,6 +49,7 @@ extern __pdata enum ao_flight_state ao_log_state;  #define AO_LOG_FORMAT_TELEMINI		8	/* 16-byte MS5607 baro only, 3.3V supply */  #define AO_LOG_FORMAT_TELEGPS		9	/* 32 byte telegps records */  #define AO_LOG_FORMAT_TELEMEGA		10	/* 32 byte typed telemega records with 32 bit gyro cal */ +#define AO_LOG_FORMAT_DETHERM		11	/* 16-byte MS5607 baro only, no ADC */  #define AO_LOG_FORMAT_NONE		127	/* No log at all */  extern __code uint8_t ao_log_format; diff --git a/src/kernel/ao_log_mini.c b/src/kernel/ao_log_mini.c index 0ca3ed06..844f38aa 100644 --- a/src/kernel/ao_log_mini.c +++ b/src/kernel/ao_log_mini.c @@ -110,9 +110,11 @@ ao_log(void)  					      ao_data_ring[ao_log_data_pos].ms5607_raw.pres);  				ao_log_pack24(log.u.sensor.temp,  					      ao_data_ring[ao_log_data_pos].ms5607_raw.temp); +#if AO_LOG_FORMAT != AO_LOG_FORMAT_DETHERM  				log.u.sensor.sense_a = ao_data_ring[ao_log_data_pos].adc.sense_a;  				log.u.sensor.sense_m = ao_data_ring[ao_log_data_pos].adc.sense_m;  				log.u.sensor.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt; +#endif  				ao_log_mini(&log);  				if (ao_log_state <= ao_flight_coast)  					next_sensor = log.tick + AO_SENSOR_INTERVAL_ASCENT; diff --git a/src/kernel/ao_panic.c b/src/kernel/ao_panic.c index c29cd8fe..e280f98c 100644 --- a/src/kernel/ao_panic.c +++ b/src/kernel/ao_panic.c @@ -38,10 +38,15 @@ ao_panic_delay(uint8_t n)  {  	uint8_t	i = 0, j = 0; -	while (n--) +	while (n--) { +#ifdef AO_PANIC_DELAY_SCALE +	uint8_t s = AO_PANIC_DELAY_SCALE; +	while (s--) +#endif  		while (--j)  			while (--i)  				ao_arch_nop(); +	}  }  void @@ -56,16 +61,16 @@ ao_panic(uint8_t reason)  	ao_arch_block_interrupts();  	for (;;) {  		ao_panic_delay(20); +#if HAS_BEEP  		for (n = 0; n < 5; n++) { -			ao_led_on(AO_LED_PANIC);  			ao_beep(AO_BEEP_HIGH);  			ao_panic_delay(1); -			ao_led_off(AO_LED_PANIC);  			ao_beep(AO_BEEP_LOW);  			ao_panic_delay(1);  		}  		ao_beep(AO_BEEP_OFF);  		ao_panic_delay(2); +#endif  #ifdef SDCC  #pragma disable_warning 126 diff --git a/src/kernel/ao_power.c b/src/kernel/ao_power.c new file mode 100644 index 00000000..bead5944 --- /dev/null +++ b/src/kernel/ao_power.c @@ -0,0 +1,80 @@ +/* + * Copyright © 2016 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_power.h> + +static struct ao_power	*head, *tail; + +void +ao_power_register(struct ao_power *power) +{ +	if (power->registered) +		return; +	power->registered = TRUE; +	if (tail) { +		tail->next = power; +		power->prev = tail; +		tail = power; +	} else { +		head = tail = power; +	} +#ifdef AO_LED_POWER +	ao_led_on(AO_LED_POWER); +#endif +} + +void +ao_power_unregister(struct ao_power *power) +{ +	if (!power->registered) +		return; +	power->registered = FALSE; +	if (power->prev) +		power->prev->next = power->next; +	else +		head = power->next; +	if (power->next) +		power->next->prev = power->prev; +	else +		tail = power->prev; +} + +void +ao_power_suspend(void) +{ +	struct ao_power	*p; + +#ifdef AO_LED_POWER +	ao_led_off(AO_LED_POWER); +#endif +	for (p = tail; p; p = p->prev) +		p->suspend(p->arg); +} + +void +ao_power_resume(void) +{ +	struct ao_power	*p; + +	for (p = head; p; p = p->next) +		p->resume(p->arg); +#ifdef AO_LED_POWER +	ao_led_on(AO_LED_POWER); +#endif +} + diff --git a/src/kernel/ao_power.h b/src/kernel/ao_power.h new file mode 100644 index 00000000..98a8c1c7 --- /dev/null +++ b/src/kernel/ao_power.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2016 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_POWER_H_ +#define _AO_POWER_H_ + +#if AO_POWER_MANAGEMENT + +struct ao_power { +	struct ao_power	*prev, *next; + +	void (*suspend)(void *arg); +	void (*resume)(void *arg); +	void *arg; +	uint8_t	registered; +}; + +void +ao_power_register(struct ao_power *power); + +void +ao_power_unregister(struct ao_power *power); + +void +ao_power_suspend(void); + +void +ao_power_resume(void); + +#else /* AO_POWER_MANAGEMENT */ + +#define ao_power_register(power) +#define ao_power_unregister(power) +#define ao_power_suspend() +#define ao_power_resume() + +#endif /* else AO_POWER_MANAGEMENT */ + +#endif /* _AO_POWER_H_ */ diff --git a/src/kernel/ao_product.c b/src/kernel/ao_product.c index c711a4d2..3a829b3a 100644 --- a/src/kernel/ao_product.c +++ b/src/kernel/ao_product.c @@ -33,11 +33,32 @@ 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 +#ifndef AO_USB_SELF_POWER +#define AO_USB_SELF_POWER	1 +#endif + +#define AO_USB_DEVICE_CLASS_COMMUNICATION	0x02 +#define AO_USB_INTERFACE_CLASS_CONTROL_CDC	0x02 +#define AO_USB_INTERFACE_CLASS_DATA_CDC		0x0A + +#ifndef AO_USB_DEVICE_CLASS +#define AO_USB_DEVICE_CLASS		AO_USB_DEVICE_CLASS_COMMUNICATION +#endif + +#ifndef AO_USB_INTERFACE_CLASS_DATA +#define AO_USB_INTERFACE_CLASS_CONTROL	AO_USB_INTERFACE_CLASS_CONTROL_CDC +#define AO_USB_INTERFACE_CLASS_DATA	AO_USB_INTERFACE_CLASS_DATA_CDC  #endif  #include "ao_usb.h" + +#define HEADER_LEN	       	9 +#define CONTROL_CLASS_LEN	35 +#define DATA_LEN		(9 + 7 * AO_USB_HAS_OUT + 7 * AO_USB_HAS_IN + 7 * AO_USB_HAS_IN2) + +#define TOTAL_LENGTH		(HEADER_LEN + AO_USB_HAS_INT * CONTROL_CLASS_LEN + DATA_LEN) +#define NUM_INTERFACES		(AO_USB_HAS_INT + 1) +  /* USB descriptors in one giant block of bytes */  AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =  { @@ -45,7 +66,7 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =  	0x12,  	AO_USB_DESC_DEVICE,  	LE_WORD(0x0110),	/*  bcdUSB */ -	0x02,			/*  bDeviceClass */ +	AO_USB_DEVICE_CLASS,	/*  bDeviceClass */  	0x00,			/*  bDeviceSubClass */  	0x00,			/*  bDeviceProtocol */  	AO_USB_CONTROL_SIZE,	/*  bMaxPacketSize */ @@ -60,20 +81,21 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =  	/* Configuration descriptor */  	0x09,  	AO_USB_DESC_CONFIGURATION, -	LE_WORD(67),		/*  wTotalLength */ -	0x02,			/*  bNumInterfaces */ +	LE_WORD(TOTAL_LENGTH),	/*  wTotalLength */ +	NUM_INTERFACES,		/*  bNumInterfaces */  	0x01,			/*  bConfigurationValue */  	0x00,			/*  iConfiguration */ -	0xC0,			/*  bmAttributes */ +	0x80 | (AO_USB_SELF_POWER << 6),	/*  bmAttributes */  	AO_USB_MAX_POWER >> 1,	/*  bMaxPower, 2mA units */ +#if AO_USB_HAS_INT  	/* Control class interface */  	0x09,  	AO_USB_DESC_INTERFACE,  	0x00,			/*  bInterfaceNumber */  	0x00,			/*  bAlternateSetting */  	0x01,			/*  bNumEndPoints */ -	AO_USB_INTERFACE_CLASS,	/*  bInterfaceClass */ +	AO_USB_INTERFACE_CLASS_CONTROL,	/*  bInterfaceClass */  	0x02,			/*  bInterfaceSubClass */  	0x01,			/*  bInterfaceProtocol, linux requires value of 1 for the cdc_acm module */  	0x00,			/*  iInterface */ @@ -111,18 +133,20 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =  	0x03,			/* bmAttributes = intr */  	LE_WORD(8),		/* wMaxPacketSize */  	0xff,			/* bInterval */ +#endif  	/* Data class interface descriptor */  	0x09,  	AO_USB_DESC_INTERFACE, -	0x01,			/* bInterfaceNumber */ -	0x00,			/* bAlternateSetting */ -	0x02,			/* bNumEndPoints */ -	0x0A,			/* bInterfaceClass = data */ -	0x00,			/* bInterfaceSubClass */ -	0x00,			/* bInterfaceProtocol */ -	0x00,			/* iInterface */ - +	AO_USB_HAS_INT,			/* bInterfaceNumber */ +	0x00,				/* bAlternateSetting */ +	AO_USB_HAS_OUT + AO_USB_HAS_IN + AO_USB_HAS_IN2,	/* bNumEndPoints */ +	AO_USB_INTERFACE_CLASS_DATA,	/* bInterfaceClass = data */ +	0x00,				/* bInterfaceSubClass */ +	0x00,				/* bInterfaceProtocol */ +	0x00,				/* iInterface */ + +#if AO_USB_HAS_OUT  	/* Data EP OUT */  	0x07,  	AO_USB_DESC_ENDPOINT, @@ -130,7 +154,9 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =  	0x02,			/* bmAttributes = bulk */  	LE_WORD(AO_USB_OUT_SIZE),/* wMaxPacketSize */  	0x00,			/* bInterval */ +#endif +#if AO_USB_HAS_IN  	/* Data EP in */  	0x07,  	AO_USB_DESC_ENDPOINT, @@ -138,6 +164,17 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =  	0x02,			/* bmAttributes = bulk */  	LE_WORD(AO_USB_IN_SIZE),/* wMaxPacketSize */  	0x00,			/* bInterval */ +#endif + +#if AO_USB_HAS_IN2 +	/* Data EP in 2 */ +	0x07, +	AO_USB_DESC_ENDPOINT, +	AO_USB_IN2_EP|0x80,	/* bEndpointAddress */ +	0x02,			/* bmAttributes = bulk */ +	LE_WORD(AO_USB_IN_SIZE),/* wMaxPacketSize */ +	0x00,			/* bInterval */ +#endif  	/* String descriptors */  	0x04, diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c index 55e423bb..e430edc6 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -355,7 +355,6 @@ ao_yield(void) ao_arch_naked_define  	 */  	if (ao_cur_task->wchan == NULL)  		ao_task_to_run_queue(ao_cur_task); -	ao_cur_task = NULL;  	for (;;) {  		ao_arch_memory_barrier();  		if (!ao_list_is_empty(&run_queue)) @@ -425,6 +424,7 @@ ao_sleep(__xdata void *wchan)  void  ao_wakeup(__xdata void *wchan) __reentrant  { +	ao_validate_cur_stack();  #if HAS_TASK_QUEUE  	struct ao_task	*sleep, *next;  	struct ao_list	*sleep_queue; @@ -442,10 +442,12 @@ ao_wakeup(__xdata void *wchan) __reentrant  	}  	ao_arch_irqrestore(flags);  #else +	{  	uint8_t	i;  	for (i = 0; i < ao_num_tasks; i++)  		if (ao_tasks[i]->wchan == wchan)  			ao_tasks[i]->wchan = NULL; +	}  #endif  	ao_check_stack();  } diff --git a/src/kernel/ao_task.h b/src/kernel/ao_task.h index c6bec0e3..0e353fe8 100644 --- a/src/kernel/ao_task.h +++ b/src/kernel/ao_task.h @@ -56,6 +56,10 @@ extern __data uint8_t ao_num_tasks;  extern __xdata struct ao_task *__data ao_cur_task;  extern __data uint8_t ao_task_minimize_latency;	/* Reduce IRQ latency */ +#ifndef HAS_ARCH_VALIDATE_CUR_STACK +#define ao_validate_cur_stack() +#endif +  /*   ao_task.c   */ diff --git a/src/kernel/ao_usb.h b/src/kernel/ao_usb.h index 1ce4f82f..8f3e7813 100644 --- a/src/kernel/ao_usb.h +++ b/src/kernel/ao_usb.h @@ -105,6 +105,23 @@ extern __code __at (0x00aa) uint8_t ao_usb_descriptors [];  #ifndef AO_USB_OUT_EP  #define AO_USB_OUT_EP		4  #define AO_USB_IN_EP		5 +#define AO_USB_IN2_EP		6 +#endif + +#ifndef AO_USB_HAS_OUT +#define AO_USB_HAS_OUT	1 +#endif + +#ifndef AO_USB_HAS_IN +#define AO_USB_HAS_IN	1 +#endif + +#ifndef AO_USB_HAS_INT +#define AO_USB_HAS_INT	1 +#endif + +#ifndef AO_USB_HAS_IN2 +#define AO_USB_HAS_IN2	0  #endif  /*  | 
