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 /* |