diff options
| author | Bdale Garbee <bdale@gag.com> | 2017-08-12 00:59:03 -0400 | 
|---|---|---|
| committer | Bdale Garbee <bdale@gag.com> | 2017-08-12 00:59:03 -0400 | 
| commit | 59c6167b9f1e9de30455af1632e9a0b65d64ad63 (patch) | |
| tree | d27e4b3df53300081aa6ac0a30820c58a1c968ef /src | |
| parent | 41eedf88751910ea9c0a299444fbac769edb8427 (diff) | |
| parent | fccfa54bb3b746cecfcdc1fd497cf736bbfe3ef3 (diff) | |
Merge branch 'branch-1.8' into debian
Diffstat (limited to 'src')
86 files changed, 3087 insertions, 217 deletions
| diff --git a/src/Makefile b/src/Makefile index 5bc0a7a0..25e43a0e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -41,13 +41,17 @@ ARMM3DIRS=\  	teledongle-v3.0 teledongle-v3.0/flash-loader \  	teleballoon-v2.0 \  	telebt-v3.0 telebt-v3.0/flash-loader \ +	telebt-v4.0 telebt-v4.0/flash-loader \  	telelcotwo-v0.1 telelcotwo-v0.1/flash-loader \  	telefiretwo-v0.1 telefiretwo-v0.1/flash-loader \  ARMM0DIRS=\  	easymini-v1.0 easymini-v1.0/flash-loader \  	chaoskey-v0.1 chaoskey-v0.1/flash-loader \ -	chaoskey-v1.0 chaoskey-v1.0/flash-loader +	chaoskey-v1.0 chaoskey-v1.0/flash-loader \ +	telemini-v3.0 telemini-v3.0/flash-loader \ +	easymini-v2.0 easymini-v2.0/flash-loader \ +	micropeak-v2.0 micropeak-v2.0/flash-loader  AVRDIRS=\  	telescience-v0.1 telescience-pwm micropeak nanopeak-v0.1 microkite diff --git a/src/avr/ao_usb_avr.c b/src/avr/ao_usb_avr.c index 08950a97..41d3c1be 100644 --- a/src/avr/ao_usb_avr.c +++ b/src/avr/ao_usb_avr.c @@ -136,7 +136,7 @@ ISR(USB_GEN_vect)  } -__xdata static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8}; +struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};  /* Walk through the list of descriptors and find a match   */ diff --git a/src/cc1111/ao_usb.c b/src/cc1111/ao_usb.c index 7d363c08..259f6512 100644 --- a/src/cc1111/ao_usb.c +++ b/src/cc1111/ao_usb.c @@ -112,7 +112,7 @@ ao_usb_ep0_flush(void)  	USBCS0 = cs0;  } -__xdata static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8}; +__xdata struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};  /* Walk through the list of descriptors and find a match   */ diff --git a/src/drivers/ao_hmc5883.c b/src/drivers/ao_hmc5883.c index f668fb66..c33aa536 100644 --- a/src/drivers/ao_hmc5883.c +++ b/src/drivers/ao_hmc5883.c @@ -126,13 +126,15 @@ struct ao_hmc5883_sample ao_hmc5883_current;  static void  ao_hmc5883(void)  { +	struct ao_hmc5883_sample	sample;  	ao_hmc5883_setup();  	for (;;) { -		ao_hmc5883_sample(&ao_hmc5883_current); -		ao_arch_critical( -			AO_DATA_PRESENT(AO_DATA_HMC5883); -			AO_DATA_WAIT(); -			); +		ao_hmc5883_sample(&sample); +		ao_arch_block_interrupts(); +		ao_hmc5883_current = sample; +		AO_DATA_PRESENT(AO_DATA_HMC5883); +		AO_DATA_WAIT(); +		ao_arch_release_interrupts();  	}  } @@ -141,10 +143,8 @@ static struct ao_task ao_hmc5883_task;  static void  ao_hmc5883_show(void)  { -	struct ao_data	sample; -	ao_data_get(&sample); -	printf ("X: %d Y: %d Z: %d missed irq: %lu\n", -		sample.hmc5883.x, sample.hmc5883.y, sample.hmc5883.z, ao_hmc5883_missed_irq); +	printf ("X: %d Z: %d Y: %d missed irq: %lu\n", +		ao_hmc5883_current.x, ao_hmc5883_current.z, ao_hmc5883_current.y, ao_hmc5883_missed_irq);  }  static const struct ao_cmds ao_hmc5883_cmds[] = { diff --git a/src/drivers/ao_hmc5883.h b/src/drivers/ao_hmc5883.h index 78637b02..b90733df 100644 --- a/src/drivers/ao_hmc5883.h +++ b/src/drivers/ao_hmc5883.h @@ -77,7 +77,7 @@  #define HMC5883_ID_C		12  struct ao_hmc5883_sample { -	int16_t		x, y, z; +	int16_t		x, z, y;  };  extern struct ao_hmc5883_sample	ao_hmc5883_current; diff --git a/src/drivers/ao_mpu6000.c b/src/drivers/ao_mpu6000.c index 650407ad..81d3c16c 100644 --- a/src/drivers/ao_mpu6000.c +++ b/src/drivers/ao_mpu6000.c @@ -192,7 +192,7 @@ _ao_mpu6000_setup(void)  	_ao_mpu6000_wait_alive();  	/* Reset the whole chip */ -	 +  	_ao_mpu6000_reg_write(MPU6000_PWR_MGMT_1,  			      (1 << MPU6000_PWR_MGMT_1_DEVICE_RESET)); @@ -292,7 +292,7 @@ _ao_mpu6000_setup(void)  		ao_delay(AO_MS_TO_TICKS(200));  		_ao_mpu6000_sample(&normal_mode); -	 +  		errors += ao_mpu6000_accel_check(normal_mode.accel_x, test_mode.accel_x);  		errors += ao_mpu6000_accel_check(normal_mode.accel_y, test_mode.accel_y);  		errors += ao_mpu6000_accel_check(normal_mode.accel_z, test_mode.accel_z); @@ -315,7 +315,7 @@ _ao_mpu6000_setup(void)  	/* Set sample rate divider to sample at 200Hz (v = gyro/rate - 1) */  	_ao_mpu6000_reg_write(MPU6000_SMPRT_DIV,  			      1000 / 200 - 1); -	 +  	ao_delay(AO_MS_TO_TICKS(100));  	ao_mpu6000_configured = 1;  } @@ -325,6 +325,7 @@ struct ao_mpu6000_sample	ao_mpu6000_current;  static void  ao_mpu6000(void)  { +	struct ao_mpu6000_sample	sample;  	/* ao_mpu6000_init already grabbed the SPI bus and mutex */  	_ao_mpu6000_setup();  #if AO_MPU6000_SPI @@ -335,14 +336,15 @@ ao_mpu6000(void)  #if AO_MPU6000_SPI  		ao_mpu6000_spi_get();  #endif -		_ao_mpu6000_sample(&ao_mpu6000_current); +		_ao_mpu6000_sample(&sample);  #if AO_MPU6000_SPI  		ao_mpu6000_spi_put(); -#endif	 -		ao_arch_critical( -			AO_DATA_PRESENT(AO_DATA_MPU6000); -			AO_DATA_WAIT(); -			); +#endif +		ao_arch_block_interrupts(); +		ao_mpu6000_current = sample; +		AO_DATA_PRESENT(AO_DATA_MPU6000); +		AO_DATA_WAIT(); +		ao_arch_release_interrupts();  	}  } @@ -351,16 +353,13 @@ static struct ao_task ao_mpu6000_task;  static void  ao_mpu6000_show(void)  { -	struct ao_data	sample; - -	ao_data_get(&sample);  	printf ("Accel: %7d %7d %7d Gyro: %7d %7d %7d\n", -		sample.mpu6000.accel_x, -		sample.mpu6000.accel_y, -		sample.mpu6000.accel_z, -		sample.mpu6000.gyro_x, -		sample.mpu6000.gyro_y, -		sample.mpu6000.gyro_z); +		ao_mpu6000_current.accel_x, +		ao_mpu6000_current.accel_y, +		ao_mpu6000_current.accel_z, +		ao_mpu6000_current.gyro_x, +		ao_mpu6000_current.gyro_y, +		ao_mpu6000_current.gyro_z);  }  static const struct ao_cmds ao_mpu6000_cmds[] = { @@ -374,7 +373,7 @@ ao_mpu6000_init(void)  	ao_mpu6000_configured = 0;  	ao_add_task(&ao_mpu6000_task, ao_mpu6000, "mpu6000"); -	 +  #if AO_MPU6000_SPI  	ao_spi_init_cs(AO_MPU6000_SPI_CS_PORT, (1 << AO_MPU6000_SPI_CS_PIN)); @@ -386,7 +385,7 @@ ao_mpu6000_init(void)  	ao_cur_task = &ao_mpu6000_task;  	ao_spi_get(AO_MPU6000_SPI_BUS, AO_SPI_SPEED_1MHz);  	ao_cur_task = NULL; -#endif	 +#endif  	ao_cmd_register(&ao_mpu6000_cmds[0]);  } diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c index 261df67f..914e0c1b 100644 --- a/src/drivers/ao_ms5607.c +++ b/src/drivers/ao_ms5607.c @@ -191,17 +191,23 @@ ao_ms5607_sample(__xdata struct ao_ms5607_sample *sample)  #include "ao_ms5607_convert.c"  #endif -#if HAS_TASK +#ifndef HAS_MS5607_TASK +#define HAS_MS5607_TASK HAS_TASK +#endif +  __xdata struct ao_ms5607_sample	ao_ms5607_current; +#if HAS_MS5607_TASK  static void  ao_ms5607(void)  { +	struct ao_ms5607_sample	sample;  	ao_ms5607_setup();  	for (;;)  	{ -		ao_ms5607_sample(&ao_ms5607_current); +		ao_ms5607_sample(&sample);  		ao_arch_block_interrupts(); +		ao_ms5607_current = sample;  		AO_DATA_PRESENT(AO_DATA_MS5607);  		AO_DATA_WAIT();  		ao_arch_release_interrupts(); @@ -209,7 +215,9 @@ ao_ms5607(void)  }  __xdata struct ao_task ao_ms5607_task; +#endif +#if HAS_TASK  void  ao_ms5607_info(void)  { @@ -248,6 +256,8 @@ ao_ms5607_init(void)  #if HAS_TASK  	ao_cmd_register(&ao_ms5607_cmds[0]); +#endif +#if HAS_MS5607_TASK  	ao_add_task(&ao_ms5607_task, ao_ms5607, "ms5607");  #endif diff --git a/src/drivers/ao_rn4678.c b/src/drivers/ao_rn4678.c new file mode 100644 index 00000000..98dc35b5 --- /dev/null +++ b/src/drivers/ao_rn4678.c @@ -0,0 +1,606 @@ +/* + * Copyright © 2017 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, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#include <ao.h> +#include <ao_rn4678.h> +#include <ao_exti.h> +#include <stdarg.h> + +static uint8_t	ao_rn_connected; + +#define AO_RN_DEBUG 0 + +#if AO_RN_DEBUG +static void ao_rn_dbg(char *format, ...) { +	va_list a; +	uint32_t	irq = ao_arch_irqsave(); +	ao_arch_release_interrupts(); +	va_start(a, format); +	vprintf(format, a); +	va_end(a); +	flush(); +	ao_arch_irqrestore(irq); +} + +static char	ao_rn_dir; + +static void +ao_rn_log_char(char c, char dir) +{ +	if (dir != ao_rn_dir) { +		putchar(dir); putchar('\n'); +		ao_rn_dir = dir; +	} +	switch (c) { +	case '\r': +		putchar('\\'); putchar('r'); +		break; +	case '\n': +		putchar('\\'); putchar('n'); +		break; +	default: +		putchar(c); +	} +	flush(); +} + +static void +ao_rn_log_out_char(char c) +{ +	ao_rn_log_char(c, '}'); +} + +static void +ao_rn_log_in_char(char c) +{ +	ao_rn_log_char(c, '{'); +} + +static inline void +ao_rn_putchar(char c) +{ +	ao_rn_log_out_char(c); +	ao_serial_rn_putchar(c); +} + +static inline int +_ao_rn_pollchar(void) +{ +	int	c = _ao_serial_rn_pollchar(); + +	if (c != AO_READ_AGAIN) { +		ao_arch_release_interrupts(); +		ao_rn_log_in_char((char) c); +		ao_arch_block_interrupts(); +	} +	return c; +} +#else +#define ao_rn_dbg(fmt, ...) +#define ao_rn_putchar(c)	ao_serial_rn_putchar(c) +#define _ao_rn_pollchar()	_ao_serial_rn_pollchar() +#endif + +/* For stdio, this skips all status messages *sigh* */ + +#define STATUS_CHAR	'%' + +static const char *status_strings[] = { +	"RFCOMM_CLOSE", +	"RFCOMM_OPEN", +	"CONNECT", +	"LCONNECT", +	"DISCONN", +	"BONDED", +}; + +#define NUM_STATUS_STRING	(sizeof status_strings/sizeof status_strings[0]) + +static char		ao_rn_buffer[64]; +static int		ao_rn_buf_cnt, ao_rn_buf_ptr; +static int		ao_rn_draining; +static AO_TICK_TYPE	ao_rn_buf_time; + +/* Well, this is annoying. The status strings from the RN4678 can't be + * disabled due to a firmware bug. So, this code finds those in the + * input and strips them out. + */ +int +_ao_wrap_rn_pollchar(void) +{ +	int		c = AO_READ_AGAIN; +	unsigned	i; +	int		done = 0; + +	while (!done && !ao_rn_draining) { +		c = _ao_serial_rn_pollchar(); + +		if (c == AO_READ_AGAIN) { +			if (ao_rn_buf_cnt && (ao_time() - ao_rn_buf_time) > AO_MS_TO_TICKS(1000)) { +				ao_rn_draining = 1; +				continue; +			} +			return AO_READ_AGAIN; +		} + +		if (ao_rn_buf_cnt) { +			/* buffering chars */ + +			if (c == STATUS_CHAR) { +				/* End of status string, drop it and carry on */ +				ao_rn_buffer[ao_rn_buf_cnt] = '\0'; +//				ao_rn_dbg("discard %s\n", ao_rn_buffer); +				ao_rn_buf_cnt = 0; +			} else if (ao_rn_buf_cnt == sizeof(ao_rn_buffer)) { +				/* If we filled the buffer, just give up */ +				ao_rn_draining = 1; +			} else { +				ao_rn_buffer[ao_rn_buf_cnt++] = c; +				for (i = 0; i < NUM_STATUS_STRING; i++) { +					int cmp = strlen(status_strings[i]); +					if (cmp >= ao_rn_buf_cnt) +						cmp = ao_rn_buf_cnt-1; +					if (memcmp(ao_rn_buffer+1, status_strings[i], cmp) == 0) +						break; +				} +				if (i == NUM_STATUS_STRING) +					ao_rn_draining = 1; +			} +		} else if (c == STATUS_CHAR) { +			ao_rn_buffer[0] = c; +			ao_rn_buf_cnt = 1; +			ao_rn_buf_ptr = 0; +			ao_rn_buf_time = ao_time(); +		} else +			done = 1; +	} +	if (ao_rn_draining) { +		c = ao_rn_buffer[ao_rn_buf_ptr++] & 0xff; +		if (ao_rn_buf_ptr == ao_rn_buf_cnt) { +			ao_rn_buf_ptr = ao_rn_buf_cnt = 0; +			ao_rn_draining = 0; +		} +	} +	return c; +} + +static void +ao_rn_puts(char *s) +{ +	char c; + +	while ((c = *s++)) +		ao_rn_putchar(c); +} + +static void +ao_rn_drain(void) +{ +	int	timeout = 0; + +//	ao_rn_dbg("drain...\n"); +	ao_serial_rn_drain(); +	while (!timeout) { +		ao_arch_block_interrupts(); +		while (_ao_rn_pollchar() == AO_READ_AGAIN) { +			if (_ao_serial_rn_sleep_for(AO_MS_TO_TICKS(10))) { +				timeout = 1; +				break; +			} +		} +		ao_arch_release_interrupts(); +	} +//	ao_rn_dbg("drain done\n"); +} + +static void +ao_rn_send_cmd(char *cmd, char *param) +{ +//	ao_rn_dbg("send_cmd %s%s\n", cmd, param ? param : ""); +	ao_rn_drain(); +	ao_rn_puts(cmd); +	if (param) +		ao_rn_puts(param); +	ao_rn_putchar('\r'); +} + +static int +ao_rn_wait_char(AO_TICK_TYPE giveup_time) +{ +	int c; + +	ao_arch_block_interrupts(); +	while ((c = _ao_rn_pollchar()) == AO_READ_AGAIN) { +		AO_TICK_SIGNED	delay = (AO_TICK_SIGNED) (giveup_time - ao_time()); +		if (delay < 0) { +			ao_arch_release_interrupts(); +			return AO_READ_AGAIN; +		} +		_ao_serial_rn_sleep_for(delay); +	} +	ao_arch_release_interrupts(); +	return c; +} + +static int +ao_rn_wait_for(int timeout, char *match) +{ +	char		reply[AO_RN_MAX_REPLY_LEN + 1]; +	int		match_len = strlen(match); +	AO_TICK_TYPE	giveup_time = ao_time() + timeout; +	int		c; + +//	ao_rn_dbg("wait for %d, \"%s\"\n", timeout, match); +	memset(reply, ' ', sizeof(reply)); +	while (memcmp(reply, match, match_len) != 0) { +		c = ao_rn_wait_char(giveup_time); +		if (c == AO_READ_AGAIN) { +//			ao_rn_dbg("\twait for timeout\n"); +			return AO_RN_TIMEOUT; +		} +		reply[match_len] = (char) c; +		memmove(reply, reply+1, match_len); +		reply[match_len] = '\0'; +//		ao_rn_dbg("\tmatch now \"%s\"\n", reply); +	} +//	ao_rn_dbg("\twait for ok\n"); +	return AO_RN_OK; +} + +static int +ao_rn_wait_line(AO_TICK_TYPE giveup_time, char *line, int len) +{ +	char *l = line; + +//	ao_rn_dbg("wait line\n"); +	for (;;) { +		int c = ao_rn_wait_char(giveup_time); + +		/* timeout */ +		if (c == AO_READ_AGAIN) { +//			ao_rn_dbg("\twait line timeout\n"); +			return AO_RN_TIMEOUT; +		} + +		/* done */ +		if (c == '\r') { +			*l = '\0'; +//			ao_rn_dbg("\twait line \"%s\"\n", line); +			return AO_RN_OK; +		} + +		if (c == '\n') +			continue; + +		/* buffer overrun */ +		if (len <= 1) +			return AO_RN_ERROR; + +		*l++ = (char) c; +		len--; +	} +} + +static int +ao_rn_wait_status(void) +{ +	char		message[AO_RN_MAX_REPLY_LEN]; +	AO_TICK_TYPE	giveup_time = ao_time() + AO_RN_CMD_TIMEOUT; +	int		status; + +//	ao_rn_dbg("wait status\n"); +	status = ao_rn_wait_line(giveup_time, message, sizeof (message)); +	if (status == AO_RN_OK) +		if (strncmp(message, "AOK", 3) != 0) +			status = AO_RN_ERROR; +	return status; +} + +static int +ao_rn_set_name(void) +{ +	char	sn[8]; +	char	*s = sn + 8; +	int	n; + +//	ao_rn_dbg("set name...\n"); +	*--s = '\0'; +	n = ao_serial_number; +	do { +		*--s = '0' + n % 10; +	} while (n /= 10); +	ao_rn_send_cmd(AO_RN_SET_NAME_CMD "TeleBT-", s); +	return ao_rn_wait_status(); +} + +static int +ao_rn_get_name(char *name, int len) +{ +//	ao_rn_dbg("get name...\n"); +	ao_rn_send_cmd(AO_RN_GET_NAME_CMD, NULL); +	return ao_rn_wait_line(ao_time() + AO_RN_CMD_TIMEOUT, name, len); +} + +static void +ao_rn_check_link(void) +{ +	ao_rn_connected = 1 - ao_gpio_get(AO_RN_CONNECTED_PORT, AO_RN_CONNECTED_PIN, foo); +} + +static void +ao_rn_isr(void) +{ +	ao_rn_check_link(); +	ao_wakeup(&ao_rn_connected); +} + +static void +ao_bt_panic(int where) +{ +	int i; +	for (;;) { +		for (i = 0; i < 50; i++) { +			ao_led_toggle(AO_BT_LED); +			ao_delay(AO_MS_TO_TICKS(10)); +		} +		ao_led_off(AO_BT_LED); +		ao_delay(AO_MS_TO_TICKS(500)); +		for (i = 0; i < where; i++) { +			ao_led_for(AO_BT_LED, AO_MS_TO_TICKS(200)); +			ao_delay(AO_MS_TO_TICKS(200)); +		} +	} +} + +static uint8_t	ao_rn_stdio; + +/* + * Set the stdio echo for the bluetooth link + */ +void +ao_rn_echo(uint8_t echo) +{ +	ao_stdios[ao_rn_stdio].echo = echo; +} + +static void +ao_rn(void) +{ +	int	status = AO_RN_ERROR; +	char	name[17]; +	int	i; + +	ao_rn_dbg("ao_rn top\n"); + +	/* Select CMD mode after the device gets out of reset */ +	ao_gpio_set(AO_RN_CMD_PORT, AO_RN_CMD_PIN, foo, AO_RN_CMD_CMD); + +	for (i = 0; i < 3; i++) { +		ao_rn_dbg("reset device\n"); + +		ao_gpio_set(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 0); +		ao_delay(AO_MS_TO_TICKS(100)); + +		/* Reboot the RN4678 and wait for it to start talking */ +		ao_rn_drain(); +		ao_gpio_set(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 1); +		status = ao_rn_wait_for(AO_RN_REBOOT_TIMEOUT, AO_RN_REBOOT_MSG); +		if (status != AO_RN_OK) { +			ao_rn_dbg("reboot failed\n"); +			continue; +		} + +		/* After it reboots, it can take a moment before it responds +		 * to commands +		 */ +		status = ao_rn_wait_for(AO_RN_REBOOT_TIMEOUT, "CMD> "); + +		if (status == AO_RN_TIMEOUT) { +			ao_rn_puts("$$$"); +			(void) ao_rn_wait_for(AO_RN_REBOOT_TIMEOUT, "CMD> "); +		} + +		ao_rn_send_cmd(AO_RN_VERSION_CMD, NULL); +		(void) ao_rn_wait_status(); + +		/* Check to see if the name is already set and assume +		 * that the device is ready to go +		 */ +		status = ao_rn_get_name(name, sizeof (name)); +		if (status != AO_RN_OK) { +			ao_rn_dbg("get name failed\n"); +			status = ao_rn_get_name(name, sizeof (name)); +			if (status != AO_RN_OK) +				continue; +		} + +		if (strncmp(name, "TeleBT-", 7) == 0) { +			ao_rn_dbg("name is set\n"); +			status = AO_RN_OK; +			break; +		} + +		/* Make the command pin control command/data mode */ +		ao_rn_send_cmd(AO_RN_SET_COMMAND_PIN, NULL); +		if (ao_rn_wait_status() != AO_RN_OK) { +			ao_rn_dbg("set command pin failed\n"); +			continue; +		} + +		ao_rn_send_cmd(AO_RN_SET_STATUS_STRING, AO_RN_STATUS_STRING_ENABLE); +		if (ao_rn_wait_status() != AO_RN_OK) { +			ao_rn_dbg("set status string\n"); +			continue; +		} + +		/* Select 'fast' mode to ignore command sequence (more or less) */ +		ao_rn_send_cmd(AO_RN_SET_FAST_MODE, NULL); +		if (ao_rn_wait_status() != AO_RN_OK) { +			ao_rn_dbg("set fast mode failed\n"); +			continue; +		} + +		/* Finally, set the name. Doing this last makes it possible to check +		 * if the whole sequence has been done +		 */ +		if (ao_rn_set_name() != AO_RN_OK) { +			ao_rn_dbg("set name failed\n"); +			continue; +		} + +		/* After we've configured the device, go back around and reboot it +		 * as that's how we get the new configuration to take effect +		 */ +	} +	ao_rn_dbg("ao_rn status %d\n", status); + +	if (status != AO_RN_OK) +		ao_bt_panic(4); + +	ao_gpio_set(AO_RN_CMD_PORT, AO_RN_CMD_PIN, foo, AO_RN_CMD_DATA); + +	/* Wait for the hardware to finish sending messages, then clear the queue */ +	ao_delay(AO_MS_TO_TICKS(200)); +	ao_rn_drain(); + +	ao_exti_enable(AO_RN_CONNECTED_PORT, AO_RN_CONNECTED_PIN); + +#if AO_RN_DEBUG + +	/* +	 * Separate debug code when things aren't working. Just dump +	 * inbound bluetooth characters to stdout +	 */ +	for (;;) { +		int	c; + +		ao_arch_block_interrupts(); +		while ((c = _ao_rn_pollchar()) == AO_READ_AGAIN) +			ao_sleep(&ao_serial_rn_rx_fifo); +		ao_arch_release_interrupts(); +	} +#else +	ao_rn_stdio = ao_add_stdio(_ao_wrap_rn_pollchar, +				   ao_serial_rn_putchar, +				   NULL); + +	ao_rn_echo(0); +	ao_rn_check_link(); +	/* +	 * Now just hang around and flash the blue LED when we've got +	 * a connection +	 */ +	for (;;) { +		ao_arch_block_interrupts(); +		while (!ao_rn_connected) +			ao_sleep(&ao_rn_connected); +		ao_arch_release_interrupts(); +		while (ao_rn_connected) { +			ao_led_for(AO_BT_LED, AO_MS_TO_TICKS(20)); +			if (ao_rn_buf_cnt != 0) +				ao_wakeup(&ao_stdin_ready); +			ao_delay(AO_SEC_TO_TICKS(3)); +		} +	} +#endif +} + +static struct ao_task ao_rn_task; + +static void +ao_rn_factory(void) +{ +	int	i; +	int	v = 0; + +	/* +	 * Factory reset. Flip pin P3_1 5 times within the first five +	 * seconds of power-on +	 */ + +	/* Select our target output pin */ +	ao_enable_output(AO_RN_P3_1_PORT, AO_RN_P3_1_PIN, foo, v); + +	/* Turn off the BT device using the SW_BTN pin */ +	printf("Power down BT\n"); flush(); +	ao_gpio_set(AO_RN_SW_BTN_PORT, AO_RN_SW_BTN_PIN, foo, 0); +	ao_delay(AO_MS_TO_TICKS(1000)); + +	/* And turn it back on */ +	printf("Power up BT\n"); flush(); +	ao_gpio_set(AO_RN_SW_BTN_PORT, AO_RN_SW_BTN_PIN, foo, 1); + +	/* Right after power on, poke P3_1 five times to force a +	 * factory reset +	 */ +	for (i = 0; i < 20; i++) { +		v = 1-v; +		ao_delay(AO_MS_TO_TICKS(50)); +		ao_gpio_set(AO_RN_P3_1_PORT, AO_RN_P3_1_PIN, foo, v); +		ao_led_toggle(AO_BT_LED); +	} + +	/* And let P3_1 float again */ +	ao_enable_input(AO_RN_P3_1_PORT, AO_RN_P3_1_PIN, AO_EXTI_MODE_PULL_NONE); + +	printf("Reboot BT\n"); flush(); +	ao_delay(AO_MS_TO_TICKS(100)); +	ao_gpio_set(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 0); +	ao_delay(AO_MS_TO_TICKS(100)); +	ao_gpio_set(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 1); +} + +#if AO_RN_DEBUG +static void +ao_rn_send(void) +{ +	int	c; + +	while ((c = getchar()) != '~') +		ao_rn_putchar(c); +} +#endif + +static const struct ao_cmds rn_cmds[] = { +	{ ao_rn_factory, "F\0Factory reset rn4678" }, +#if AO_RN_DEBUG +	{ ao_rn_send, "B\0Send data to rn4678. End with ~" }, +#endif +	{ 0 }, +}; + +void +ao_rn4678_init(void) +{ +	(void) ao_rn_set_name; + +	ao_serial_rn_set_speed(AO_SERIAL_SPEED_115200); + +	/* Reset line */ +	ao_enable_output(AO_RN_RST_N_PORT, AO_RN_RST_N_PIN, foo, 0); + +	/* SW_BTN */ +	ao_enable_output(AO_RN_SW_BTN_PORT, AO_RN_SW_BTN_PIN, foo, 1); + +	/* P3_7 command/data selector */ +	ao_enable_output(AO_RN_CMD_PORT, AO_RN_CMD_PIN, foo, AO_RN_CMD_CMD); + +	ao_enable_input(AO_RN_CONNECTED_PORT, AO_RN_CONNECTED_PIN, AO_EXTI_MODE_PULL_NONE); +	ao_exti_setup(AO_RN_CONNECTED_PORT, AO_RN_CONNECTED_PIN, +		      AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_LOW, +		      ao_rn_isr); + +	ao_cmd_register(rn_cmds); +	ao_add_task(&ao_rn_task, ao_rn, "bluetooth"); +} diff --git a/src/drivers/ao_rn4678.h b/src/drivers/ao_rn4678.h new file mode 100644 index 00000000..a4dcea38 --- /dev/null +++ b/src/drivers/ao_rn4678.h @@ -0,0 +1,101 @@ +/* + * Copyright © 2017 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, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#ifndef _AO_RN4678_H_ +#define _AO_RN4678_H_ + +/* From the rn4678 pictail board + +    1	SW_BTN	0-off/1-on	 2	P2_0	1-app/0-test (boot time) +    3	P2_4	1-app/0-WF	 4	EAN	0-app/1-WF (reboots) +    5				 6	RTS	0 +    7				 8	P3_2	1 (NC) +    9	TXD			10	P3_3	1 (NC) +   11	RXD			12	P3_4	1 (NC) +   13				14 +   15				16	P3_7	1 (NC) +   17	P0_5	1 (NC)		18	RST_N	1 run/0 reset +   19	WAKE_UP	1 run/0 btn	20 +   21	P0_4	0 (NC)		22 +   23	P1_5	1 (NC)		24	P3_1	1 (NC) +   25	CTS	0		26	3.3V +   27				28	GND + + +   Interesting pins: + +   Not connected to microcontroller: + +   SW_BTN	0-off		1-on +   P2_4		0 write-flash	1-app +   WAKE_UP	0-stop		1-run +   P2_0		0 test		1-run +   EAN		1-WF (reboots)	0-run +   RST_N	0 reset		1 run + +   Connected to microcontroller: + +   CTS		mostly 0 +   RTS		mostly 1 + +   TXD +   RXD + +   Other connections -- LDO33_O to VDD_IO + +*/ + +#define AO_RN_REBOOT_MSG	"REBOOT" + +#define AO_RN_CMD_TIMEOUT	AO_MS_TO_TICKS(200) + +#define AO_RN_REBOOT_TIMEOUT	AO_MS_TO_TICKS(2000) + +#define AO_RN_MAX_REPLY_LEN	10 + +#define AO_RN_SET_NAME_CMD		"SN," +#define AO_RN_GET_NAME_CMD		"GN" + +#define AO_RN_SET_STATUS_STRING	"so," +#define AO_RN_STATUS_STRING_DISABLE	" " +#define AO_RN_STATUS_STRING_ENABLE	"%,%" + +#define AO_RN_REBOOT_CMD		"R,1" + +#define AO_RN_VERSION_CMD		"V" + +#define AO_RN_TIMEOUT	-1 +#define AO_RN_ERROR	0 +#define AO_RN_OK	1 + +#define AO_RN_SET_COMMAND_PIN	"SX,07,0B" + +#define AO_RN_SET_AUTH_JUST_WORKS	"SA,2" +#define AO_RN_SET_FAST_MODE		"SQ,9000" + +/* This pin is configured to control cmd/data mode */ +#define AO_RN_CMD_PORT	AO_RN_P3_7_PORT +#define AO_RN_CMD_PIN	AO_RN_P3_7_PIN + +#define AO_RN_CMD_CMD	0 +#define AO_RN_CMD_DATA	1 + +/* This pin indicates BT connection status */ +#define AO_RN_CONNECTED_PORT	AO_RN_P1_5_PORT +#define AO_RN_CONNECTED_PIN	AO_RN_P1_5_PIN + +void +ao_rn4678_init(void); + +#endif /* _AO_RN_H_ */ diff --git a/src/easymini-v1.0/ao_pins.h b/src/easymini-v1.0/ao_pins.h index 5983bb9e..45c6891d 100644 --- a/src/easymini-v1.0/ao_pins.h +++ b/src/easymini-v1.0/ao_pins.h @@ -42,7 +42,7 @@  #define PACKET_HAS_SLAVE	0 -#define AO_LOG_FORMAT		AO_LOG_FORMAT_EASYMINI +#define AO_LOG_FORMAT		AO_LOG_FORMAT_EASYMINI1  /* USART */ diff --git a/src/easymini-v2.0/.gitignore b/src/easymini-v2.0/.gitignore new file mode 100644 index 00000000..e5f7d586 --- /dev/null +++ b/src/easymini-v2.0/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +*.elf diff --git a/src/easymini-v2.0/Makefile b/src/easymini-v2.0/Makefile new file mode 100644 index 00000000..9b4cc6d7 --- /dev/null +++ b/src/easymini-v2.0/Makefile @@ -0,0 +1,83 @@ +# +# AltOS build +# +# + +include ../stmf0/Makefile.defs + +INC = \ +	ao.h \ +	ao_arch.h \ +	ao_arch_funcs.h \ +	ao_pins.h \ +	ao_product.h \ +	stm32f0.h + +# +# Common AltOS sources +# + +ALTOS_SRC = \ +	ao_interrupt.c \ +	ao_boot_chain.c \ +	ao_romconfig.c \ +	ao_product.c \ +	ao_mutex.c \ +	ao_panic.c \ +	ao_stdio.c \ +	ao_storage.c \ +	ao_report.c \ +	ao_ignite.c \ +	ao_flight.c \ +	ao_kalman.c \ +	ao_sample.c \ +	ao_data.c \ +	ao_convert_pa.c \ +	ao_convert_volt.c \ +	ao_task.c \ +	ao_log.c \ +	ao_log_mini.c \ +	ao_cmd.c \ +	ao_config.c \ +	ao_dma_stm.c \ +	ao_timer.c \ +	ao_exti_stm.c \ +	ao_spi_stm.c \ +	ao_adc_stm.c \ +	ao_usb_stm.c \ +	ao_m25.c \ +	ao_ms5607.c \ +	ao_beep_stm.c + +PRODUCT=EasyMini-v2.0 +PRODUCT_DEF=-DEASYMINI_V_2_0 +IDPRODUCT=0x0026 + +CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) -g -Os + +PROGNAME=easymini-v2.0 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) ao_easymini.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) $(HEX) + +$(PROG): Makefile $(OBJ) +	$(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +ao_product.h: ao-make-product.5c ../Version +	$(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +$(OBJ): $(INC) + +distclean:	clean + +clean: +	rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx +	rm -f ao_product.h + +install: + +uninstall: diff --git a/src/easymini-v2.0/ao_easymini.c b/src/easymini-v2.0/ao_easymini.c new file mode 100644 index 00000000..7246cae2 --- /dev/null +++ b/src/easymini-v2.0/ao_easymini.c @@ -0,0 +1,53 @@ +/* + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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_exti.h> + +void +main(void) +{ +	ao_clock_init(); +	ao_task_init(); +	ao_timer_init(); + +	ao_dma_init(); +	ao_spi_init(); +	ao_exti_init(); + +	ao_adc_init(); + +#if HAS_BEEP +	ao_beep_init(); +#endif +#if HAS_USB +	ao_usb_init(); +#endif +	ao_cmd_init(); + +	ao_ms5607_init(); + +	ao_storage_init(); +	ao_flight_init(); +	ao_log_init(); +	ao_report_init(); +	ao_igniter_init(); +	ao_config_init(); + +	ao_start_scheduler(); +} diff --git a/src/easymini-v2.0/ao_pins.h b/src/easymini-v2.0/ao_pins.h new file mode 100644 index 00000000..2ec0e90b --- /dev/null +++ b/src/easymini-v2.0/ao_pins.h @@ -0,0 +1,163 @@ +/* + * Copyright © 2017 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#define HAS_BEEP		1 +#define HAS_BATTERY_REPORT	1 + +#define AO_STACK_SIZE	448 + +#define IS_FLASH_LOADER	0 + +/* 48MHz clock based on 16MHz reference */ +//#define AO_HSI48	1 +#define AO_HSE			16000000 +#define AO_RCC_CFGR_PLLMUL	STM_RCC_CFGR_PLLMUL_3 +#define AO_RCC_CFGR2_PLLDIV	STM_RCC_CFGR2_PREDIV_1 +#define AO_PLLMUL		3 +#define AO_PLLDIV		1 + +/* HCLK = 48MHz */ +#define AO_AHB_PRESCALER	1 +#define AO_RCC_CFGR_HPRE_DIV	STM_RCC_CFGR_HPRE_DIV_1 + +/* APB = 40MHz */ +#define AO_APB_PRESCALER	1 +#define AO_RCC_CFGR_PPRE_DIV	STM_RCC_CFGR_PPRE_DIV_1 + +#define HAS_USB			1 +#define AO_USB_DIRECTIO		0 +#define AO_PA11_PA12_RMP	1 +#define AO_USB_FORCE_IDLE	1 + +#define AO_LOG_FORMAT		AO_LOG_FORMAT_EASYMINI2 + +#define HAS_BOOT_RADIO		0 + +#define HAS_ACCEL		0 +#define HAS_GPS			0 +#define HAS_RADIO		0 +#define HAS_FLIGHT		1 +#define HAS_EEPROM		1 +#define HAS_TELEMETRY		0 +#define HAS_APRS		0 +#define HAS_LOG			1 +#define USE_INTERNAL_FLASH	0 +#define HAS_IGNITE		1 +#define HAS_IGNITE_REPORT	1 + +/* Beeper is on Tim3 CH3 */ +#define BEEPER_TIMER		3 +#define BEEPER_CHANNEL		3 +#define BEEPER_PORT		(&stm_gpiob) +#define BEEPER_PIN		0 +#define BEEPER_AFR		STM_AFR_AF1 + +/* SPI */ + +#define HAS_SPI_1		1 +#define SPI_1_PA5_PA6_PA7	1 +#define SPI_1_PB3_PB4_PB5	1 +#define SPI_1_OSPEEDR		STM_OSPEEDR_MEDIUM + +/* M25 */ + +#define M25_MAX_CHIPS		1 +#define AO_M25_SPI_CS_PORT	(&stm_gpioa) +#define AO_M25_SPI_CS_MASK	(1 << 15) +#define AO_M25_SPI_BUS		AO_SPI_1_PB3_PB4_PB5 + +/* MS5607 */ + +#define HAS_MS5607		1 +#define HAS_MS5611		0 +#define AO_MS5607_PRIVATE_PINS	1 +#define AO_MS5607_CS_PORT	(&stm_gpioa) +#define AO_MS5607_CS_PIN	4 +#define AO_MS5607_CS_MASK	(1 << AO_MS5607_CS_PIN) +#define AO_MS5607_MISO_PORT	(&stm_gpioa) +#define AO_MS5607_MISO_PIN	6 +#define AO_MS5607_MISO_MASK	(1 << AO_MS5607_MISO_PIN) +#define AO_MS5607_SPI_INDEX	AO_SPI_1_PA5_PA6_PA7 +#define AO_MS5607_SPI_SPEED	AO_SPI_SPEED_12MHz + +#define AO_DATA_RING		64 + +/* + * ADC + */ + +#define HAS_ADC			1 + +#define AO_ADC_PIN0_PORT	(&stm_gpioa)	/* sense_m */ +#define AO_ADC_PIN0_PIN		0 +#define AO_ADC_PIN0_CH		0 +#define AO_ADC_PIN1_PORT	(&stm_gpioa)	/* sense_a */ +#define AO_ADC_PIN1_PIN		1 +#define AO_ADC_PIN1_CH		1 +#define AO_ADC_PIN2_PORT	(&stm_gpioa)	/* v_batt */ +#define AO_ADC_PIN2_PIN		2 +#define AO_ADC_PIN2_CH		2 + +#define AO_ADC_RCC_AHBENR	((1 << STM_RCC_AHBENR_IOPAEN)) + +#define AO_NUM_ADC		3 + +struct ao_adc { +	int16_t		sense_m; +	int16_t		sense_a; +	int16_t		v_batt; +}; + +/* + * Igniter + */ + +#define AO_IGNITER_CLOSED	400 +#define AO_IGNITER_OPEN		60 + +#define AO_IGNITER_DROGUE_PORT	(&stm_gpiob) +#define AO_IGNITER_DROGUE_PIN	6 +#define AO_IGNITER_SET_DROGUE(v)	ao_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, AO_IGNITER_DROGUE, v) + +#define AO_IGNITER_MAIN_PORT	(&stm_gpiob) +#define AO_IGNITER_MAIN_PIN	7 +#define AO_IGNITER_SET_MAIN(v)	ao_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, AO_IGNITER_MAIN, v) + +#define AO_SENSE_DROGUE(p)	((p)->adc.sense_a) +#define AO_SENSE_MAIN(p)	((p)->adc.sense_m) + +#define AO_ADC_DUMP(p) \ +	printf("tick: %5u apogee: %5d main: %5d batt: %5d\n", \ +	       (p)->tick, (p)->adc.sense_a, (p)->adc.sense_m, (p)->adc.v_batt) + +/* + * Voltage divider on ADC battery sampler + */ +#define AO_BATTERY_DIV_PLUS	100	/* 100k */ +#define AO_BATTERY_DIV_MINUS	27	/* 27k */ + +/* + * Voltage divider on ADC igniter samplers + */ +#define AO_IGNITE_DIV_PLUS	100	/* 100k */ +#define AO_IGNITE_DIV_MINUS	27	/* 27k */ + +/* + * ADC reference in decivolts + */ +#define AO_ADC_REFERENCE_DV	33 diff --git a/src/easymini-v2.0/flash-loader/.gitignore b/src/easymini-v2.0/flash-loader/.gitignore new file mode 100644 index 00000000..a8a0dcec --- /dev/null +++ b/src/easymini-v2.0/flash-loader/.gitignore @@ -0,0 +1 @@ +*.bin diff --git a/src/easymini-v2.0/flash-loader/Makefile b/src/easymini-v2.0/flash-loader/Makefile new file mode 100644 index 00000000..8a611751 --- /dev/null +++ b/src/easymini-v2.0/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=easymini-v2.0 +include $(TOPDIR)/stmf0/Makefile-flash.defs diff --git a/src/easymini-v2.0/flash-loader/ao_pins.h b/src/easymini-v2.0/flash-loader/ao_pins.h new file mode 100644 index 00000000..3098fc22 --- /dev/null +++ b/src/easymini-v2.0/flash-loader/ao_pins.h @@ -0,0 +1,37 @@ +/* + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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_PINS_H_ +#define _AO_PINS_H_ + +#include <ao_flash_stm_pins.h> + +/* pin 5 (PB1) on debug header to gnd for boot mode */ + +#define AO_BOOT_PIN			1 +#define AO_BOOT_APPLICATION_GPIO	stm_gpiob +#define AO_BOOT_APPLICATION_PIN		1 +#define AO_BOOT_APPLICATION_VALUE	1 +#define AO_BOOT_APPLICATION_MODE	AO_EXTI_MODE_PULL_UP + +/* USB */ +#define HAS_USB			1 +#define AO_USB_DIRECTIO		0 +#define AO_PA11_PA12_RMP	1 + +#endif /* _AO_PINS_H_ */ diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 5dda1c85..25634ffc 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -35,6 +35,10 @@ __pdata uint8_t ao_config_loaded;  __pdata uint8_t ao_config_dirty;  __xdata uint8_t ao_config_mutex; +#if HAS_FORCE_FREQ +__xdata uint8_t ao_force_freq; +#endif +  #ifndef AO_CONFIG_DEFAULT_APRS_INTERVAL  #define AO_CONFIG_DEFAULT_APRS_INTERVAL	0  #endif diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h index a2f2c6ca..aca669db 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -45,7 +45,7 @@ extern __pdata enum ao_flight_state ao_log_state;  #define AO_LOG_FORMAT_TELEMETRY		3	/* 32 byte ao_telemetry records */  #define AO_LOG_FORMAT_TELESCIENCE	4	/* 32 byte typed telescience records */  #define AO_LOG_FORMAT_TELEMEGA_OLD	5	/* 32 byte typed telemega records */ -#define AO_LOG_FORMAT_EASYMINI		6	/* 16-byte MS5607 baro only, 3.0V supply */ +#define AO_LOG_FORMAT_EASYMINI1		6	/* 16-byte MS5607 baro only, 3.0V supply */  #define AO_LOG_FORMAT_TELEMETRUM	7	/* 16-byte typed telemetrum records */  #define AO_LOG_FORMAT_TELEMINI2		8	/* 16-byte MS5607 baro only, 3.3V supply, cc1111 SoC */  #define AO_LOG_FORMAT_TELEGPS		9	/* 32 byte telegps records */ @@ -53,6 +53,7 @@ extern __pdata enum ao_flight_state ao_log_state;  #define AO_LOG_FORMAT_DETHERM		11	/* 16-byte MS5607 baro only, no ADC */  #define AO_LOG_FORMAT_TELEMINI3		12	/* 16-byte MS5607 baro only, 3.3V supply, stm32f042 SoC */  #define AO_LOG_FORMAT_TELEFIRETWO	13	/* 32-byte test stand data */ +#define AO_LOG_FORMAT_EASYMINI2		14	/* 16-byte MS5607 baro only, 3.3V supply, stm32f042 SoC */  #define AO_LOG_FORMAT_NONE		127	/* No log at all */  extern __code uint8_t ao_log_format; @@ -252,8 +253,8 @@ struct ao_log_mega {  			int16_t		gyro_y;		/* 20 */  			int16_t		gyro_z;		/* 22 */  			int16_t		mag_x;		/* 24 */ -			int16_t		mag_y;		/* 26 */ -			int16_t		mag_z;		/* 28 */ +			int16_t		mag_z;		/* 26 */ +			int16_t		mag_y;		/* 28 */  			int16_t		accel;		/* 30 */  		} sensor;	/* 32 */  		/* AO_LOG_TEMP_VOLT */ @@ -309,9 +310,7 @@ struct ao_log_firetwo {  		/* AO_LOG_FLIGHT */  		struct {  			uint16_t	flight;		/* 4 */ -			uint16_t	idle_pressure;	/* 6 */ -			uint16_t	idle_thrust;	/* 8 */ -		} flight;	/* 16 */ +		} flight;	/* 6 */  		/* AO_LOG_STATE */  		struct {  			uint16_t	state;		/* 4 */ diff --git a/src/kernel/ao_log_firetwo.c b/src/kernel/ao_log_fireone.c index 4b42abe4..1a82673d 100644 --- a/src/kernel/ao_log_firetwo.c +++ b/src/kernel/ao_log_fireone.c @@ -75,8 +75,6 @@ typedef uint8_t check_log_size[1-(256 % sizeof(struct ao_log_firetwo))] ;  void  ao_log(void)  { -	uint16_t ao_idle_pressure = 0;		// write code to capture pre-test values someday -	uint16_t ao_idle_thrust = 0;  	uint16_t ao_flight_state = ao_flight_startup;  	ao_storage_setup(); @@ -89,8 +87,6 @@ ao_log(void)  		log.type = AO_LOG_FLIGHT;  		log.tick = ao_time(); -		log.u.flight.idle_pressure = ao_idle_pressure; -		log.u.flight.idle_thrust = ao_idle_thrust;  		log.u.flight.flight = ao_flight_number;  		ao_log_firetwo(&log); diff --git a/src/kernel/ao_log_mega.c b/src/kernel/ao_log_mega.c index a0212198..b86abe7a 100644 --- a/src/kernel/ao_log_mega.c +++ b/src/kernel/ao_log_mega.c @@ -135,8 +135,8 @@ ao_log(void)  #endif  #if HAS_HMC5883  				log.u.sensor.mag_x = ao_data_ring[ao_log_data_pos].hmc5883.x; -				log.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].hmc5883.y;  				log.u.sensor.mag_z = ao_data_ring[ao_log_data_pos].hmc5883.z; +				log.u.sensor.mag_y = ao_data_ring[ao_log_data_pos].hmc5883.y;  #endif  				log.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);  				ao_log_mega(&log); diff --git a/src/kernel/ao_log_micro.c b/src/kernel/ao_log_micro.c index aa0f5c76..d6f9c5a8 100644 --- a/src/kernel/ao_log_micro.c +++ b/src/kernel/ao_log_micro.c @@ -19,7 +19,12 @@  #include <ao.h>  #include <ao_micropeak.h>  #include <ao_log_micro.h> +#ifndef ao_async_byte  #include <ao_async.h> +#else +#include <ao_serial.h> +#endif +#include <ao_storage.h>  static uint16_t ao_log_offset = STARTING_LOG_OFFSET; diff --git a/src/kernel/ao_log_micro.h b/src/kernel/ao_log_micro.h index ec5cf3ed..f0243028 100644 --- a/src/kernel/ao_log_micro.h +++ b/src/kernel/ao_log_micro.h @@ -23,7 +23,9 @@  #define PA_MIN_OFFSET		4  #define N_SAMPLES_OFFSET	8  #define STARTING_LOG_OFFSET	10 +#ifndef MAX_LOG_OFFSET  #define MAX_LOG_OFFSET		512 +#endif  void  ao_log_micro_save(void); diff --git a/src/kernel/ao_microkalman.c b/src/kernel/ao_microkalman.c index ff543cc4..3cfb87cc 100644 --- a/src/kernel/ao_microkalman.c +++ b/src/kernel/ao_microkalman.c @@ -32,10 +32,32 @@  #include <ao_kalman.h> +#ifndef AO_MK_STEP_96MS +#define AO_MK_STEP_96MS	1 + +#endif + +#if AO_MK_STEP_100MS +#define AO_MK_TIME_STEP	0.1 + +#define AO_K0_10	AO_MK2_BARO_K0_10 +#define AO_K1_10	AO_MK2_BARO_K1_10 +#define AO_K2_10	AO_MK2_BARO_K2_10 +#endif + +#if AO_MK_STEP_96MS +#define AO_MK_TIME_STEP	0.096 + +#define AO_K0_10	AO_MK_BARO_K0_10 +#define AO_K1_10	AO_MK_BARO_K1_10 +#define AO_K2_10	AO_MK_BARO_K2_10 +#endif +  /* Basic time step (96ms) */ -#define AO_MK_STEP	to_fix_v(0.096) +#define AO_MK_STEP	to_fix_v(AO_MK_TIME_STEP) +  /* step ** 2 / 2 */ -#define AO_MK_STEP_2_2	to_fix_v(0.004608) +#define AO_MK_STEP_2_2	to_fix_v(AO_MK_TIME_STEP * AO_MK_TIME_STEP / 2.0)  uint32_t	ao_k_pa;		/* 24.8 fixed point */  int32_t		ao_k_pa_speed;		/* 16.16 fixed point */ @@ -66,9 +88,9 @@ ao_microkalman_correct(void)  	e = pa - from_fix8(ao_k_pa); -	ao_k_pa       += fix16_to_fix8((int32_t) e * AO_MK_BARO_K0_10); -	ao_k_pa_speed += (int32_t) e * AO_MK_BARO_K1_10; -	ao_k_pa_accel += (int32_t) e * AO_MK_BARO_K2_10; +	ao_k_pa       += fix16_to_fix8((int32_t) e * AO_K0_10); +	ao_k_pa_speed += (int32_t) e * AO_K1_10; +	ao_k_pa_accel += (int32_t) e * AO_K2_10;  	ao_pa = from_fix8(ao_k_pa);  	ao_pa_speed = from_fix(ao_k_pa_speed);  	ao_pa_accel = from_fix(ao_k_pa_accel); diff --git a/src/kernel/ao_report_micro.c b/src/kernel/ao_report_micro.c index af68457d..9c7afdc5 100644 --- a/src/kernel/ao_report_micro.c +++ b/src/kernel/ao_report_micro.c @@ -17,6 +17,7 @@   */  #include <ao.h> +#include <ao_report_micro.h>  #define mid(time)	ao_led_for(AO_LED_REPORT, time)  #define pause(time)	ao_delay(time) diff --git a/src/kernel/ao_report_micro.h b/src/kernel/ao_report_micro.h new file mode 100644 index 00000000..bd6c0622 --- /dev/null +++ b/src/kernel/ao_report_micro.h @@ -0,0 +1,21 @@ +/* + * Copyright © 2017 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, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#ifndef _AO_REPORT_MICRO_H_ +#define _AO_REPORT_MICRO_H_ + +void +ao_report_altitude(void); + +#endif /* _AO_REPORT_MICRO_H_ */ diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index fa817824..2ae1e41b 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -160,8 +160,8 @@ ao_send_mega_sensor(void)  #if HAS_HMC5883  	telemetry.mega_sensor.mag_x = packet->hmc5883.x; -	telemetry.mega_sensor.mag_y = packet->hmc5883.y;  	telemetry.mega_sensor.mag_z = packet->hmc5883.z; +	telemetry.mega_sensor.mag_y = packet->hmc5883.y;  #endif  	ao_telemetry_send(); @@ -296,6 +296,10 @@ static __pdata int8_t ao_telemetry_config_max;  static __pdata int8_t ao_telemetry_config_cur;  static __pdata uint16_t ao_telemetry_flight_number; +#ifndef ao_telemetry_battery_convert +#define ao_telemetry_battery_convert(a) (a) +#endif +  static void  ao_send_configuration(void)  { @@ -308,7 +312,7 @@ ao_send_configuration(void)  		telemetry.configuration.config_minor = AO_CONFIG_MINOR;  #if AO_idProduct_NUMBER == 0x25 && HAS_ADC  		/* TeleGPS gets battery voltage instead of apogee delay */ -		telemetry.configuration.apogee_delay = ao_data_ring[ao_data_ring_prev(ao_data_head)].adc.v_batt; +		telemetry.configuration.apogee_delay = ao_telemetry_battery_convert(ao_data_ring[ao_data_ring_prev(ao_data_head)].adc.v_batt);  #else  		telemetry.configuration.apogee_delay = ao_config.apogee_delay;  		telemetry.configuration.main_deploy = ao_config.main_deploy; diff --git a/src/kernel/ao_telemetry.h b/src/kernel/ao_telemetry.h index 45aaeb07..23e3ed7d 100644 --- a/src/kernel/ao_telemetry.h +++ b/src/kernel/ao_telemetry.h @@ -198,8 +198,8 @@ struct ao_telemetry_mega_sensor {  	int16_t		gyro_z;		/* 24 */  	int16_t		mag_x;		/* 26 */ -	int16_t		mag_y;		/* 28 */ -	int16_t		mag_z;		/* 30 */ +	int16_t		mag_z;		/* 28 */ +	int16_t		mag_y;		/* 30 */  	/* 32 */  }; diff --git a/src/kernel/ao_tracker.c b/src/kernel/ao_tracker.c index 4abd309a..46278530 100644 --- a/src/kernel/ao_tracker.c +++ b/src/kernel/ao_tracker.c @@ -164,6 +164,25 @@ ao_tracker(void)  	}  } +#ifdef AO_LED_GPS_LOCK + +static struct ao_task ao_gps_lock_task; + +static void +ao_gps_lock(void) +{ +	for (;;) { +		if ((gps_data.flags & (AO_GPS_VALID|AO_GPS_COURSE_VALID)) == +		    (AO_GPS_VALID|AO_GPS_COURSE_VALID)) +		{ +			ao_led_for(AO_LED_GPS_LOCK, AO_MS_TO_TICKS(20)); +		} +		ao_delay(AO_SEC_TO_TICKS(3)); +	} +} +#endif + +  static uint8_t erasing_current;  void @@ -222,4 +241,7 @@ ao_tracker_init(void)  #endif  	ao_cmd_register(&ao_tracker_cmds[0]);  	ao_add_task(&ao_tracker_task, ao_tracker, "tracker"); +#ifdef AO_LED_GPS_LOCK +	ao_add_task(&ao_gps_lock_task, ao_gps_lock, "gps lock"); +#endif  } diff --git a/src/kernel/ao_usb.h b/src/kernel/ao_usb.h index cdea5178..936d939b 100644 --- a/src/kernel/ao_usb.h +++ b/src/kernel/ao_usb.h @@ -155,6 +155,8 @@ struct ao_usb_line_coding {  	uint8_t		data_bits;  } ; +extern __xdata struct ao_usb_line_coding ao_usb_line_coding; +  extern __pdata uint8_t ao_usb_running;  #endif /* _AO_USB_H_ */ diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index 5c13eb4b..c50e7528 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -477,7 +477,7 @@ ao_usb_ep0_in_start(uint16_t max)  	ao_usb_ep0_flush();  } -static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8}; +struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};  /* Walk through the list of descriptors and find a match   */ diff --git a/src/micropeak-v2.0/.gitignore b/src/micropeak-v2.0/.gitignore new file mode 100644 index 00000000..c2062c34 --- /dev/null +++ b/src/micropeak-v2.0/.gitignore @@ -0,0 +1,3 @@ +ao_product.h +microsplash-v* +microsplash-load diff --git a/src/micropeak-v2.0/Makefile b/src/micropeak-v2.0/Makefile new file mode 100644 index 00000000..32154fa6 --- /dev/null +++ b/src/micropeak-v2.0/Makefile @@ -0,0 +1,100 @@ +# +# Tiny AltOS build +# +# + +include ../stmf0/Makefile.defs + +PUBLISH_DIR=$(HOME)/altusmetrumllc/Binaries +PUBLISH_HEX=$(PUBLISH_DIR)/$(HEX) + +MICRO_SRC=\ +	ao_report_micro.c \ +	ao_log_micro.c \ +	ao_microflight.c \ +	ao_microkalman.c + +ALTOS_SRC = \ +	ao_micropeak.c \ +	ao_spi_stm.c \ +	ao_dma_stm.c \ +	ao_led.c \ +	ao_timer.c \ +	ao_ms5607.c \ +	ao_exti_stm.c \ +	ao_convert_pa.c \ +	ao_romconfig.c \ +	ao_product.c \ +	ao_panic.c \ +	ao_stdio.c \ +	ao_serial_stm.c \ +	ao_usb_stm.c \ +	ao_mutex.c \ +	ao_interrupt.c \ +	ao_cmd.c \ +	ao_task.c \ +	ao_data.c \ +	ao_boot_chain.c \ +	ao_microflight.c \ +	ao_report_micro.c \ +	ao_storage_stm.c \ +	ao_storage.c \ +	ao_log_micro.c \ +	ao_microkalman.c + +INC=\ +	ao.h \ +	ao_pins.h \ +	ao_arch.h \ +	ao_arch_funcs.h \ +	ao_exti.h \ +	ao_ms5607.h \ +	ao_log_micro.h \ +	ao_micropeak.h \ +	altitude-pa.h \ +	stm32f0.h + +IDPRODUCT=0x14 +PRODUCT=MicroPeak-v2.0 +PRODUCT_DEF=-DMICROPEAK + +CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) -g -Os + +PROGNAME=micropeak-v2.0 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) +OBJ=$(SRC:.c=.o) + +all: $(PROG) $(HEX) + +LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stmf0 -Wl,-Tmicropeak.ld -n + +$(PROG): Makefile $(OBJ) micropeak.ld +	$(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +ao_product.h: ao-make-product.5c ../Version +	$(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +ao_product.o: ao_product.c ao_product.h + +distclean:	clean + +clean: +	rm -f *.o *.elf *.ihx +	rm -f ao_product.h + +publish: $(PUBLISH_HEX) + +$(PUBLISH_HEX): $(HEX) +	cp -a $(HEX) $@ + +../altitude-pa.h: make-altitude-pa +	nickle $< > $@ + +install: + +uninstall: + +$(OBJ): ao_product.h $(INC) diff --git a/src/micropeak-v2.0/ao_micropeak.c b/src/micropeak-v2.0/ao_micropeak.c new file mode 100644 index 00000000..1cfa1209 --- /dev/null +++ b/src/micropeak-v2.0/ao_micropeak.c @@ -0,0 +1,278 @@ +/* + * Copyright © 2017 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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_exti.h> +#include <ao_micropeak.h> +#include <ao_report_micro.h> +#include <ao_log_micro.h> +#include <ao_storage.h> + +static struct ao_ms5607_value	value; + +alt_t		ground_alt, max_alt; +alt_t		ao_max_height; + +void +ao_pa_get(void) +{ +	ao_ms5607_sample(&ao_ms5607_current); +	ao_ms5607_convert(&ao_ms5607_current, &value); +	pa = value.pres; +} + +static void +ao_compute_height(void) +{ +	ground_alt = ao_pa_to_altitude(pa_ground); +	max_alt = ao_pa_to_altitude(pa_min); +	ao_max_height = max_alt - ground_alt; +} + +static void +ao_pips(void) +{ +	uint8_t	i; +	for (i = 0; i < 10; i++) { +		ao_led_toggle(AO_LED_REPORT); +		ao_delay(AO_MS_TO_TICKS(80)); +	} +	ao_delay(AO_MS_TO_TICKS(200)); +} + +void +ao_delay_until(uint16_t target) { +	int16_t	delay = target - ao_time(); +	if (delay > 0) { +		ao_sleep_for(ao_delay_until, delay); +	} +} + +static struct ao_task mp_task; + +static void +ao_battery_disable(void) +{ +	/* Disable */ +	if (stm_adc.cr & (1 << STM_ADC_CR_ADEN)) { +		stm_adc.cr |= (1 << STM_ADC_CR_ADDIS); +		while (stm_adc.cr & (1 << STM_ADC_CR_ADDIS)) +			; +	} + +	/* Turn off everything */ +	stm_adc.cr &= ~((1 << STM_ADC_CR_ADCAL) | +			(1 << STM_ADC_CR_ADSTP) | +			(1 << STM_ADC_CR_ADSTART) | +			(1 << STM_ADC_CR_ADEN)); +} + +static void +ao_battery_init(void) +{ +	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_ADCEN); + +	ao_battery_disable(); + +	/* Configure */ +	stm_adc.cfgr1 = ((0 << STM_ADC_CFGR1_AWDCH) |				  /* analog watchdog channel 0 */ +			 (0 << STM_ADC_CFGR1_AWDEN) |				  /* Disable analog watchdog */ +			 (0 << STM_ADC_CFGR1_AWDSGL) |				  /* analog watchdog on all channels */ +			 (0 << STM_ADC_CFGR1_DISCEN) |				  /* Not discontinuous mode. All channels converted with one trigger */ +			 (0 << STM_ADC_CFGR1_AUTOOFF) |				  /* Leave ADC running */ +			 (1 << STM_ADC_CFGR1_WAIT) |				  /* Wait for data to be read before next conversion */ +			 (0 << STM_ADC_CFGR1_CONT) |				  /* only one set of conversions per trigger */ +			 (1 << STM_ADC_CFGR1_OVRMOD) |				  /* overwrite on overrun */ +			 (STM_ADC_CFGR1_EXTEN_DISABLE << STM_ADC_CFGR1_EXTEN) |	  /* SW trigger */ +			 (0 << STM_ADC_CFGR1_ALIGN) |				  /* Align to LSB */ +			 (STM_ADC_CFGR1_RES_12 << STM_ADC_CFGR1_RES) |		  /* 12 bit resolution */ +			 (STM_ADC_CFGR1_SCANDIR_UP << STM_ADC_CFGR1_SCANDIR) |	  /* scan 0 .. n */ +			 (STM_ADC_CFGR1_DMACFG_ONESHOT << STM_ADC_CFGR1_DMACFG) | /* one set of conversions then stop */ +			 (1 << STM_ADC_CFGR1_DMAEN));				  /* enable DMA */ + +	/* Set the clock */ +	stm_adc.cfgr2 = STM_ADC_CFGR2_CKMODE_PCLK_2 << STM_ADC_CFGR2_CKMODE; + +	/* Shortest sample time */ +	stm_adc.smpr = STM_ADC_SMPR_SMP_71_5 << STM_ADC_SMPR_SMP; + +	/* Select Vref */ +	stm_adc.chselr = 1 << 17; + +	stm_adc.ccr = ((0 << STM_ADC_CCR_VBATEN) | +		       (0 << STM_ADC_CCR_TSEN) | +		       (1 << STM_ADC_CCR_VREFEN)); + +	/* Calibrate */ +	stm_adc.cr |= (1 << STM_ADC_CR_ADCAL); +	while ((stm_adc.cr & (1 << STM_ADC_CR_ADCAL)) != 0) +		; + +	/* Enable */ +	stm_adc.cr |= (1 << STM_ADC_CR_ADEN); +	while ((stm_adc.isr & (1 << STM_ADC_ISR_ADRDY)) == 0) +		; + +	/* Clear any stale status bits */ +	stm_adc.isr = 0; + +	/* Turn on syscfg */ +	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SYSCFGCOMPEN); +} + +static void +ao_battery_fini(void) +{ +	/* Disable */ +	ao_battery_disable(); + +	/* Power down */ +	stm_rcc.apb2enr &= ~(1 << STM_RCC_APB2ENR_ADCEN); +} + +static uint16_t +ao_battery_voltage(void) +{ +	uint16_t	vrefint; + +	ao_battery_init(); + +	stm_adc.cr |= (1 << STM_ADC_CR_ADSTART); + +	while ((stm_adc.isr & (1 << STM_ADC_ISR_EOC)) == 0) +		ao_arch_nop(); + +	vrefint = stm_adc.dr; + +	ao_battery_fini(); + +	return 330 * stm_cal.vrefint_cal / vrefint; +} + + +uint8_t	ao_on_battery; + +static void +ao_micropeak(void) +{ +	ao_ms5607_setup(); +	ao_storage_setup(); + +	/* Give the person a second to get their finger out of the way */ +	ao_delay(AO_MS_TO_TICKS(1000)); + +	ao_pips(); + +	ao_log_micro_restore(); +	ao_compute_height(); +	ao_report_altitude(); +	ao_log_micro_dump(); + +#if BOOST_DELAY +	ao_delay(BOOST_DELAY); +#endif + +	ao_microflight(); + +	ao_log_micro_save(); +	ao_compute_height(); +	ao_report_altitude(); + +	ao_sleep(&ao_on_battery); +} + +static void +ao_show_bat(void) +{ +	printf("battery: %u\n", ao_battery_voltage()); +} + +static struct ao_cmds mp_cmd[] = { +	{ ao_show_bat, "b\0Show battery voltage" }, +	{ 0 } +}; + +static void +ao_hsi_init(void) +{ +	uint32_t	cfgr; + +	/* Disable all interrupts */ +	stm_rcc.cir = 0; + +	/* Enable prefetch */ +	stm_flash.acr |= (1 << STM_FLASH_ACR_PRFTBE); + +	/* Enable power interface clock */ +	stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN); + +	/* HCLK to 48MHz -> AHB prescaler = /1 */ +	cfgr = stm_rcc.cfgr; +	cfgr &= ~(STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE); +	cfgr |= (AO_RCC_CFGR_HPRE_DIV << STM_RCC_CFGR_HPRE); +	stm_rcc.cfgr = cfgr; +	while ((stm_rcc.cfgr & (STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE)) != +	       (AO_RCC_CFGR_HPRE_DIV << STM_RCC_CFGR_HPRE)) +		ao_arch_nop(); + +	/* APB Prescaler = AO_APB_PRESCALER */ +	cfgr = stm_rcc.cfgr; +	cfgr &= ~(STM_RCC_CFGR_PPRE_MASK << STM_RCC_CFGR_PPRE); +	cfgr |= (AO_RCC_CFGR_PPRE_DIV << STM_RCC_CFGR_PPRE); +	stm_rcc.cfgr = cfgr; + +	/* Clear reset flags */ +	stm_rcc.csr |= (1 << STM_RCC_CSR_RMVF); +} + +void +main(void) +{ +	if (ao_battery_voltage() < 320) +		ao_on_battery = 1; + +	/* Leave the system running on the HSI if we're on battery */ +	if (!ao_on_battery) +		ao_clock_init(); +	else +		ao_hsi_init(); + +	ao_led_init(LEDS_AVAILABLE); +	ao_task_init(); +	ao_timer_init(); +	ao_serial_init(); +	stm_moder_set(&stm_gpioa, 2, STM_MODER_OUTPUT); + +	ao_dma_init(); +	ao_spi_init(); +	ao_exti_init(); + +	/* Leave USB disabled on battery */ +	if (!ao_on_battery) { +		ao_usb_init(); +		ao_cmd_init(); +	} + +	ao_ms5607_init(); + +	ao_storage_init(); + +	ao_add_task(&mp_task, ao_micropeak, "micropeak"); +	ao_cmd_register(mp_cmd); +	ao_start_scheduler(); +} diff --git a/src/micropeak-v2.0/ao_pins.h b/src/micropeak-v2.0/ao_pins.h new file mode 100644 index 00000000..fa2ed804 --- /dev/null +++ b/src/micropeak-v2.0/ao_pins.h @@ -0,0 +1,145 @@ +/* + * 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. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +extern uint8_t ao_on_battery; + +#define AO_SYSCLK	(ao_on_battery ? STM_HSI_FREQ : 48000000) + +#define LED_PORT_ENABLE	STM_RCC_AHBENR_IOPAEN +#define LED_PORT	(&stm_gpioa) +#define LED_PIN_ORANGE	2 +#define AO_LED_ORANGE	(1 << LED_PIN_ORANGE) +#define AO_LED_REPORT	AO_LED_ORANGE +#define AO_LED_PANIC	AO_LED_ORANGE + +#define LEDS_AVAILABLE	(AO_LED_ORANGE) + +#define AO_POWER_MANAGEMENT	0 + +/* 48MHz clock based on USB */ +#define AO_HSI48	1 +/* Need HSI running to flash */ +#define AO_NEED_HSI	1 + +/* HCLK = 12MHz usb / 2MHz battery */ +#define AO_AHB_PRESCALER	(ao_on_battery ? 16 : 1) +#define AO_RCC_CFGR_HPRE_DIV	(ao_on_battery ? STM_RCC_CFGR_HPRE_DIV_16 : STM_RCC_CFGR_HPRE_DIV_1) + +/* APB = 12MHz usb / 2MHz battery */ +#define AO_APB_PRESCALER	1 +#define AO_RCC_CFGR_PPRE_DIV	STM_RCC_CFGR_PPRE_DIV_1 + +#define HAS_USB			1 +#define AO_PA11_PA12_RMP	1 + +#define PACKET_HAS_SLAVE	0 +#define HAS_SERIAL_1		0 +#define HAS_SERIAL_2		1 +#define USE_SERIAL_2_STDIN	0 +#define USE_SERIAL_2_FLOW	0 +#define USE_SERIAL_2_SW_FLOW	0 +#define SERIAL_2_PA2_PA3	1 +#define SERIAL_2_PA14_PA15	0 +#define USE_SERIAL2_FLOW	0 +#define USE_SERIAL2_SW_FLOW	0 + +#define IS_FLASH_LOADER		0 + +#define HAS_MS5607		1 +#define HAS_MS5611		0 +#define HAS_MS5607_TASK		0 +#define HAS_EEPROM		0 +#define HAS_BEEP		0 + +/* Logging */ +#define LOG_INTERVAL		1 +#define SAMPLE_SLEEP		AO_MS_TO_TICKS(100) +#define BOOST_DELAY		AO_SEC_TO_TICKS(60) +#define AO_LOG_ID		AO_LOG_ID_MICRO_PEAK2 + +/* Kalman filter */ + +#define AO_MK_STEP_100MS	1 +#define AO_MK_STEP_96MS		0 + +/* SPI */ +#define HAS_SPI_1		1 +#define SPI_1_PA5_PA6_PA7	1 +#define SPI_1_PB3_PB4_PB5	0 +#define SPI_1_OSPEEDR		STM_OSPEEDR_MEDIUM + +#define HAS_SPI_2		0 + +/* MS5607 */ +#define HAS_MS5607		1 +#define HAS_MS5611		0 +#define AO_MS5607_PRIVATE_PINS	0 +#define AO_MS5607_CS_PORT	(&stm_gpioa) +#define AO_MS5607_CS_PIN	4 +#define AO_MS5607_CS_MASK	(1 << AO_MS5607_CS_PIN) +#define AO_MS5607_MISO_PORT	(&stm_gpioa) +#define AO_MS5607_MISO_PIN	6 +#define AO_MS5607_MISO_MASK	(1 << AO_MS5607_MISO_PIN) +#define AO_MS5607_SPI_INDEX	AO_SPI_1_PA5_PA6_PA7 + +typedef int32_t alt_t; + +#define AO_ALT_VALUE(x)		((x) * (alt_t) 10) + +#define AO_DATA_RING		32 + +#define HAS_ADC			0 + +static inline void +ao_power_off(void) __attribute((noreturn)); + +static inline void +ao_power_off(void) { +	for (;;) { +	} +} + +extern alt_t ao_max_height; + +void ao_delay_until(uint16_t target); + +#define ao_async_stop() do {					\ +		ao_serial2_drain();				\ +		stm_moder_set(&stm_gpioa, 2, STM_MODER_OUTPUT); \ +	} while (0) + +#define ao_async_start() do {						\ +		stm_moder_set(&stm_gpioa, 2, STM_MODER_ALTERNATE);	\ +		ao_delay(AO_MS_TO_TICKS(100));				\ +	} while (0) + +#define ao_async_byte(b) ao_serial2_putchar((char) (b)) + +#define ao_eeprom_read(pos, ptr, size) ao_storage_read(pos, ptr, size) +#define ao_eeprom_write(pos, ptr, size) ao_storage_write(pos, ptr, size) +#define MAX_LOG_OFFSET	ao_storage_total + +extern uint32_t __flash__[]; +extern uint32_t __flash_end__[]; + +#define AO_BOOT_APPLICATION_BOUND	((uint32_t *) __flash__) +#define USE_STORAGE_CONFIG	0 + +#endif /* _AO_PINS_H_ */ diff --git a/src/micropeak-v2.0/flash-loader/.gitignore b/src/micropeak-v2.0/flash-loader/.gitignore new file mode 100644 index 00000000..43f0aa8d --- /dev/null +++ b/src/micropeak-v2.0/flash-loader/.gitignore @@ -0,0 +1,2 @@ +*.bin +*.elf diff --git a/src/micropeak-v2.0/flash-loader/Makefile b/src/micropeak-v2.0/flash-loader/Makefile new file mode 100644 index 00000000..4e30c1c6 --- /dev/null +++ b/src/micropeak-v2.0/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=micropeak-v2.0 +include $(TOPDIR)/stmf0/Makefile-flash.defs diff --git a/src/micropeak-v2.0/flash-loader/ao_pins.h b/src/micropeak-v2.0/flash-loader/ao_pins.h new file mode 100644 index 00000000..196a8b1d --- /dev/null +++ b/src/micropeak-v2.0/flash-loader/ao_pins.h @@ -0,0 +1,37 @@ +/* + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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_PINS_H_ +#define _AO_PINS_H_ + +#include <ao_flash_stm_pins.h> + +/* LED anode (PA2) to 3.3 for boot mode */ + +#define AO_BOOT_PIN			1 +#define AO_BOOT_APPLICATION_GPIO	stm_gpioa +#define AO_BOOT_APPLICATION_PIN		2 +#define AO_BOOT_APPLICATION_VALUE	0 +#define AO_BOOT_APPLICATION_MODE	AO_EXTI_MODE_PULL_DOWN + +/* USB */ +#define HAS_USB			1 +#define AO_USB_DIRECTIO		0 +#define AO_PA11_PA12_RMP	1 + +#endif /* _AO_PINS_H_ */ diff --git a/src/micropeak-v2.0/micropeak.ld b/src/micropeak-v2.0/micropeak.ld new file mode 100644 index 00000000..77717e16 --- /dev/null +++ b/src/micropeak-v2.0/micropeak.ld @@ -0,0 +1,123 @@ +/* + * Copyright © 2012 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +MEMORY { +	rom (rx) :   ORIGIN = 0x08001000, LENGTH = 20K +	flash(rx) :  ORIGIN = 0x08006000, LENGTH = 8K +	ram (!w) :   ORIGIN = 0x20000000, LENGTH = 6k - 128 +	stack (!w) : ORIGIN = 0x20000000 + 6k - 128, LENGTH = 128 +} + +INCLUDE registers.ld + +EXTERN (stm_interrupt_vector) + +SECTIONS { +	/* +	 * Rom contents +	 */ + +	.interrupt ORIGIN(ram) : AT (ORIGIN(rom)) { +		__interrupt_start__ = .; +		__interrupt_rom__ = ORIGIN(rom); +		*(.interrupt)	/* Interrupt vectors */ +		__interrupt_end__ = .; +	} > ram + +	.text ORIGIN(rom) + 0x100 : { +		__text_start__ = .; + +		/* Ick. What I want is to specify the +		 * addresses of some global constants so +		 * that I can find them across versions +		 * of the application. I can't figure out +		 * how to make gnu ld do that, so instead +		 * we just load the two files that include +		 * these defines in the right order here and +		 * expect things to 'just work'. Don't change +		 * the contents of those files, ok? +		 */ +		ao_romconfig.o(.romconfig*) +		ao_product.o(.romconfig*) + +		*(.text*)	/* Executable code */ +	} > rom + +	.ARM.exidx : { +		*(.ARM.exidx* .gnu.linkonce.armexidx.*) +	} > rom + +	.rodata : { +		*(.rodata*)	/* Constants */ +	} > rom + +	__text_end__ = .; + +	/* Boot data which must live at the start of ram so that +	 * the application and bootloader share the same addresses. +	 * This must be all uninitialized data +	 */ +	.boot (NOLOAD) : { +		__boot_start__ = .; +		*(.boot) +		. = ALIGN(4); +		__boot_end__ = .; +	} >ram + +	/* Functions placed in RAM (required for flashing) +	 * +	 * Align to 8 bytes as that's what the ARM likes text +	 * segment alignments to be, and if we don't, then +	 * we end up with a mismatch between the location in +	 * ROM and the desired location in RAM. I don't +	 * entirely understand this, but at least this appears +	 * to work... +	 */ + +	.textram BLOCK(8): { +		__data_start__ = .; +		*(.ramtext) +	} >ram AT>rom + +	/* Data -- relocated to RAM, but written to ROM +	 */ +	.data : { +		*(.data)	/* initialized data */ +		. = ALIGN(4); +		__data_end__ = .; +	} >ram AT>rom + +	.bss : { +		__bss_start__ = .; +		*(.bss) +		*(COMMON) +		. = ALIGN(4); +		__bss_end__ = .; +	} >ram + +	PROVIDE(end = .); + +	PROVIDE(__flash__ = ORIGIN(flash)); +	PROVIDE(__flash_end__ = ORIGIN(flash) + LENGTH(flash)); + +	PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack)); +} + +ENTRY(start); + + diff --git a/src/nucleao-32/Makefile b/src/nucleao-32/Makefile index 69049982..2b9fe14f 100644 --- a/src/nucleao-32/Makefile +++ b/src/nucleao-32/Makefile @@ -60,7 +60,7 @@ IDPRODUCT=0x000a  CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) -Os -g -LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stmf0 -Wl,-Tload.ld +LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stmf0 -Wl,-Tload.ld -n  PROGNAME=nucleo-32  PROG=$(PROGNAME)-$(VERSION).elf diff --git a/src/nucleao-32/ao_lisp_os.h b/src/nucleao-32/ao_lisp_os.h new file mode 100644 index 00000000..1993ac44 --- /dev/null +++ b/src/nucleao-32/ao_lisp_os.h @@ -0,0 +1,62 @@ +/* + * 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_LISP_OS_H_ +#define _AO_LISP_OS_H_ + +#include "ao.h" + +static inline int +ao_lisp_getc() { +	static uint8_t	at_eol; +	int c; + +	if (at_eol) { +		ao_cmd_readline(); +		at_eol = 0; +	} +	c = ao_cmd_lex(); +	if (c == '\n') +		at_eol = 1; +	return c; +} + +static inline void +ao_lisp_os_flush(void) +{ +	flush(); +} + +static inline void +ao_lisp_abort(void) +{ +	ao_panic(1); +} + +static inline void +ao_lisp_os_led(int led) +{ +	ao_led_set(led); +} + +static inline void +ao_lisp_os_delay(int delay) +{ +	ao_delay(AO_MS_TO_TICKS(delay)); +} + +#endif diff --git a/src/nucleao-32/ao_lisp_os_save.c b/src/nucleao-32/ao_lisp_os_save.c new file mode 100644 index 00000000..cd740ccd --- /dev/null +++ b/src/nucleao-32/ao_lisp_os_save.c @@ -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, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#include <ao.h> +#include <ao_lisp.h> +#include <ao_flash.h> + +extern uint8_t	__flash__[] __attribute__((aligned(4))); + +/* saved variables to rebuild the heap + +   ao_lisp_atoms +   ao_lisp_frame_global + */ + +int +ao_lisp_os_save(void) +{ +	int i; + +	for (i = 0; i < AO_LISP_POOL_TOTAL; i += 256) { +		uint32_t	*dst = (uint32_t *) (void *) &__flash__[i]; +		uint32_t	*src = (uint32_t *) (void *) &ao_lisp_pool[i]; + +		ao_flash_page(dst, src); +	} +	return 1; +} + +int +ao_lisp_os_restore_save(struct ao_lisp_os_save *save, int offset) +{ +	memcpy(save, &__flash__[offset], sizeof (struct ao_lisp_os_save)); +	return 1; +} + +int +ao_lisp_os_restore(void) +{ +	memcpy(ao_lisp_pool, __flash__, AO_LISP_POOL_TOTAL); +	return 1; +} diff --git a/src/nucleao-32/load.ld b/src/nucleao-32/load.ld new file mode 100644 index 00000000..02a23a95 --- /dev/null +++ b/src/nucleao-32/load.ld @@ -0,0 +1,108 @@ +/* + * Copyright © 2012 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +MEMORY { +	rom (rx) :   ORIGIN = 0x08001000, LENGTH = 27K +	flash (rx) : ORIGIN = 0x08007c00, LENGTH = 1K +	ram (!w) :   ORIGIN = 0x20000000, LENGTH = 6k - 128 +	stack (!w) : ORIGIN = 0x20000000 + 6k - 128, LENGTH = 128 +} + +INCLUDE registers.ld + +EXTERN (stm_interrupt_vector) + +SECTIONS { +	/* +	 * Rom contents +	 */ + +	.interrupt ORIGIN(ram) : AT (ORIGIN(rom)) { +		__interrupt_start__ = .; +		__interrupt_rom__ = ORIGIN(rom); +		*(.interrupt)	/* Interrupt vectors */ +		__interrupt_end__ = .; +	} > ram + +	.text ORIGIN(rom) + 0x100 : { +		__text_start__ = .; + +		/* Ick. What I want is to specify the +		 * addresses of some global constants so +		 * that I can find them across versions +		 * of the application. I can't figure out +		 * how to make gnu ld do that, so instead +		 * we just load the two files that include +		 * these defines in the right order here and +		 * expect things to 'just work'. Don't change +		 * the contents of those files, ok? +		 */ +		ao_romconfig.o(.romconfig*) +		ao_product.o(.romconfig*) + +		*(.text*)	/* Executable code */ +	} > rom + +	.ARM.exidx : { +		*(.ARM.exidx* .gnu.linkonce.armexidx.*) +	} > rom + +	.rodata : { +		*(.rodata*)	/* Constants */ +	} > rom + +	__text_end__ = .; + +	/* Boot data which must live at the start of ram so that +	 * the application and bootloader share the same addresses. +	 * This must be all uninitialized data +	 */ +	.boot (NOLOAD) : { +		__boot_start__ = .; +		*(.boot) +		. = ALIGN(4); +		__boot_end__ = .; +	} >ram + +	/* Data -- relocated to RAM, but written to ROM +	 */ +	.data : { +		__data_start__ = .; +		*(.data)	/* initialized data */ +		. = ALIGN(4); +		__data_end__ = .; +	} >ram AT>rom + +	.bss : { +		__bss_start__ = .; +		*(.bss) +		*(COMMON) +		. = ALIGN(4); +		__bss_end__ = .; +	} >ram + +	PROVIDE(end = .); + +	PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack)); + +	__flash__ = ORIGIN(flash); +} + +ENTRY(start); + + diff --git a/src/product/ao_micropeak.c b/src/product/ao_micropeak.c index f9960eb8..8aac79cd 100644 --- a/src/product/ao_micropeak.c +++ b/src/product/ao_micropeak.c @@ -22,7 +22,6 @@  #include <ao_log_micro.h>  #include <ao_async.h> -static struct ao_ms5607_sample	sample;  static struct ao_ms5607_value	value;  alt_t		ground_alt, max_alt; @@ -31,8 +30,8 @@ alt_t		ao_max_height;  void  ao_pa_get(void)  { -	ao_ms5607_sample(&sample); -	ao_ms5607_convert(&sample, &value); +	ao_ms5607_sample(&ao_ms5607_current); +	ao_ms5607_convert(&ao_ms5607_current, &value);  	pa = value.pres;  } diff --git a/src/product/ao_micropeak.h b/src/product/ao_micropeak.h index 6dc7a465..240eed59 100644 --- a/src/product/ao_micropeak.h +++ b/src/product/ao_micropeak.h @@ -19,7 +19,9 @@  #ifndef _AO_MICROPEAK_H_  #define _AO_MICROPEAK_H_ +#ifndef SAMPLE_SLEEP  #define SAMPLE_SLEEP		AO_MS_TO_TICKS(96) +#endif  /* 64 sample, or about six seconds worth */  #define GROUND_AVG_SHIFT	6 @@ -36,6 +38,7 @@  #define AO_LOG_ID_MICROPEAK	0  #define AO_LOG_ID_MICROKITE	1 +#define AO_LOG_ID_MICROPEAK2	2  #ifndef AO_LOG_ID  #define AO_LOG_ID		AO_LOG_ID_MICROPEAK diff --git a/src/product/ao_telemini.c b/src/product/ao_telemini.c index b192763d..14414a48 100644 --- a/src/product/ao_telemini.c +++ b/src/product/ao_telemini.c @@ -19,8 +19,6 @@  #include "ao.h"  #include "ao_pins.h" -__xdata uint8_t ao_force_freq; -  void  main(void)  { diff --git a/src/stm/ao_serial_stm.c b/src/stm/ao_serial_stm.c index c625471e..ef562313 100644 --- a/src/stm/ao_serial_stm.c +++ b/src/stm/ao_serial_stm.c @@ -195,7 +195,7 @@ ao_usart_set_speed(struct ao_stm_usart *usart, uint8_t speed)  }  static void -ao_usart_init(struct ao_stm_usart *usart) +ao_usart_init(struct ao_stm_usart *usart, int hw_flow)  {  	usart->reg->cr1 = ((0 << STM_USART_CR1_OVER8) |  			  (1 << STM_USART_CR1_UE) | @@ -236,6 +236,10 @@ ao_usart_init(struct ao_stm_usart *usart)  			  (0 << STM_USART_CR3_IREN) |  			  (0 << STM_USART_CR3_EIE)); +	if (hw_flow) +		usart->reg->cr3 |= ((1 << STM_USART_CR3_CTSE) | +				    (1 << STM_USART_CR3_RTSE)); +  	/* Pick a 9600 baud rate */  	ao_usart_set_speed(usart, AO_SERIAL_SPEED_9600);  } @@ -244,8 +248,6 @@ ao_usart_init(struct ao_stm_usart *usart)  static void  ao_usart_set_flow(struct ao_stm_usart *usart)  { -	usart->reg->cr3 |= ((1 << STM_USART_CR3_CTSE) | -			    (1 << STM_USART_CR3_RTSE));  }  #endif @@ -441,7 +443,7 @@ ao_serial_init(void)  	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_USART1EN);  	ao_stm_usart1.reg = &stm_usart1; -	ao_usart_init(&ao_stm_usart1); +	ao_usart_init(&ao_stm_usart1, 0);  	stm_nvic_set_enable(STM_ISR_USART1_POS);  	stm_nvic_set_priority(STM_ISR_USART1_POS, AO_STM_NVIC_MED_PRIORITY); @@ -494,10 +496,7 @@ ao_serial_init(void)  	stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USART2EN);  	ao_stm_usart2.reg = &stm_usart2; -	ao_usart_init(&ao_stm_usart2); -#if USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW -	ao_usart_set_flow(&ao_stm_usart2); -#endif +	ao_usart_init(&ao_stm_usart2, USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW);  	stm_nvic_set_enable(STM_ISR_USART2_POS);  	stm_nvic_set_priority(STM_ISR_USART2_POS, AO_STM_NVIC_MED_PRIORITY); @@ -541,7 +540,7 @@ ao_serial_init(void)  	stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USART3EN);  	ao_stm_usart3.reg = &stm_usart3; -	ao_usart_init(&ao_stm_usart3); +	ao_usart_init(&ao_stm_usart3, 0);  	stm_nvic_set_enable(STM_ISR_USART3_POS);  	stm_nvic_set_priority(STM_ISR_USART3_POS, AO_STM_NVIC_MED_PRIORITY); diff --git a/src/stm/ao_usb_stm.c b/src/stm/ao_usb_stm.c index 33e0617c..595bddac 100644 --- a/src/stm/ao_usb_stm.c +++ b/src/stm/ao_usb_stm.c @@ -598,7 +598,7 @@ ao_usb_ep0_in_start(uint16_t max)  	ao_usb_ep0_flush();  } -static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8}; +struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};  /* Walk through the list of descriptors and find a match   */ diff --git a/src/stmf0/ao_arch.h b/src/stmf0/ao_arch.h index c5f451f5..5c5085d9 100644 --- a/src/stmf0/ao_arch.h +++ b/src/stmf0/ao_arch.h @@ -94,12 +94,17 @@ extern const uint32_t ao_radio_cal;   * For the stm32f042, we want to use the USB-based HSI48 clock   */ -#if AO_HSI48 +#ifndef AO_SYSCLK +#if AO_HSI +#define AO_SYSCLK	STM_HSI_FREQ +#endif +#if AO_HSI48  #define AO_SYSCLK	48000000 -#define AO_HCLK		(AO_SYSCLK / AO_AHB_PRESCALER) -  #endif +#endif + +#define AO_HCLK		(AO_SYSCLK / AO_AHB_PRESCALER)  #if AO_HSE || AO_HSI @@ -150,7 +155,9 @@ ao_adc_init();  #if HAS_BOOT_LOADER  #define AO_BOOT_APPLICATION_BASE	((uint32_t *) 0x08001000) +#ifndef AO_BOOT_APPLICATION_BOUND  #define AO_BOOT_APPLICATION_BOUND	((uint32_t *) (0x08000000 + stm_flash_size())) +#endif  #define AO_BOOT_LOADER_BASE		((uint32_t *) 0x08000000)  #endif diff --git a/src/stmf0/ao_arch_funcs.h b/src/stmf0/ao_arch_funcs.h index c38ce41a..01d51f90 100644 --- a/src/stmf0/ao_arch_funcs.h +++ b/src/stmf0/ao_arch_funcs.h @@ -310,6 +310,27 @@ void  ao_i2c_init(void);  /* ao_serial_stm.c */ + +#if USE_SERIAL_1_FLOW && USE_SERIAL_1_SW_FLOW || USE_SERIAL_2_FLOW && USE_SERIAL_2_SW_FLOW +#define HAS_SERIAL_SW_FLOW	1 +#else +#define HAS_SERIAL_SW_FLOW	0 +#endif + +#if USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW +#define USE_SERIAL_2_HW_FLOW	1 +#endif + +#if USE_SERIAL_1_FLOW && !USE_SERIAL_1_SW_FLOW +#define USE_SERIAL_1_HW_FLOW	1 +#endif + +#if USE_SERIAL_1_HW_FLOW || USE_SERIAL_2_HW_FLOW +#define HAS_SERIAL_HW_FLOW	1 +#else +#define HAS_SERIAL_HW_FLOW	0 +#endif +  struct ao_stm_usart {  	struct ao_fifo		rx_fifo;  	struct ao_fifo		tx_fifo; diff --git a/src/stmf0/ao_beep_stm.c b/src/stmf0/ao_beep_stm.c index 610f4a31..15137230 100644 --- a/src/stmf0/ao_beep_stm.c +++ b/src/stmf0/ao_beep_stm.c @@ -25,6 +25,10 @@  #define BEEPER_TIMER	1  #endif +#ifndef BEEPER_AFR +#define BEEPER_AFR	STM_AFR_AF2 +#endif +  #if BEEPER_TIMER == 1  #define timer stm_tim1  #define STM_RCC_TIMER STM_RCC_APB2ENR_TIM1EN @@ -366,7 +370,7 @@ ao_beep(uint8_t beep)  		timer.egr = (1 << STM_TIM23_EGR_UG);  		/* Hook the timer up to the beeper pin */ -		stm_afr_set(BEEPER_PORT, BEEPER_PIN, STM_AFR_AF2); +		stm_afr_set(BEEPER_PORT, BEEPER_PIN, BEEPER_AFR);  #endif  	}  } diff --git a/src/stmf0/ao_exti.h b/src/stmf0/ao_exti.h index 7452af8e..36c3f7ca 100644 --- a/src/stmf0/ao_exti.h +++ b/src/stmf0/ao_exti.h @@ -21,6 +21,7 @@  #define AO_EXTI_MODE_RISING	1  #define AO_EXTI_MODE_FALLING	2 +#define AO_EXTI_MODE_PULL_NONE	0  #define AO_EXTI_MODE_PULL_UP	4  #define AO_EXTI_MODE_PULL_DOWN	8  #define AO_EXTI_PRIORITY_LOW	16 diff --git a/src/stmf0/ao_serial_stm.c b/src/stmf0/ao_serial_stm.c index 30b0dbd2..59cfde2e 100644 --- a/src/stmf0/ao_serial_stm.c +++ b/src/stmf0/ao_serial_stm.c @@ -163,24 +163,12 @@ ao_usart_drain(struct ao_stm_usart *usart)  	ao_arch_release_interrupts();  } -static const struct { -	uint32_t brr; -} ao_usart_speeds[] = { -	[AO_SERIAL_SPEED_4800] = { -		AO_PCLK / 4800 -	}, -	[AO_SERIAL_SPEED_9600] = { -		AO_PCLK / 9600 -	}, -	[AO_SERIAL_SPEED_19200] = { -		AO_PCLK / 19200 -	}, -	[AO_SERIAL_SPEED_57600] = { -		AO_PCLK / 57600 -	}, -	[AO_SERIAL_SPEED_115200] = { -		AO_PCLK / 115200 -	}, +static const uint32_t ao_usart_speeds[] = { +	[AO_SERIAL_SPEED_4800] = 4800, +	[AO_SERIAL_SPEED_9600] = 9600, +	[AO_SERIAL_SPEED_19200] = 19200, +	[AO_SERIAL_SPEED_57600] = 57600, +	[AO_SERIAL_SPEED_115200] = 115200,  };  static void @@ -188,11 +176,11 @@ ao_usart_set_speed(struct ao_stm_usart *usart, uint8_t speed)  {  	if (speed > AO_SERIAL_SPEED_115200)  		return; -	usart->reg->brr = ao_usart_speeds[speed].brr; +	usart->reg->brr = AO_PCLK / ao_usart_speeds[speed];  }  static void -ao_usart_init(struct ao_stm_usart *usart) +ao_usart_init(struct ao_stm_usart *usart, int hw_flow)  {  	usart->reg->cr1 = ((0 << STM_USART_CR1_M1) |  			   (0 << STM_USART_CR1_EOBIE) | @@ -235,44 +223,39 @@ ao_usart_init(struct ao_stm_usart *usart)  			   (0 << STM_USART_CR2_LBDL) |  			   (0 << STM_USART_CR2_ADDM7)); -	usart->reg->cr3 = ((0 << STM_USART_CR3_WUFIE) | -			   (0 << STM_USART_CR3_WUS) | -			   (0 << STM_USART_CR3_SCARCNT) | -			   (0 << STM_USART_CR3_DEP) | -			   (0 << STM_USART_CR3_DEM) | -			   (0 << STM_USART_CR3_DDRE) | -			   (0 << STM_USART_CR3_OVRDIS) | -			   (0 << STM_USART_CR3_ONEBIT) | -			   (0 << STM_USART_CR3_CTIIE) | -			   (0 << STM_USART_CR3_CTSE) | -			   (0 << STM_USART_CR3_RTSE) | -			   (0 << STM_USART_CR3_DMAT) | -			   (0 << STM_USART_CR3_DMAR) | -			   (0 << STM_USART_CR3_SCEN) | -			   (0 << STM_USART_CR3_NACK) | -			   (0 << STM_USART_CR3_HDSEL) | -			   (0 << STM_USART_CR3_IRLP) | -			   (0 << STM_USART_CR3_IREN) | -			   (0 << STM_USART_CR3_EIE)); - +	uint32_t cr3 = ((0 << STM_USART_CR3_WUFIE) | +			(0 << STM_USART_CR3_WUS) | +			(0 << STM_USART_CR3_SCARCNT) | +			(0 << STM_USART_CR3_DEP) | +			(0 << STM_USART_CR3_DEM) | +			(0 << STM_USART_CR3_DDRE) | +			(0 << STM_USART_CR3_OVRDIS) | +			(0 << STM_USART_CR3_ONEBIT) | +			(0 << STM_USART_CR3_CTIIE) | +			(0 << STM_USART_CR3_CTSE) | +			(0 << STM_USART_CR3_RTSE) | +			(0 << STM_USART_CR3_DMAT) | +			(0 << STM_USART_CR3_DMAR) | +			(0 << STM_USART_CR3_SCEN) | +			(0 << STM_USART_CR3_NACK) | +			(0 << STM_USART_CR3_HDSEL) | +			(0 << STM_USART_CR3_IRLP) | +			(0 << STM_USART_CR3_IREN) | +			(0 << STM_USART_CR3_EIE)); + +	if (hw_flow) +		cr3 |= ((1 << STM_USART_CR3_CTSE) | +			(1 << STM_USART_CR3_RTSE)); + +	usart->reg->cr3 = cr3;  	/* Pick a 9600 baud rate */  	ao_usart_set_speed(usart, AO_SERIAL_SPEED_9600);  	/* Enable the usart */  	usart->reg->cr1 |= (1 << STM_USART_CR1_UE); -  } -#if HAS_SERIAL_HW_FLOW -static void -ao_usart_set_flow(struct ao_stm_usart *usart) -{ -	usart->reg->cr3 |= ((1 << STM_USART_CR3_CTSE) | -			    (1 << STM_USART_CR3_RTSE)); -} -#endif -  #if HAS_SERIAL_1  struct ao_stm_usart ao_stm_usart1; @@ -360,7 +343,7 @@ ao_serial2_set_speed(uint8_t speed)  	ao_usart_set_speed(&ao_stm_usart2, speed);  } -#if HAS_SERIAL_SW_FLOW +#if USE_SERIAL_2_FLOW && USE_SERIAL_2_SW_FLOW  void  ao_serial2_cts(void)  { @@ -403,13 +386,13 @@ ao_serial_init(void)  	 */  #if SERIAL_1_PA9_PA10 -	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPAEN); +	ao_enable_port(&stm_gpioa);  	stm_afr_set(&stm_gpioa, 9, STM_AFR_AF1);  	stm_afr_set(&stm_gpioa, 10, STM_AFR_AF1);  #else  #if SERIAL_1_PB6_PB7 -	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPBEN); +	ao_enable_port(&stm_gpiob);  	stm_afr_set(&stm_gpiob, 6, STM_AFR_AF0);  	stm_afr_set(&stm_gpiob, 7, STM_AFR_AF0); @@ -421,7 +404,7 @@ ao_serial_init(void)  	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_USART1EN);  	ao_stm_usart1.reg = &stm_usart1; -	ao_usart_init(&ao_stm_usart1); +	ao_usart_init(&ao_stm_usart1, 0);  	stm_nvic_set_enable(STM_ISR_USART1_POS);  	stm_nvic_set_priority(STM_ISR_USART1_POS, 4); @@ -440,8 +423,7 @@ ao_serial_init(void)  	 */  # if SERIAL_2_PA2_PA3 -	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPAEN); - +	ao_enable_port(&stm_gpioa);  	stm_afr_set(&stm_gpioa, 2, STM_AFR_AF1);  	stm_afr_set(&stm_gpioa, 3, STM_AFR_AF1);  #  if USE_SERIAL_2_FLOW @@ -459,8 +441,7 @@ ao_serial_init(void)  #  endif  # else  #  if SERIAL_2_PA14_PA15 -	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPAEN); - +	ao_enable_port(&stm_gpioa);  	stm_afr_set(&stm_gpioa, 14, STM_AFR_AF1);  	stm_afr_set(&stm_gpioa, 15, STM_AFR_AF1);  #   if USE_SERIAL_2_FLOW @@ -484,10 +465,7 @@ ao_serial_init(void)  	stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USART2EN);  	ao_stm_usart2.reg = &stm_usart2; -	ao_usart_init(&ao_stm_usart2); -# if USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW -	ao_usart_set_flow(&ao_stm_usart2); -# endif +	ao_usart_init(&ao_stm_usart2, USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW);  	stm_nvic_set_enable(STM_ISR_USART2_POS);  	stm_nvic_set_priority(STM_ISR_USART2_POS, 4); diff --git a/src/stmf0/ao_storage_stm.c b/src/stmf0/ao_storage_stm.c new file mode 100644 index 00000000..1a6198a7 --- /dev/null +++ b/src/stmf0/ao_storage_stm.c @@ -0,0 +1,191 @@ +/* + * Copyright © 2017 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, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#include <ao.h> +#include <ao_storage.h> + +uint32_t	ao_storage_block; +ao_pos_t	ao_storage_total; +uint16_t	ao_storage_unit; + +/* Note that the HSI clock must be running for this code to work. + * Also, special care must be taken with the linker to ensure that the + * functions marked 'ramtext' land in ram and not rom. An example of that + * can be found in altos-loader.ld + */ + +static uint8_t +ao_flash_is_locked(void) +{ +	return (stm_flash.cr & (1 << STM_FLASH_CR_LOCK)) != 0; +} + +static void +ao_flash_unlock(void) +{ +	if (!ao_flash_is_locked()) +		return; + +	/* Unlock FLASH_CR register */ +	stm_flash.keyr = STM_FLASH_KEYR_KEY1; +	stm_flash.keyr = STM_FLASH_KEYR_KEY2; +	if (ao_flash_is_locked()) +		ao_panic(AO_PANIC_FLASH); +} + +static void +ao_flash_lock(void) +{ +	stm_flash.cr |= (1 << STM_FLASH_CR_LOCK); +} + +static uint32_t +stm_flash_page_size(void) +{ +	uint16_t	dev_id = stm_dev_id(); + +	switch (dev_id) { +	case 0x440:	/* stm32f05x */ +	case 0x444:	/* stm32f03x */ +	case 0x445:	/* stm32f04x */ +		return 1024; +	case 0x442:	/* stm32f09x */ +	case 0x448:	/* stm32f07x */ +		return 2048; +	} +	ao_panic(AO_PANIC_FLASH); +	return 0; +} + +#define ao_flash_wait_bsy() do { while (stm_flash.sr & (1 << STM_FLASH_SR_BSY)); } while (0) + +static void __attribute__ ((section(".ramtext"),noinline)) +_ao_flash_erase_page(uint16_t *page) +{ +	stm_flash.cr |= (1 << STM_FLASH_CR_PER); + +	stm_flash.ar = (uintptr_t) page; + +	stm_flash.cr |= (1 << STM_FLASH_CR_STRT); + +	ao_flash_wait_bsy(); + +	stm_flash.cr &= ~(1 << STM_FLASH_CR_PER); +} + +#define _ao_flash_addr(pos)	((uint16_t *) (void *) ((uint8_t *) __flash__ + (pos))) + +static void __attribute ((section(".ramtext"), noinline)) _ao_flash_byte(uint32_t pos, uint8_t b) +{ +	uint16_t	v; +	uint16_t	*a = _ao_flash_addr(pos & ~1); + +	if (pos & 1) +		v = (*a & 0xff) | (b << 8); +	else +		v = (*a & 0xff00) | b; +	*a = v; +	ao_flash_wait_bsy(); +} + +static void __attribute__ ((section(".ramtext"), noinline)) +_ao_flash_write(uint32_t pos, void *sv, uint16_t len) +{ +	uint8_t		*s = sv; +	uint16_t	*f16; +	uint16_t	v; + +	stm_flash.cr |= (1 << STM_FLASH_CR_PG); + +	if (pos & 1) { +		_ao_flash_byte(pos++, *s++); +		len--; +	} +	f16 = _ao_flash_addr(pos); +	while(len > 1) { +		v = s[0] | (s[1] << 8); +		s += 2; +		*f16++ = v; +		ao_flash_wait_bsy(); +		len -= 2; +		pos += 2; +	} +	if (len) +		_ao_flash_byte(pos, *s++); + +	stm_flash.cr &= ~(1 << STM_FLASH_CR_PG); +} + +uint8_t +ao_storage_erase(uint32_t pos) +{ +	ao_arch_block_interrupts(); +	ao_flash_unlock(); + +	_ao_flash_erase_page(_ao_flash_addr(pos)); + +	ao_flash_lock(); +	ao_arch_release_interrupts(); +	return 1; +} + +uint8_t +ao_storage_device_write(uint32_t pos, void *v, uint16_t len) +{ +	if (len == 0) +		return 1; + +	ao_arch_block_interrupts(); +	ao_flash_unlock(); + +	_ao_flash_write(pos, v, len); + +	ao_flash_lock(); +	ao_arch_release_interrupts(); +	return 1; +} + +uint8_t +ao_storage_device_read(uint32_t pos, __xdata void *d, uint16_t len) __reentrant +{ +	if (pos >= ao_storage_total || pos + len > ao_storage_total) +		return 0; +	memcpy(d, _ao_flash_addr(pos), len); +	return 1; +} + +void +ao_storage_flush(void) __reentrant +{ +} + +void +ao_storage_setup(void) +{ +	ao_storage_block = stm_flash_page_size(); +	ao_storage_total = ((uint8_t *) __flash_end__) - ((uint8_t *) __flash__); +	ao_storage_unit = ao_storage_total; +} + +void +ao_storage_device_info(void) __reentrant +{ +	printf ("Using internal flash, page %d bytes, total %d bytes\n", +		ao_storage_block, ao_storage_total); +} + +void +ao_storage_device_init(void) +{ +} diff --git a/src/stmf0/ao_timer.c b/src/stmf0/ao_timer.c index 5c05e4f1..50fd67b8 100644 --- a/src/stmf0/ao_timer.c +++ b/src/stmf0/ao_timer.c @@ -86,6 +86,7 @@ ao_timer_set_adc_interval(uint8_t interval)  void  ao_timer_init(void)  { +	stm_systick.csr = 0;  	stm_systick.rvr = SYSTICK_RELOAD;  	stm_systick.cvr = 0;  	stm_systick.csr = ((1 << STM_SYSTICK_CSR_ENABLE) | diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c index 652b3b6c..59aed3aa 100644 --- a/src/stmf0/ao_usb_stm.c +++ b/src/stmf0/ao_usb_stm.c @@ -655,7 +655,7 @@ ao_usb_ep0_in_start(uint16_t max)  	ao_usb_ep0_flush();  } -static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8}; +struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};  #if AO_USB_DEVICE_ID_SERIAL  static uint8_t ao_usb_serial[2 + 48]; diff --git a/src/stmf0/stm32f0.h b/src/stmf0/stm32f0.h index e53a5dfd..61faf2e4 100644 --- a/src/stmf0/stm32f0.h +++ b/src/stmf0/stm32f0.h @@ -282,8 +282,8 @@ struct stm_rcc {  extern struct stm_rcc stm_rcc; -/* Nominal high speed internal oscillator frequency is 16MHz */ -#define STM_HSI_FREQ		16000000 +/* Nominal high speed internal oscillator frequency is 8MHz */ +#define STM_HSI_FREQ		8000000  #define STM_RCC_CR_PLLRDY	(25)  #define STM_RCC_CR_PLLON	(24) diff --git a/src/telebt-v3.0/Makefile b/src/telebt-v3.0/Makefile index 40d1f6e4..4636c046 100644 --- a/src/telebt-v3.0/Makefile +++ b/src/telebt-v3.0/Makefile @@ -55,6 +55,7 @@ ALTOS_SRC = \  	ao_convert_volt.c \  	ao_packet_master.c \  	ao_packet.c \ +	ao_send_packet.c \  	ao_monitor.c \  	$(PROFILE) \  	$(SAMPLE_PROFILE) \ diff --git a/src/telebt-v3.0/ao_telebt.c b/src/telebt-v3.0/ao_telebt.c index 8775d993..63633c90 100644 --- a/src/telebt-v3.0/ao_telebt.c +++ b/src/telebt-v3.0/ao_telebt.c @@ -23,6 +23,7 @@  #include <ao_profile.h>  #include <ao_btm.h>  #include <ao_lco_cmd.h> +#include <ao_send_packet.h>  #if HAS_SAMPLE_PROFILE  #include <ao_sample_profile.h>  #endif @@ -53,6 +54,7 @@ main(void)  	ao_radio_init();  	ao_packet_master_init();  	ao_monitor_init(); +	ao_send_packet_init();  	ao_config_init(); diff --git a/src/telebt-v4.0/.gitignore b/src/telebt-v4.0/.gitignore new file mode 100644 index 00000000..d1cf2326 --- /dev/null +++ b/src/telebt-v4.0/.gitignore @@ -0,0 +1,4 @@ +ao_product.h +*.bin +*.ihx +*.elf diff --git a/src/telebt-v4.0/Makefile b/src/telebt-v4.0/Makefile new file mode 100644 index 00000000..38ac7513 --- /dev/null +++ b/src/telebt-v4.0/Makefile @@ -0,0 +1,81 @@ +# +# AltOS build +# +# + +include ../stmf0/Makefile.defs + +INC = \ +	ao.h \ +	ao_arch.h \ +	ao_arch_funcs.h \ +	ao_boot.h \ +	ao_pins.h \ +	ao_product.h \ +	ao_cc1200_CC1200.h \ +	ao_task.h \ +	ao_rn4678.h \ +	stm32f0.h \ +	Makefile + +ALTOS_SRC = \ +	ao_boot_chain.c \ +	ao_interrupt.c \ +	ao_product.c \ +	ao_romconfig.c \ +	ao_cmd.c \ +	ao_config.c \ +	ao_data.c \ +	ao_task.c \ +	ao_led.c \ +	ao_stdio.c \ +	ao_panic.c \ +	ao_timer.c \ +	ao_mutex.c \ +	ao_serial_stm.c \ +	ao_rn4678.c \ +	ao_freq.c \ +	ao_dma_stm.c \ +	ao_spi_stm.c \ +	ao_cc1200.c \ +	ao_adc_stm.c \ +	ao_usb_stm.c \ +	ao_exti_stm.c \ +	ao_convert_volt.c \ +	ao_packet_master.c \ +	ao_packet.c \ +	ao_monitor.c \ +	ao_send_packet.c + +PRODUCT=TeleBT-v4.0 +PRODUCT_DEF=-DTELEBT_V_4_0 +IDPRODUCT=0x000e + +CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) -Os -g + +PROGNAME=telebt-v4.0 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) ao_telebt.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) $(HEX) + +$(PROG): Makefile $(OBJ) altos.ld +	$(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +$(OBJ): $(INC) + +ao_product.h: ao-make-product.5c ../Version +	$(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +distclean:	clean + +clean: +	rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx +	rm -f ao_product.h + +install: + +uninstall: diff --git a/src/telebt-v4.0/ao_pins.h b/src/telebt-v4.0/ao_pins.h new file mode 100644 index 00000000..f3d70d1a --- /dev/null +++ b/src/telebt-v4.0/ao_pins.h @@ -0,0 +1,290 @@ +/* + * Copyright © 2017 Bdale Garbee <bdale@gag.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; either version 2 of the License, or + * (at your option) any later version. + * + * 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_PINS_H_ +#define _AO_PINS_H_ + +#define AO_STACK_SIZE		512 + +#define AO_HSE                  32000000 +#define AO_RCC_CFGR_PLLMUL	STM_RCC_CFGR_PLLMUL_3 +#define AO_RCC_CFGR2_PLLDIV	STM_RCC_CFGR2_PREDIV_2 +#define AO_PLLMUL		3 +#define AO_PLLDIV		2 + +/* HCLK = 48MHz */ +#define AO_AHB_PRESCALER        1 +#define AO_RCC_CFGR_HPRE_DIV    STM_RCC_CFGR_HPRE_DIV_1 + +/* APB = 48MHz */ +#define AO_APB_PRESCALER        1 +#define AO_RCC_CFGR_PPRE_DIV    STM_RCC_CFGR_PPRE_DIV_1 + +#define HAS_USB			1 +#define AO_USB_DIRECTIO		0 +#define AO_PA11_PA12_RMP	0 + +#define IS_FLASH_LOADER 	0 +#define HAS_TASK_QUEUE		1 + +/* + * Serial ports + */ +#define HAS_SERIAL_1		0 +#define USE_SERIAL_1_STDIN	0 +#define SERIAL_1_PB6_PB7	0 +#define SERIAL_1_PA9_PA10	0 + +#define HAS_SERIAL_2		1 +#define USE_SERIAL_2_STDIN	1 +#define DELAY_SERIAL_2_STDIN	1 +#define USE_SERIAL_2_FLOW	1 +#define USE_SERIAL_2_SW_FLOW	0 +#define SERIAL_2_PA2_PA3	1 +#define SERIAL_2_PD5_PD6	0 +#define SERIAL_2_PORT_RTS	(&stm_gpioa) +#define SERIAL_2_PIN_RTS	1 +#define SERIAL_2_PORT_CTS	(&stm_gpioa) +#define SERIAL_2_PIN_CTS	0 + +#define AO_CONFIG_MAX_SIZE	1024 + +#define HAS_EEPROM		0 +#define USE_INTERNAL_FLASH	0 +#define USE_EEPROM_CONFIG	0 +#define USE_STORAGE_CONFIG	0 +#define HAS_BEEP		0 +#define HAS_BATTERY_REPORT	0 +#define HAS_RADIO		1 +#define HAS_TELEMETRY		0 +#define HAS_APRS		0 +#define HAS_ACCEL		0 +#define HAS_AES			0 + +#define HAS_SPI_1		1 +#define SPI_1_PA5_PA6_PA7	1	/* CC1200 */ +#define SPI_1_PB3_PB4_PB5	0 +#define SPI_1_PE13_PE14_PE15	0 +#define SPI_1_OSPEEDR		STM_OSPEEDR_HIGH + +#define HAS_SPI_2		0 +#define SPI_2_PB13_PB14_PB15	0 +#define SPI_2_PD1_PD3_PD4	0 +#define SPI_2_OSPEEDR		STM_OSPEEDR_HIGH + +#define HAS_I2C_1		0 +#define I2C_1_PB8_PB9		0 + +#define HAS_I2C_2		0 +#define I2C_2_PB10_PB11		0 + +#define PACKET_HAS_SLAVE	0 +#define PACKET_HAS_MASTER	1 + +#define LOW_LEVEL_DEBUG		0 + +#define LED_PORT_0_ENABLE	STM_RCC_AHBENR_IOPBEN +#define LED_PORT_1_ENABLE	STM_RCC_AHBENR_IOPCEN +#define LED_PORT_0		(&stm_gpiob) +#define LED_PORT_1		(&stm_gpioc) +#define LED_PORT_0_SHIFT	0 +#define LED_PORT_1_SHIFT	0 +#define LED_PIN_RED		(0 + LED_PORT_0_SHIFT) +#define LED_PIN_BLUE		(15 + LED_PORT_1_SHIFT) +#define AO_LED_RED		(1 << LED_PIN_RED) +#define AO_LED_BLUE		(1 << LED_PIN_BLUE) +#define LED_PORT_0_MASK		(AO_LED_RED) +#define LED_PORT_1_MASK		(AO_LED_BLUE) +#define AO_BT_LED		AO_LED_BLUE + +#define LEDS_AVAILABLE		(AO_LED_RED | AO_LED_BLUE) + +#define HAS_GPS			0 +#define HAS_FLIGHT		0 +#define HAS_ADC			1 +#define HAS_ADC_TEMP		0 +#define HAS_LOG			0 + +/* + * ADC + */ +#define AO_DATA_RING		32 +#define AO_ADC_NUM_SENSE	2 + +struct ao_adc { +	int16_t			v_batt; +}; + +#define AO_ADC_DUMP(p) \ +	printf("tick: %5u batt %5d\n", \ +	       (p)->tick, \ +	       (p)->adc.v_batt); + +#define AO_ADC_V_BATT		4 +#define AO_ADC_V_BATT_PORT	(&stm_gpioa) +#define AO_ADC_V_BATT_PIN	4 + +#define AO_ADC_RCC_AHBENR	((1 << STM_RCC_AHBENR_IOPAEN)) + +#define AO_NUM_ADC_PIN		1 + +#define AO_ADC_PIN0_PORT	AO_ADC_V_BATT_PORT +#define AO_ADC_PIN0_PIN		AO_ADC_V_BATT_PIN +#define AO_ADC_PIN0_CH		AO_ADC_V_BATT_PIN + +#define AO_NUM_ADC	       	(AO_NUM_ADC_PIN) + +#define AO_ADC_SQ1		AO_ADC_V_BATT + +/* + * Voltage divider on ADC battery sampler + */ +#define AO_BATTERY_DIV_PLUS	51	/* 5.1k */ +#define AO_BATTERY_DIV_MINUS	100	/* 10k */ + +/* + * ADC reference in decivolts + */ +#define AO_ADC_REFERENCE_DV	33 + +/* + * RN4678 + */ +#define HAS_RN			1 + +#define ao_serial_rn_getchar	ao_serial2_getchar +#define ao_serial_rn_putchar	ao_serial2_putchar +#define _ao_serial_rn_pollchar	_ao_serial2_pollchar +#define _ao_serial_rn_sleep_for	_ao_serial2_sleep_for +#define ao_serial_rn_set_speed ao_serial2_set_speed +#define ao_serial_rn_drain	ao_serial2_drain +#define ao_serial_rn_rx_fifo	(ao_stm_usart2.rx_fifo) + +/* Pin 5. BM70 P2_2 */ +#define AO_RN_SW_BTN_PORT	(&stm_gpioc) +#define AO_RN_SW_BTN_PIN	14 + +/* Pin 9. BM70 P2_3 */ +#define AO_RN_WAKEUP_PORT	(&stm_gpiob) +#define AO_RN_WAKEUP_PIN	9 + +/* Pin 11. BM70 P2_7/tx_ind. Status indication along with P1_5 */ +#define AO_RN_P0_4_PORT		(&stm_gpioc) +#define AO_RN_P0_4_PIN		13 + +/* Pin 12. BM70 P1_1. Status indication along with P0_4 */ +#define AO_RN_P1_5_PORT		(&stm_gpiob) +#define AO_RN_P1_5_PIN		6 + +/* Pin 13. BM70 P1_2. Also I2C SCL */ +#define AO_RN_P1_2_PORT		(&stm_gpiob) +#define AO_RN_P1_2_PIN		7 + +/* Pin 14. BM70 P1_3. Also I2C SDA */ +#define AO_RN_P1_3_PORT		(&stm_gpiob) +#define AO_RN_P1_3_PIN		8 + +/* Pin 15. BM70 P0_0/cts. */ +#define AO_RN_CTS_PORT		(&stm_gpioa) +#define AO_RN_CTS_PIN		1 + +/* Pin 16. BM70 P1_0. */ +#define AO_RN_P0_5_PORT		(&stm_gpiob) +#define AO_RN_P0_5_PIN		5 + +/* Pin 17. BM70 P3_6. */ +#define AO_RN_RTS_PORT		(&stm_gpioa) +#define AO_RN_RTS_PIN		0 + +/* Pin 18. BM70 P2_0. */ +#define AO_RN_P2_0_PORT		(&stm_gpiob) +#define AO_RN_P2_0_PIN		3 + +/* Pin 19. BM70 P2_4. */ +#define AO_RN_P2_4_PORT		(&stm_gpioa) +#define AO_RN_P2_4_PIN		10 + +/* Pin 20. BM70 NC. */ +#define AO_RN_EAN_PORT +#define AO_RN_EAN_PIN + +/* Pin 21. BM70 RST_N. */ +#define AO_RN_RST_N_PORT	(&stm_gpioa) +#define AO_RN_RST_N_PIN		15 + +/* Pin 22. BM70 RXD. */ +#define AO_RN_RXD_PORT		(&stm_gpioa) +#define AO_RN_RXD_PIN		2 + +/* Pin 23. BM70 TXD. */ +#define AO_RN_TXD_PORT		(&stm_gpioa) +#define AO_RN_TXD_PIN		3 + +/* Pin 24. BM70 P3_1/RSSI_IND. */ +#define AO_RN_P3_1_PORT		(&stm_gpiob) +#define AO_RN_P3_1_PIN		2 + +/* Pin 25. BM70 P3_2/LINK_DROP. */ +#define AO_RN_P3_2_PORT		(&stm_gpioa) +#define AO_RN_P3_2_PIN		8 + +/* Pin 26. BM70 P3_3/UART_RX_IND. */ +#define AO_RN_P3_3_PORT		(&stm_gpiob) +#define AO_RN_P3_3_PIN		15 + +/* Pin 27. BM70 P3_4/PAIRING_KEY. */ +#define AO_RN_P3_4_PORT		(&stm_gpiob) +#define AO_RN_P3_4_PIN		14 + +/* Pin 28. BM70 P3_5. */ +#define AO_RN_P3_6_PORT		(&stm_gpiob) +#define AO_RN_P3_6_PIN		13 + +/* Pin 29. BM70 P0_7. */ +#define AO_RN_P3_7_PORT		(&stm_gpiob) +#define AO_RN_P3_7_PIN		12 + +/* + * Radio (cc1200) + */ + +/* gets pretty close to 434.550 */ + +#define AO_RADIO_CAL_DEFAULT 	5695485 + +#define AO_FEC_DEBUG		0 +#define AO_CC1200_SPI_CS_PORT	(&stm_gpiob) +#define AO_CC1200_SPI_CS_PIN	11 +#define AO_CC1200_SPI_BUS	AO_SPI_1_PA5_PA6_PA7 +#define AO_CC1200_SPI		stm_spi1 +#define AO_CC1200_SPI_SPEED	AO_SPI_SPEED_6MHz + +#define AO_CC1200_INT_PORT		(&stm_gpiob) +#define AO_CC1200_INT_PIN		(10) + +#define AO_CC1200_INT_GPIO	2 +#define AO_CC1200_INT_GPIO_IOCFG	CC1200_IOCFG2 + +#define HAS_BOOT_RADIO		0 + +/* Monitor bits */ +#define HAS_MONITOR		1 +#define LEGACY_MONITOR		0 +#define AO_MONITOR_LED		AO_LED_RED + +#endif /* _AO_PINS_H_ */ diff --git a/src/telebt-v4.0/ao_telebt.c b/src/telebt-v4.0/ao_telebt.c new file mode 100644 index 00000000..953ec4bc --- /dev/null +++ b/src/telebt-v4.0/ao_telebt.c @@ -0,0 +1,58 @@ +/* + * Copyright © 2015 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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_exti.h> +#include <ao_packet.h> +#include <ao_send_packet.h> +#include <ao_usb.h> +#include <ao_rn4678.h> + +int +main(void) +{ +	ao_clock_init(); + +	ao_task_init(); +	ao_led_init(LEDS_AVAILABLE); +	ao_led_on(LEDS_AVAILABLE); +	ao_timer_init(); + +	ao_spi_init(); +	ao_dma_init(); +	ao_exti_init(); + +	ao_adc_init(); +	ao_cmd_init(); +	ao_send_packet_init(); + +	ao_usb_init(); +	ao_serial_init(); + +	ao_radio_init(); +	ao_packet_master_init(); +	ao_monitor_init(); +	ao_rn4678_init(); + +	ao_config_init(); + +	ao_led_off(LEDS_AVAILABLE); + +	ao_start_scheduler(); +	return 0; +} diff --git a/src/telebt-v4.0/flash-loader/Makefile b/src/telebt-v4.0/flash-loader/Makefile new file mode 100644 index 00000000..1a3c8c49 --- /dev/null +++ b/src/telebt-v4.0/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=telebt-v4.0 +include $(TOPDIR)/stmf0/Makefile-flash.defs diff --git a/src/telebt-v4.0/flash-loader/ao_pins.h b/src/telebt-v4.0/flash-loader/ao_pins.h new file mode 100644 index 00000000..8f4d6f81 --- /dev/null +++ b/src/telebt-v4.0/flash-loader/ao_pins.h @@ -0,0 +1,37 @@ +/* + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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_PINS_H_ +#define _AO_PINS_H_ + +#include <ao_flash_stm_pins.h> + +/* ground U7 pin 30 to force bootload */ + +#define AO_BOOT_PIN			1 +#define AO_BOOT_APPLICATION_GPIO	stm_gpioa +#define AO_BOOT_APPLICATION_PIN		9 +#define AO_BOOT_APPLICATION_VALUE	1 +#define AO_BOOT_APPLICATION_MODE	AO_EXTI_MODE_PULL_UP + +/* USB */ +#define HAS_USB			1 +#define AO_USB_DIRECTIO		0 +#define AO_PA11_PA12_RMP	0 + +#endif /* _AO_PINS_H_ */ diff --git a/src/telefiretwo-v1.0/Makefile b/src/telefireone-v1.0/Makefile index 87d5d477..53f088cb 100644 --- a/src/telefiretwo-v1.0/Makefile +++ b/src/telefireone-v1.0/Makefile @@ -55,18 +55,18 @@ ALTOS_SRC = \  	ao_pad.c \  	ao_radio_cmac_cmd.c \  	ao_log.c \ -	ao_log_firetwo.c +	ao_log_fireone.c  PRODUCT_SRC = \ -	ao_telefiretwo.c +	ao_telefireone.c -PRODUCT=TeleFireTwo-v1.0 -PRODUCT_DEF=-DTELEFIRETWO_V_1_0 +PRODUCT=TeleFireOne-v1.0 +PRODUCT_DEF=-DTELEFIREONE_V_1_0  IDPRODUCT=0x000f  CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) -Os -g -PROGNAME = telefiretwo-v1.0 +PROGNAME = telefireone-v1.0  PROG = $(PROGNAME)-$(VERSION).elf  HEX = $(PROGNAME)-$(VERSION).ihx diff --git a/src/telefiretwo-v1.0/ao_pins.h b/src/telefireone-v1.0/ao_pins.h index b2f5a5ab..d36d9d82 100644 --- a/src/telefiretwo-v1.0/ao_pins.h +++ b/src/telefireone-v1.0/ao_pins.h @@ -34,7 +34,7 @@  #define HAS_EEPROM		1  #define HAS_LOG			1  #define HAS_PAD			1 -#define USE_INTERNAL_FLASH	0 +#define USE_INTERNAL_FLASH	1  #define IGNITE_ON_P0		0  #define PACKET_HAS_MASTER	0  #define PACKET_HAS_SLAVE	0 diff --git a/src/telefiretwo-v1.0/ao_telefiretwo.c b/src/telefireone-v1.0/ao_telefireone.c index 115b3e91..115b3e91 100644 --- a/src/telefiretwo-v1.0/ao_telefiretwo.c +++ b/src/telefireone-v1.0/ao_telefireone.c diff --git a/src/telefiretwo-v1.0/flash-loader/.gitignore b/src/telefireone-v1.0/flash-loader/.gitignore index 65fe7eab..65fe7eab 100644 --- a/src/telefiretwo-v1.0/flash-loader/.gitignore +++ b/src/telefireone-v1.0/flash-loader/.gitignore diff --git a/src/telefiretwo-v1.0/flash-loader/Makefile b/src/telefireone-v1.0/flash-loader/Makefile index d429dcc4..d429dcc4 100644 --- a/src/telefiretwo-v1.0/flash-loader/Makefile +++ b/src/telefireone-v1.0/flash-loader/Makefile diff --git a/src/telefiretwo-v1.0/flash-loader/ao_pins.h b/src/telefireone-v1.0/flash-loader/ao_pins.h index ded45a40..ded45a40 100644 --- a/src/telefiretwo-v1.0/flash-loader/ao_pins.h +++ b/src/telefireone-v1.0/flash-loader/ao_pins.h diff --git a/src/telegps-v2.0/.gitignore b/src/telegps-v2.0/.gitignore new file mode 100644 index 00000000..892c3acc --- /dev/null +++ b/src/telegps-v2.0/.gitignore @@ -0,0 +1,3 @@ +ao_product.h +ao_serial_lpc.h +*.elf diff --git a/src/telegps-v2.0/ao_pins.h b/src/telegps-v2.0/ao_pins.h index c51f0afb..f92564d6 100644 --- a/src/telegps-v2.0/ao_pins.h +++ b/src/telegps-v2.0/ao_pins.h @@ -21,18 +21,23 @@  #define LED_PORT_ENABLE STM_RCC_AHBENR_IOPBEN  #define LED_PORT        (&stm_gpiob) -#define LED_PIN_RED     5 -#define AO_LED_RED      (1 << LED_PIN_RED) +#define LED_PIN_GREEN   5 +#define AO_LED_GREEN    (1 << LED_PIN_GREEN) +#define AO_LED_PANIC	AO_LED_GREEN +#define AO_LED_GPS_LOCK	AO_LED_GREEN -#define LEDS_AVAILABLE  (AO_LED_RED) +#define LEDS_AVAILABLE  (AO_LED_GREEN) + +#define AO_STACK_SIZE		512  #define IS_FLASH_LOADER		0  #define HAS_BEEP 	       0  #define AO_HSE                  32000000  #define AO_RCC_CFGR_PLLMUL      STM_RCC_CFGR_PLLMUL_3 +#define AO_RCC_CFGR2_PLLDIV	STM_RCC_CFGR2_PREDIV_2  #define AO_PLLMUL               3 -#define AO_PLLDIV               1 +#define AO_PLLDIV               2  /* HCLK = 48MHz */  #define AO_AHB_PRESCALER        1 @@ -42,8 +47,6 @@  #define AO_APB_PRESCALER        1  #define AO_RCC_CFGR_PPRE_DIV    STM_RCC_CFGR_PPRE_DIV_1 -#define AO_RCC_CFGR2_PLLDIV	STM_RCC_CFGR2_PREDIV_1 -  #define HAS_USB                         1  #define AO_USB_DIRECTIO                 0  #define AO_PA11_PA12_RMP                1 @@ -53,11 +56,13 @@  /* ADC */  #define HAS_ADC			1 -#define AO_ADC_PIN0_PORT        (&stm_gpioa) -#define AO_ADC_PIN0_PIN         0 -#define AO_ADC_PIN0_CH          0 +#define AO_ADC_PIN0_PORT        (&stm_gpiob) +#define AO_ADC_PIN0_PIN         1 +#define AO_ADC_PIN0_CH          9 + +#define AO_ADC_RCC_AHBENR       ((1 << STM_RCC_AHBENR_IOPBEN)) -#define AO_ADC_RCC_AHBENR       ((1 << STM_RCC_AHBENR_IOPAEN)) +#define ao_telemetry_battery_convert(a)	((a) << 3)  #define AO_NUM_ADC              1 @@ -90,8 +95,6 @@ struct ao_adc {  #define SPI_1_PB3_PB4_PB5       0  #define SPI_1_OSPEEDR           STM_OSPEEDR_HIGH -#define HAS_MS5607              0 -  /* Flash */  #define M25_MAX_CHIPS           1 @@ -99,14 +102,18 @@ struct ao_adc {  #define AO_M25_SPI_CS_MASK      (1 << 0)  #define AO_M25_SPI_BUS          AO_SPI_1_PA5_PA6_PA7 -#define HAS_SERIAL_1		1 +/* Serial */ +#define HAS_SERIAL_1		0  #define SERIAL_1_PB6_PB7	1  #define USE_SERIAL_1_STDIN	0 -#define ao_gps_getchar		ao_serial1_getchar -#define ao_gps_putchar		ao_serial1_putchar -#define ao_gps_set_speed	ao_serial1_set_speed -#define ao_gps_fifo		(ao_usart_rx_fifo) +#define HAS_SERIAL_2	       	1 +#define SERIAL_2_PA2_PA3	1 +#define USE_SERIAL_2_STDIN	0 + +#define ao_gps_getchar		ao_serial2_getchar +#define ao_gps_putchar		ao_serial2_putchar +#define ao_gps_set_speed	ao_serial2_set_speed  #define HAS_EEPROM		1  #define USE_INTERNAL_FLASH	0 @@ -114,7 +121,6 @@ struct ao_adc {  #define HAS_TELEMETRY		1  #define HAS_RDF			1  #define HAS_APRS		1 -#define HAS_RADIO_RECV		0  #define HAS_GPS			1  #define HAS_FLIGHT		0 @@ -143,22 +149,17 @@ struct ao_adc {  #define AO_FEC_DEBUG            0  #define AO_CC1200_SPI_CS_PORT   (&stm_gpioa) -#define AO_CC1200_SPI_CS_PIN    5 +#define AO_CC1200_SPI_CS_PIN    1  #define AO_CC1200_SPI_BUS       AO_SPI_1_PA5_PA6_PA7  #define AO_CC1200_SPI           stm_spi1 -#define AO_CC1200_SPI_SPEED     AO_SPI_SPEED_FAST +#define AO_CC1200_SPI_SPEED     AO_SPI_SPEED_6MHz  #define AO_CC1200_INT_PORT              (&stm_gpioa)  #define AO_CC1200_INT_PIN               4 -#define AO_CC1200_MCU_WAKEUP_PORT       (&stm_gpioa) -#define AO_CC1200_MCU_WAKEUP_PIN        (0)  #define AO_CC1200_INT_GPIO      2  #define AO_CC1200_INT_GPIO_IOCFG        CC1200_IOCFG2 -#define AO_CC1200_MARC_GPIO     3 -#define AO_CC1200_MARC_GPIO_IOCFG       CC1200_IOCFG3 -  #define HAS_BOOT_RADIO          0  #endif /* _AO_PINS_H_ */ diff --git a/src/telegps-v2.0/ao_telegps.c b/src/telegps-v2.0/ao_telegps.c index 7a923d11..998c2008 100644 --- a/src/telegps-v2.0/ao_telegps.c +++ b/src/telegps-v2.0/ao_telegps.c @@ -25,43 +25,35 @@ int  main(void)  {  	ao_clock_init(); +	ao_task_init(); +	ao_cmd_init(); +	ao_config_init(); -#if HAS_STACK_GUARD -	ao_mpu_init(); -#endif +	ao_led_init(LEDS_AVAILABLE); +	ao_led_on(AO_LED_GREEN); -	ao_task_init(); +	/* internal systems */  	ao_timer_init(); - -	ao_spi_init(); +	ao_dma_init();  	ao_exti_init(); -	ao_storage_init(); - +	/* SoC hardware */ +	ao_adc_init();  	ao_serial_init(); - -	ao_cmd_init(); - +	ao_spi_init();  	ao_usb_init(); -	ao_radio_init(); - -#if HAS_ADC -	ao_adc_init(); -#endif +	/* External hardware */ +	ao_storage_init(); +	ao_radio_init();  	ao_gps_init(); -#if HAS_LOG -	ao_log_init(); -#endif - -	ao_tracker_init(); +	/* Services */ +	ao_log_init();  	ao_telemetry_init(); +	ao_tracker_init(); -#if HAS_SAMPLE_PROFILE -	ao_sample_profile_init(); -#endif -	ao_config_init(); +	ao_led_off(AO_LED_GREEN);  	ao_start_scheduler();  	return 0; diff --git a/src/telegps-v2.0/flash-loader/.gitignore b/src/telegps-v2.0/flash-loader/.gitignore new file mode 100644 index 00000000..7bbed045 --- /dev/null +++ b/src/telegps-v2.0/flash-loader/.gitignore @@ -0,0 +1,2 @@ +*.elf +*.bin diff --git a/src/telemini-v2.0/ao_telemini.c b/src/telemini-v2.0/ao_telemini.c index 68bc3dfe..a9ee423c 100644 --- a/src/telemini-v2.0/ao_telemini.c +++ b/src/telemini-v2.0/ao_telemini.c @@ -20,8 +20,6 @@  #include "ao_pins.h"  #include <ao_exti.h> -__xdata uint8_t ao_force_freq; -  void  main(void)  { diff --git a/src/telemini-v3.0/.gitignore b/src/telemini-v3.0/.gitignore new file mode 100644 index 00000000..57946eb5 --- /dev/null +++ b/src/telemini-v3.0/.gitignore @@ -0,0 +1,3 @@ +ao_product.h +*.bin +*.elf diff --git a/src/telemini-v3.0/ao_pins.h b/src/telemini-v3.0/ao_pins.h index 351d28d8..17cff2ae 100644 --- a/src/telemini-v3.0/ao_pins.h +++ b/src/telemini-v3.0/ao_pins.h @@ -1,9 +1,10 @@  /* - * Copyright © 2013 Keith Packard <keithp@keithp.com> + * Copyright © 2017 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. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version.   *   * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -66,6 +67,13 @@  #define HAS_IGNITE_REPORT	1  #define AO_SMALL_ALTITUDE_TABLE	1 +/* Use debug connector clock for recovery mode */ +#define HAS_FORCE_FREQ		1 +#define AO_RECOVERY_PORT	(&stm_gpioa) +#define AO_RECOVERY_PIN		14 +#define AO_RECOVERY_VALUE	0 +#define AO_RECOVERY_MODE	AO_EXTI_MODE_PULL_UP +  /* Beeper is on Tim1 CH3 */  #define BEEPER_CHANNEL		4  #define BEEPER_TIMER		2 diff --git a/src/telemini-v3.0/ao_telemini.c b/src/telemini-v3.0/ao_telemini.c index 82c1acd4..a50268b9 100644 --- a/src/telemini-v3.0/ao_telemini.c +++ b/src/telemini-v3.0/ao_telemini.c @@ -1,9 +1,10 @@  /* - * Copyright © 2011 Keith Packard <keithp@keithp.com> + * Copyright © 2017 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. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version.   *   * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -18,9 +19,26 @@  #include <ao.h>  #include <ao_exti.h> +static void +ao_check_recovery(void) +{ +	int	i; +	ao_enable_input(AO_RECOVERY_PORT, AO_RECOVERY_PIN, AO_RECOVERY_MODE); +	for (i = 0; i < 100; i++) +		ao_arch_nop(); +	if (ao_gpio_get(AO_RECOVERY_PORT, AO_RECOVERY_PIN, AO_RECOVERY) == AO_RECOVERY_VALUE) { +		ao_flight_force_idle = 1; +		ao_force_freq = 1; +	} +	ao_gpio_set_mode(AO_RECOVERY_PORT, AO_RECOVERY_PIN, 0); +	ao_disable_port(AO_RECOVERY_PORT); +} +  void  main(void)  { +	ao_check_recovery(); +  	ao_clock_init();  	ao_task_init();  	ao_timer_init(); diff --git a/src/telemini-v3.0/flash-loader/ao_pins.h b/src/telemini-v3.0/flash-loader/ao_pins.h index fea9a645..c523d413 100644 --- a/src/telemini-v3.0/flash-loader/ao_pins.h +++ b/src/telemini-v3.0/flash-loader/ao_pins.h @@ -21,13 +21,13 @@  #include <ao_flash_stm_pins.h> -/* beeper to 3.3V for boot loader mode */ +/* SWDIO to gnd for boot loader mode */  #define AO_BOOT_PIN			1  #define AO_BOOT_APPLICATION_GPIO	stm_gpioa -#define AO_BOOT_APPLICATION_PIN		3 -#define AO_BOOT_APPLICATION_VALUE	0 -#define AO_BOOT_APPLICATION_MODE	AO_EXTI_MODE_PULL_DOWN +#define AO_BOOT_APPLICATION_PIN		13 +#define AO_BOOT_APPLICATION_VALUE	1 +#define AO_BOOT_APPLICATION_MODE	AO_EXTI_MODE_PULL_UP  /* USB */  #define HAS_USB			1 diff --git a/src/test/.gitignore b/src/test/.gitignore index 9237780b..56f532ef 100644 --- a/src/test/.gitignore +++ b/src/test/.gitignore @@ -18,3 +18,4 @@ ao_flight_test_noisy_accel  ao_flight_test_metrum  ao_micropeak_test  ao_aes_test +ao_lisp_test diff --git a/src/test/Makefile b/src/test/Makefile index a22abe46..a0c2d5fe 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -1,7 +1,7 @@  vpath % ..:../kernel:../drivers:../util:../micropeak:../aes:../product:../lisp  PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_flight_test_mm \ -	ao_flight_test_metrum \ +	ao_flight_test_metrum ao_flight_test_mini \  	ao_gps_test ao_gps_test_skytraq ao_gps_test_ublox ao_convert_test ao_convert_pa_test ao_fec_test \  	ao_aprs_test ao_micropeak_test ao_fat_test ao_aes_test ao_int64_test \  	ao_ms5607_convert_test ao_quaternion_test ao_lisp_test @@ -37,6 +37,9 @@ ao_flight_test_mm: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.  ao_flight_test_metrum: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS)  	cc -DTELEMETRUM_V2=1 $(CFLAGS) -o $@ $< -lm +ao_flight_test_mini: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS) +	cc -DEASYMINI=1 -DHAS_ACCEL=0 $(CFLAGS) -o $@ $< -lm +  ao_gps_test: ao_gps_test.c ao_gps_sirf.c ao_gps_print.c ao_host.h  	cc $(CFLAGS) -o $@ $< diff --git a/src/test/ao_aes_test.c b/src/test/ao_aes_test.c index 4b65df8d..135c6f1a 100644 --- a/src/test/ao_aes_test.c +++ b/src/test/ao_aes_test.c @@ -30,7 +30,7 @@  #include "../aes/ao_aes_tables.c"  #include "../aes/ao_aes.c" -static uint8_t key[16]; +static uint8_t my_key[64];  static uint8_t text[16];  static uint8_t cbc[16]; @@ -41,7 +41,7 @@ main (int argc, char **argv)  	ao_aes_init();  	ao_aes_set_mode(ao_aes_mode_cbc_mac); -	ao_aes_set_key(key); +	ao_aes_set_key(my_key);  	ao_aes_zero_iv();  	ao_aes_run(text, cbc); diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 25ddb48f..d3d39f2a 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -46,7 +46,7 @@  int ao_gps_new; -#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2) +#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2) && !defined(EASYMINI)  #define TELEMETRUM_V1 1  #endif @@ -84,6 +84,18 @@ struct ao_adc {  };  #endif +#if EASYMINI +#define AO_ADC_NUM_SENSE	2 +#define HAS_MS5607		1 +#define HAS_BEEP		1 +#define AO_CONFIG_MAX_SIZE	1024 + +struct ao_adc { +	int16_t			sense_a; +	int16_t			sense_m; +	int16_t			v_batt; +}; +#endif  #if TELEMETRUM_V1  /* @@ -323,7 +335,7 @@ struct ao_cmds {  #define ao_xmemcmp(d,s,c) memcmp(d,s,c)  #define AO_NEED_ALTITUDE_TO_PRES 1 -#if TELEMEGA || TELEMETRUM_V2 +#if TELEMEGA || TELEMETRUM_V2 || EASYMINI  #include "ao_convert_pa.c"  #include <ao_ms5607.h>  struct ao_ms5607_prom	ao_ms5607_prom; @@ -475,7 +487,7 @@ ao_insert(void)  #else  		double	accel = 0.0;  #endif -#if TELEMEGA || TELEMETRUM_V2 +#if TELEMEGA || TELEMETRUM_V2 || EASYMINI  		double	height;  		ao_ms5607_convert(&ao_data_static.ms5607_raw, &ao_data_static.ms5607_cooked); @@ -670,6 +682,19 @@ int32(uint8_t *bytes, int off)  	return (int32_t) uint32(bytes, off);  } +uint32_t +uint24(uint8_t *bytes, int off) +{ +	return (uint32_t) bytes[off] | (((uint32_t) bytes[off+1]) << 8) | +		(((uint32_t) bytes[off+2]) << 16); +} + +int32_t +int24(uint8_t *bytes, int off) +{ +	return (int32_t) uint24(bytes, off); +} +  static int log_format;  void @@ -694,12 +719,14 @@ ao_sleep(void *wchan)  		for (;;) {  			if (ao_records_read > 2 && ao_flight_state == ao_flight_startup)  			{ +  #if TELEMEGA  				ao_data_static.mpu6000 = ao_ground_mpu6000;  #endif  #if TELEMETRUM_V1  				ao_data_static.adc.accel = ao_flight_ground_accel;  #endif +  				ao_insert();  				return;  			} @@ -829,6 +856,72 @@ ao_sleep(void *wchan)  				}  			}  #endif +#if EASYMINI +			if ((log_format == AO_LOG_FORMAT_EASYMINI1 || log_format == AO_LOG_FORMAT_EASYMINI2) && nword == 14 && strlen(words[0]) == 1) { +				int	i; +				struct ao_ms5607_value	value; + +				type = words[0][0]; +				tick = strtoul(words[1], NULL, 16); +//				printf ("%c %04x", type, tick); +				for (i = 2; i < nword; i++) { +					bytes[i - 2] = strtoul(words[i], NULL, 16); +//					printf(" %02x", bytes[i-2]); +				} +//				printf ("\n"); +				switch (type) { +				case 'F': +					ao_flight_started = 1; +					ao_ground_pres = uint32(bytes, 4); +					ao_ground_height = ao_pa_to_altitude(ao_ground_pres); +#if 0 +					printf("ground pres %d height %d\n", ao_ground_pres, ao_ground_height); +					printf("sens %d off %d tcs %d tco %d tref %d tempsens %d crc %d\n", +					       ao_ms5607_prom.sens, +					       ao_ms5607_prom.off, +					       ao_ms5607_prom.tcs, +					       ao_ms5607_prom.tco, +					       ao_ms5607_prom.tref, +					       ao_ms5607_prom.tempsens, +					       ao_ms5607_prom.crc); +#endif +					break; +				case 'A': +					ao_data_static.tick = tick; +					ao_data_static.ms5607_raw.pres = int24(bytes, 0); +					ao_data_static.ms5607_raw.temp = int24(bytes, 3); +#if 0 +					printf("raw pres %d temp %d\n", +					       ao_data_static.ms5607_raw.pres, +					       ao_data_static.ms5607_raw.temp); +#endif +					ao_ms5607_convert(&ao_data_static.ms5607_raw, &value); +//					printf("pres %d height %d\n", value.pres, ao_pa_to_altitude(value.pres)); +					ao_records_read++; +					ao_insert(); +					return; +				} +				continue; +			} else if (nword == 3 && strcmp(words[0], "ms5607") == 0) { +				if (strcmp(words[1], "reserved:") == 0) +					ao_ms5607_prom.reserved = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "sens:") == 0) +					ao_ms5607_prom.sens = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "off:") == 0) +					ao_ms5607_prom.off = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "tcs:") == 0) +					ao_ms5607_prom.tcs = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "tco:") == 0) +					ao_ms5607_prom.tco = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "tref:") == 0) +					ao_ms5607_prom.tref = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "tempsens:") == 0) +					ao_ms5607_prom.tempsens = strtoul(words[2], NULL, 10); +				else if (strcmp(words[1], "crc:") == 0) +					ao_ms5607_prom.crc = strtoul(words[2], NULL, 10); +				continue; +			} +#endif  #if TELEMETRUM_V2  			if (log_format == AO_LOG_FORMAT_TELEMETRUM && nword == 14 && strlen(words[0]) == 1) {  				int	i; @@ -1007,7 +1100,7 @@ ao_sleep(void *wchan)  			if (type != 'F' && !ao_flight_started)  				continue; -#if TELEMEGA || TELEMETRUM_V2 +#if TELEMEGA || TELEMETRUM_V2 || EASYMINI  			(void) a;  			(void) b;  #else diff --git a/src/test/ao_int64_test.c b/src/test/ao_int64_test.c index 07538ee0..d329f67b 100644 --- a/src/test/ao_int64_test.c +++ b/src/test/ao_int64_test.c @@ -34,7 +34,7 @@ int	errors;  		c = ao_cast64(&ao_r);					\  		if (c != r) {						\  			printf ("trial %4d: %lld " #func mod " %lld = %lld (should be %lld)\n", \ -				trial, (int64_t) (a), (int64_t) b, c, r); \ +				trial, (long long) (a), (long long) b, (long long) c, (long long) r); \  			++errors;					\  		}							\  	} while (0) diff --git a/src/util/make-kalman b/src/util/make-kalman index 580a4515..c630e9cb 100644 --- a/src/util/make-kalman +++ b/src/util/make-kalman @@ -40,4 +40,5 @@ nickle kalman.5c -p AO_BARO -c baro -t 0.01 $SIGMA_BARO  nickle kalman.5c -p AO_BARO -c baro -t 0.1 $SIGMA_BARO  nickle kalman.5c -p AO_BARO -c baro -t 1 $SIGMA_BARO -nickle kalman_micro.5c -p AO_MK_BARO -c baro -t 0.096 $SIGMA_MICRO
\ No newline at end of file +nickle kalman_micro.5c -p AO_MK_BARO -c baro -t 0.096 $SIGMA_MICRO +nickle kalman_micro.5c -p AO_MK2_BARO -c baro -t 0.1 $SIGMA_MICRO | 
