diff options
| -rw-r--r-- | src/Makefile | 2 | ||||
| -rw-r--r-- | src/avr/ao_spi_slave.c | 10 | ||||
| -rw-r--r-- | src/core/ao.h | 4 | ||||
| -rw-r--r-- | src/drivers/ao_cc1120.c | 2 | ||||
| -rw-r--r-- | src/megadongle-v0.1/ao_pins.h | 1 | ||||
| -rw-r--r-- | src/megametrum-v0.1/ao_pins.h | 2 | ||||
| -rw-r--r-- | src/stm-demo/ao_pins.h | 1 | ||||
| -rw-r--r-- | src/stm/ao_arch_funcs.h | 4 | ||||
| -rw-r--r-- | src/stm/ao_spi_stm.c | 15 | ||||
| -rw-r--r-- | src/stm/ao_spi_stm_slave.c | 339 | ||||
| -rw-r--r-- | src/telelco-v0.1/ao_pins.h | 7 | ||||
| -rw-r--r-- | src/telescience-v0.2/.gitignore | 2 | ||||
| -rw-r--r-- | src/telescience-v0.2/Makefile | 85 | ||||
| -rw-r--r-- | src/telescience-v0.2/ao_pins.h | 144 | ||||
| -rw-r--r-- | src/telescience-v0.2/ao_telescience.c | 51 | 
15 files changed, 656 insertions, 13 deletions
| diff --git a/src/Makefile b/src/Makefile index 67ad97d1..e4b11039 100644 --- a/src/Makefile +++ b/src/Makefile @@ -23,7 +23,7 @@ SDCCDIRS=\  	telelaunch-v0.1 tidongle test \  	teleterra-v0.2 teleshield-v0.1 \  	telefire-v0.1 \ -	spiradio-v0.1 +	spiradio-v0.1 telescience-v0.2  AVRDIRS=\  	telescience-v0.1 telescience-pwm telepyro-v0.1 micropeak diff --git a/src/avr/ao_spi_slave.c b/src/avr/ao_spi_slave.c index a400b8a0..15e9924d 100644 --- a/src/avr/ao_spi_slave.c +++ b/src/avr/ao_spi_slave.c @@ -18,22 +18,24 @@  #include "ao.h"  uint8_t -ao_spi_slave_recv(uint8_t *buf, uint8_t len) +ao_spi_slave_recv(void *buf, uint16_t len)  { +	uint8_t *b = buf;  	while (len--) {  		while (!(SPSR & (1 << SPIF)))  			if ((PINB & (1 << PINB0)))  				return 0; -		*buf++ = SPDR; +		*b++ = SPDR;  	}  	return 1;  }  void -ao_spi_slave_send(uint8_t *buf, uint8_t len) +ao_spi_slave_send(void *buf, uint16_t len)  { +	uint8_t *b = buf;  	while (len--) { -		SPDR = *buf++; +		SPDR = *b++;  		while (!(SPSR & (1 << SPIF)))  			if ((PINB & (1 << PINB0)))  				return; diff --git a/src/core/ao.h b/src/core/ao.h index df5bbf48..ce0bf5d1 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -299,10 +299,10 @@ ao_altitude_to_pa(alt_t alt);   */  uint8_t -ao_spi_slave_recv(uint8_t *buf, uint8_t len); +ao_spi_slave_recv(void *buf, uint16_t len);  void -ao_spi_slave_send(uint8_t *buf, uint8_t len); +ao_spi_slave_send(void *buf, uint16_t len);  void  ao_spi_slave_init(void); diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 8068740f..53bb5a62 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -38,7 +38,7 @@ extern const uint32_t	ao_radio_cal;  #define FOSC	32000000 -#define ao_radio_select()	ao_spi_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_1MHz) +#define ao_radio_select()	ao_spi_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_4MHz)  #define ao_radio_deselect()	ao_spi_put_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS)  #define ao_radio_spi_send(d,l)	ao_spi_send((d), (l), AO_CC1120_SPI_BUS)  #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1120_SPI_BUS) diff --git a/src/megadongle-v0.1/ao_pins.h b/src/megadongle-v0.1/ao_pins.h index c766a48c..d460a490 100644 --- a/src/megadongle-v0.1/ao_pins.h +++ b/src/megadongle-v0.1/ao_pins.h @@ -78,6 +78,7 @@  #define HAS_SPI_2		1  #define SPI_2_PB13_PB14_PB15	1	/* Flash, Companion */  #define SPI_2_PD1_PD3_PD4	0 +#define SPI_2_OSPEEDR		STM_OSPEEDR_10MHz  #define SPI_2_PORT		(&stm_gpiob)  #define SPI_2_SCK_PIN		13 diff --git a/src/megametrum-v0.1/ao_pins.h b/src/megametrum-v0.1/ao_pins.h index 64da41a9..4c645871 100644 --- a/src/megametrum-v0.1/ao_pins.h +++ b/src/megametrum-v0.1/ao_pins.h @@ -76,10 +76,12 @@  #define SPI_1_PA5_PA6_PA7	1	/* Barometer */  #define SPI_1_PB3_PB4_PB5	0  #define SPI_1_PE13_PE14_PE15	1	/* Accelerometer */ +#define SPI_1_OSPEEDR		STM_OSPEEDR_10MHz  #define HAS_SPI_2		1  #define SPI_2_PB13_PB14_PB15	1	/* Flash, Companion */  #define SPI_2_PD1_PD3_PD4	0 +#define SPI_2_OSPEEDR		STM_OSPEEDR_10MHz  #define SPI_2_PORT		(&stm_gpiob)  #define SPI_2_SCK_PIN		13 diff --git a/src/stm-demo/ao_pins.h b/src/stm-demo/ao_pins.h index c9c7446e..07b4a19d 100644 --- a/src/stm-demo/ao_pins.h +++ b/src/stm-demo/ao_pins.h @@ -60,6 +60,7 @@  #define HAS_SPI_1		1  #define SPI_1_PB3_PB4_PB5	1 +#define SPI_1_OSPEEDR		STM_OSPEEDR_10MHz  #define HAS_SPI_2		0 diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 87bbe73e..d1779307 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -23,7 +23,7 @@  /* PCLK is set to 16MHz (HCLK 32MHz, APB prescaler 2) */ -#define AO_SPI_SPEED_8MHz	STM_SPI_CR1_BR_PCLK_2	/* This doesn't appear to work */ +#define AO_SPI_SPEED_8MHz	STM_SPI_CR1_BR_PCLK_2  #define AO_SPI_SPEED_4MHz	STM_SPI_CR1_BR_PCLK_4  #define AO_SPI_SPEED_2MHz	STM_SPI_CR1_BR_PCLK_8  #define AO_SPI_SPEED_1MHz	STM_SPI_CR1_BR_PCLK_16 @@ -32,7 +32,7 @@  #define AO_SPI_SPEED_125kHz	STM_SPI_CR1_BR_PCLK_128  #define AO_SPI_SPEED_62500Hz	STM_SPI_CR1_BR_PCLK_256 -#define AO_SPI_SPEED_FAST	AO_SPI_SPEED_4MHz +#define AO_SPI_SPEED_FAST	AO_SPI_SPEED_8MHz  /* Companion bus wants something no faster than 200kHz */ diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index 599d7ee0..7b4af964 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -425,12 +425,21 @@ ao_spi_init(void)  #if HAS_SPI_1  # if SPI_1_PA5_PA6_PA7  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); +	stm_ospeedr_set(&stm_gpioa, 5, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpioa, 6, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpioa, 7, SPI_1_OSPEEDR);  # endif  # if SPI_1_PB3_PB4_PB5  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); +	stm_ospeedr_set(&stm_gpiob, 3, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpiob, 4, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpiob, 5, SPI_1_OSPEEDR);  # endif  # if SPI_1_PE13_PE14_PE15  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOEEN); +	stm_ospeedr_set(&stm_gpioe, 13, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpioe, 14, SPI_1_OSPEEDR); +	stm_ospeedr_set(&stm_gpioe, 15, SPI_1_OSPEEDR);  # endif  	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SPI1EN);  	ao_spi_index[0] = AO_SPI_CONFIG_NONE; @@ -440,9 +449,15 @@ ao_spi_init(void)  #if HAS_SPI_2  # if SPI_2_PB13_PB14_PB15  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); +	stm_ospeedr_set(&stm_gpiob, 13, SPI_2_OSPEEDR); +	stm_ospeedr_set(&stm_gpiob, 14, SPI_2_OSPEEDR); +	stm_ospeedr_set(&stm_gpiob, 15, SPI_2_OSPEEDR);  # endif  # if SPI_2_PD1_PD3_PD4  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIODEN); +	stm_ospeedr_set(&stm_gpiod, 1, SPI_2_OSPEEDR); +	stm_ospeedr_set(&stm_gpiod, 3, SPI_2_OSPEEDR); +	stm_ospeedr_set(&stm_gpiod, 4, SPI_2_OSPEEDR);  # endif  	stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_SPI2EN);  	ao_spi_index[1] = AO_SPI_CONFIG_NONE; diff --git a/src/stm/ao_spi_stm_slave.c b/src/stm/ao_spi_stm_slave.c new file mode 100644 index 00000000..98022442 --- /dev/null +++ b/src/stm/ao_spi_stm_slave.c @@ -0,0 +1,339 @@ +/* + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <ao.h> + +struct ao_spi_stm_slave_info { +	uint8_t	miso_dma_index; +	uint8_t mosi_dma_index; +	struct stm_spi *stm_spi; +}; + +static uint8_t		ao_spi_slave_mutex[STM_NUM_SPI]; +static uint8_t		ao_spi_slave_index[STM_NUM_SPI]; + +static const struct ao_spi_stm_slave_info ao_spi_stm_slave_info[STM_NUM_SPI] = { +	{ +		.miso_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI1_RX), +		.mosi_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI1_TX), +		&stm_spi1 +	}, +	{ +		.miso_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI2_RX), +		.mosi_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI2_TX), +		&stm_spi2 +	} +}; + +static uint8_t	spi_dev_null; + +void +ao_spi_slave_send(void *block, uint16_t len) +{ +	struct stm_spi *stm_spi = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].stm_spi; +	uint8_t	mosi_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].mosi_dma_index; +	uint8_t	miso_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].miso_dma_index; + +	/* Set up the transmit DMA to deliver data */ +	ao_dma_set_transfer(mosi_dma_index, +			    &stm_spi->dr, +			    block, +			    len, +			    (0 << STM_DMA_CCR_MEM2MEM) | +			    (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | +			    (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | +			    (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | +			    (1 << STM_DMA_CCR_MINC) | +			    (0 << STM_DMA_CCR_PINC) | +			    (0 << STM_DMA_CCR_CIRC) | +			    (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); + +	/* Clear RXNE */ +	(void) stm_spi->dr; + +	/* Set up the receive DMA -- when this is done, we know the SPI unit +	 * is idle. Without this, we'd have to poll waiting for the BSY bit to +	 * be cleared +	 */ +	ao_dma_set_transfer(miso_dma_index, +			    &stm_spi->dr, +			    &spi_dev_null, +			    len, +			    (0 << STM_DMA_CCR_MEM2MEM) | +			    (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | +			    (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | +			    (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | +			    (0 << STM_DMA_CCR_MINC) | +			    (0 << STM_DMA_CCR_PINC) | +			    (0 << STM_DMA_CCR_CIRC) | +			    (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR)); +	stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | +			(0 << STM_SPI_CR2_RXNEIE) | +			(0 << STM_SPI_CR2_ERRIE) | +			(0 << STM_SPI_CR2_SSOE) | +			(1 << STM_SPI_CR2_TXDMAEN) | +			(1 << STM_SPI_CR2_RXDMAEN)); +	ao_dma_start(miso_dma_index); +	ao_dma_start(mosi_dma_index); +	ao_arch_critical( +		while (!ao_dma_done[miso_dma_index]) +			ao_sleep(&ao_dma_done[miso_dma_index]); +		); +	ao_dma_done_transfer(mosi_dma_index); +	ao_dma_done_transfer(miso_dma_index); +} + + +uint8_t +ao_spi_slave_recv(void *block, uint16_t len) +{ +	struct stm_spi *stm_spi = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].stm_spi; +	uint8_t	mosi_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].mosi_dma_index; +	uint8_t	miso_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].miso_dma_index; + +	/* Set up transmit DMA to make the SPI hardware actually run */ +	ao_dma_set_transfer(mosi_dma_index, +			    &stm_spi->dr, +			    &spi_dev_null, +			    len, +			    (0 << STM_DMA_CCR_MEM2MEM) | +			    (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | +			    (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | +			    (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | +			    (0 << STM_DMA_CCR_MINC) | +			    (0 << STM_DMA_CCR_PINC) | +			    (0 << STM_DMA_CCR_CIRC) | +			    (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); + +	/* Clear RXNE */ +	(void) stm_spi->dr; + +	/* Set up the receive DMA to capture data */ +	ao_dma_set_transfer(miso_dma_index, +			    &stm_spi->dr, +			    block, +			    len, +			    (0 << STM_DMA_CCR_MEM2MEM) | +			    (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | +			    (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | +			    (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | +			    (1 << STM_DMA_CCR_MINC) | +			    (0 << STM_DMA_CCR_PINC) | +			    (0 << STM_DMA_CCR_CIRC) | +			    (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR)); + +	stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | +			(0 << STM_SPI_CR2_RXNEIE) | +			(0 << STM_SPI_CR2_ERRIE) | +			(0 << STM_SPI_CR2_SSOE) | +			(1 << STM_SPI_CR2_TXDMAEN) | +			(1 << STM_SPI_CR2_RXDMAEN)); +	ao_dma_start(miso_dma_index); +	ao_dma_start(mosi_dma_index); + +	/* Wait until the SPI unit is done */ +	ao_arch_critical( +		while (!ao_dma_done[miso_dma_index]) +			ao_sleep(&ao_dma_done[miso_dma_index]); +		); + +	ao_dma_done_transfer(mosi_dma_index); +	ao_dma_done_transfer(miso_dma_index); +} + +static void +ao_spi_slave_disable_index(uint8_t spi_index) +{ +	/* Disable current config +	 */ +	switch (AO_SPI_INDEX(spi_index)) { +	case STM_SPI_INDEX(1): +		switch (spi_index) { +		case AO_SPI_1_PA5_PA6_PA7: +			stm_gpio_set(&stm_gpioa, 5, 1); +			stm_moder_set(&stm_gpioa, 5, STM_MODER_OUTPUT); +			stm_moder_set(&stm_gpioa, 6, STM_MODER_INPUT); +			stm_moder_set(&stm_gpioa, 7, STM_MODER_OUTPUT); +			break; +		case AO_SPI_1_PB3_PB4_PB5: +			stm_gpio_set(&stm_gpiob, 3, 1); +			stm_moder_set(&stm_gpiob, 3, STM_MODER_OUTPUT); +			stm_moder_set(&stm_gpiob, 4, STM_MODER_INPUT); +			stm_moder_set(&stm_gpiob, 5, STM_MODER_OUTPUT); +			break; +		case AO_SPI_1_PE13_PE14_PE15: +			stm_gpio_set(&stm_gpioe, 13, 1); +			stm_moder_set(&stm_gpioe, 13, STM_MODER_OUTPUT); +			stm_moder_set(&stm_gpioe, 14, STM_MODER_INPUT); +			stm_moder_set(&stm_gpioe, 15, STM_MODER_OUTPUT); +			break; +		} +		break; +	case STM_SPI_INDEX(2): +		switch (spi_index) { +		case AO_SPI_2_PB13_PB14_PB15: +			stm_gpio_set(&stm_gpiob, 13, 1); +			stm_moder_set(&stm_gpiob, 13, STM_MODER_OUTPUT); +			stm_moder_set(&stm_gpiob, 14, STM_MODER_INPUT); +			stm_moder_set(&stm_gpiob, 15, STM_MODER_OUTPUT); +			break; +		case AO_SPI_2_PD1_PD3_PD4: +			stm_gpio_set(&stm_gpiod, 1, 1); +			stm_moder_set(&stm_gpiod, 1, STM_MODER_OUTPUT); +			stm_moder_set(&stm_gpiod, 3, STM_MODER_INPUT); +			stm_moder_set(&stm_gpiod, 4, STM_MODER_OUTPUT); +			break; +		} +		break; +	} +} + +static void +ao_spi_slave_enable_index(uint8_t spi_index) +{ +	switch (AO_SPI_INDEX(spi_index)) { +	case STM_SPI_INDEX(1): +		switch (spi_index) { +		case AO_SPI_1_PA5_PA6_PA7: +			stm_afr_set(&stm_gpioa, 5, STM_AFR_AF5); +			stm_afr_set(&stm_gpioa, 6, STM_AFR_AF5); +			stm_afr_set(&stm_gpioa, 7, STM_AFR_AF5); +			break; +		case AO_SPI_1_PB3_PB4_PB5: +			stm_afr_set(&stm_gpiob, 3, STM_AFR_AF5); +			stm_afr_set(&stm_gpiob, 4, STM_AFR_AF5); +			stm_afr_set(&stm_gpiob, 5, STM_AFR_AF5); +			break; +		case AO_SPI_1_PE13_PE14_PE15: +			stm_afr_set(&stm_gpioe, 13, STM_AFR_AF5); +			stm_afr_set(&stm_gpioe, 14, STM_AFR_AF5); +			stm_afr_set(&stm_gpioe, 15, STM_AFR_AF5); +			break; +		} +		break; +	case STM_SPI_INDEX(2): +		switch (spi_index) { +		case AO_SPI_2_PB13_PB14_PB15: +			stm_afr_set(&stm_gpiob, 13, STM_AFR_AF5); +			stm_afr_set(&stm_gpiob, 14, STM_AFR_AF5); +			stm_afr_set(&stm_gpiob, 15, STM_AFR_AF5); +			break; +		case AO_SPI_2_PD1_PD3_PD4: +			stm_afr_set(&stm_gpiod, 1, STM_AFR_AF5); +			stm_afr_set(&stm_gpiod, 3, STM_AFR_AF5); +			stm_afr_set(&stm_gpiod, 4, STM_AFR_AF5); +			break; +		} +		break; +	} +} + +void +ao_spi_slave_get(uint8_t spi_index, uint32_t speed) +{ +	uint8_t		id = AO_SPI_INDEX(spi_index); +	struct stm_spi	*stm_spi = ao_spi_stm_slave_info[id].stm_spi; + +	ao_mutex_get(&ao_spi_slave_mutex[id]); +	stm_spi->cr1 = ((0 << STM_SPI_CR1_BIDIMODE) |			/* Three wire mode */ +			(0 << STM_SPI_CR1_BIDIOE) | +			(0 << STM_SPI_CR1_CRCEN) |			/* CRC disabled */ +			(0 << STM_SPI_CR1_CRCNEXT) | +			(0 << STM_SPI_CR1_DFF) | +			(0 << STM_SPI_CR1_RXONLY) | +			(1 << STM_SPI_CR1_SSM) |        		/* Software SS handling */ +			(1 << STM_SPI_CR1_SSI) |			/*  ... */ +			(0 << STM_SPI_CR1_LSBFIRST) |			/* Big endian */ +			(1 << STM_SPI_CR1_SPE) |			/* Enable SPI unit */ +			(speed << STM_SPI_CR1_BR) |	/* baud rate to pclk/4 */ +			(1 << STM_SPI_CR1_MSTR) | +			(0 << STM_SPI_CR1_CPOL) |			/* Format 0 */ +			(0 << STM_SPI_CR1_CPHA)); +	if (spi_index != ao_spi_slave_index[id]) { +		 +		/* Disable old config +		 */ +		ao_spi_slave_disable_index(ao_spi_slave_index[id]); + +		/* Enable new config +		 */ +		ao_spi_slave_enable_index(spi_index); +		 +		/* Remember current config +		 */ +		ao_spi_slave_index[id] = spi_index; +	} +} + +void +ao_spi_slave_put(uint8_t spi_index) +{ +	uint8_t		id = AO_SPI_INDEX(spi_index); +	struct stm_spi	*stm_spi = ao_spi_stm_slave_info[id].stm_spi; + +	stm_spi->cr1 = 0; +	ao_mutex_put(&ao_spi_slave_mutex[id]); +} + +static void +ao_spi_channel_init(uint8_t spi_index) +{ +	uint8_t		id = AO_SPI_INDEX(spi_index); +	struct stm_spi	*stm_spi = ao_spi_stm_slave_info[id].stm_spi; + +	ao_spi_slave_disable_index(spi_index); + +	stm_spi->cr1 = 0; +	(void) stm_spi->sr; +	stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | +			(0 << STM_SPI_CR2_RXNEIE) | +			(0 << STM_SPI_CR2_ERRIE) | +			(0 << STM_SPI_CR2_SSOE) | +			(0 << STM_SPI_CR2_TXDMAEN) | +			(0 << STM_SPI_CR2_RXDMAEN)); +} + +void +ao_spi_slave_init(void) +{ +#if HAS_SPI_SLAVE_1 +# if SPI_1_PA5_PA6_PA7 +	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); +# endif +# if SPI_1_PB3_PB4_PB5 +	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); +# endif +# if SPI_1_PE13_PE14_PE15 +	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOEEN); +# endif +	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SPI1EN); +	ao_spi_slave_index[0] = AO_SPI_CONFIG_NONE; +	ao_spi_channel_init(0); +#endif + +#if HAS_SPI_SLAVE_2 +# if SPI_2_PB13_PB14_PB15 +	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); +# endif +# if SPI_2_PD1_PD3_PD4 +	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIODEN); +# endif +	stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_SPI2EN); +	ao_spi_slave_index[1] = AO_SPI_CONFIG_NONE; +	ao_spi_channel_init(1); +#endif +} diff --git a/src/telelco-v0.1/ao_pins.h b/src/telelco-v0.1/ao_pins.h index 60cf018f..970f9bd1 100644 --- a/src/telelco-v0.1/ao_pins.h +++ b/src/telelco-v0.1/ao_pins.h @@ -49,18 +49,19 @@  #define HAS_TELEMETRY		0  #define HAS_AES			1 -#define HAS_SPI_1		1 -#define SPI_1_PA5_PA6_PA7	1 +#define HAS_SPI_1		0 +#define SPI_1_PA5_PA6_PA7	0  #define SPI_1_PB3_PB4_PB5	0  #define SPI_1_PE13_PE14_PE15	0 -#define HAS_SPI_2		1 +#define HAS_SPI_2		1	/* CC1111 */  #define SPI_2_PB13_PB14_PB15	1  #define SPI_2_PD1_PD3_PD4	0  #define SPI_2_GPIO		(&stm_gpiob)  #define SPI_2_SCK		13  #define SPI_2_MISO		14  #define SPI_2_MOSI		15 +#define SPI_2_OSPEEDR		STM_OSPEEDR_10MHz  #define HAS_I2C_1		0 diff --git a/src/telescience-v0.2/.gitignore b/src/telescience-v0.2/.gitignore new file mode 100644 index 00000000..cc1f8b73 --- /dev/null +++ b/src/telescience-v0.2/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +telescience-*.elf diff --git a/src/telescience-v0.2/Makefile b/src/telescience-v0.2/Makefile new file mode 100644 index 00000000..fbeeb75c --- /dev/null +++ b/src/telescience-v0.2/Makefile @@ -0,0 +1,85 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs + +INC = \ +	ao.h \ +	ao_arch.h \ +	ao_arch_funcs.h \ +	ao_pins.h \ +	ao_product.h \ +	ao_cc1120_CC1120.h \ +	ao_task.h \ +	ao_whiten.h \ +	stm32l.h \ +	Makefile + +#PROFILE=ao_profile.c +#PROFILE_DEF=-DAO_PROFILE=1 + +#SAMPLE_PROFILE=ao_sample_profile.c \ +#	ao_sample_profile_timer.c +#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1 + +#STACK_GUARD=ao_mpu_stm.c +#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 + +ALTOS_SRC = \ +	ao_interrupt.c \ +	ao_product.c \ +	ao_romconfig.c \ +	ao_cmd.c \ +	ao_config.c \ +	ao_task.c \ +	ao_led.c \ +	ao_stdio.c \ +	ao_panic.c \ +	ao_timer.c \ +	ao_mutex.c \ +	ao_dma_stm.c \ +	ao_spi_stm.c \ +	ao_usb_stm.c \ +	ao_adc_stm.c \ +	ao_data.c \ +	ao_exti_stm.c \ +	ao_storage.c \ +	ao_m25.c \ +	ao_science_slave.c \ +	ao_spi_stm_slave.c \ +	ao_log_telescience.c \ +	ao_log_single.c + +PRODUCT=TeleScience-v0.2 +PRODUCT_DEF=-DTELESCIENCE +IDPRODUCT=0x0011 + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g + +PROGNAME=telescience-v0.2 +PROG=$(PROGNAME)-$(VERSION).elf + +SRC=$(ALTOS_SRC) ao_telescience.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) + +$(PROG): Makefile $(OBJ) altos.ld +	$(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + +$(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 +	rm -f ao_product.h + +install: + +uninstall: diff --git a/src/telescience-v0.2/ao_pins.h b/src/telescience-v0.2/ao_pins.h new file mode 100644 index 00000000..7b974506 --- /dev/null +++ b/src/telescience-v0.2/ao_pins.h @@ -0,0 +1,144 @@ +/* + * 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; 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_ + +#define HAS_TASK_QUEUE		1 + +/* 8MHz High speed external crystal */ +#define AO_HSE			8000000 + +/* PLLVCO = 96MHz (so that USB will work) */ +#define AO_PLLMUL		12 +#define AO_RCC_CFGR_PLLMUL	(STM_RCC_CFGR_PLLMUL_12) + +/* SYSCLK = 32MHz (no need to go faster than CPU) */ +#define AO_PLLDIV		3 +#define AO_RCC_CFGR_PLLDIV	(STM_RCC_CFGR_PLLDIV_3) + +/* HCLK = 32MHz (CPU clock) */ +#define AO_AHB_PRESCALER	1 +#define AO_RCC_CFGR_HPRE_DIV	STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at 16MHz (HCLK/2) */ +#define AO_APB1_PRESCALER	2 +#define AO_RCC_CFGR_PPRE1_DIV	STM_RCC_CFGR_PPRE2_DIV_2 + +/* Run APB2 at 16MHz (HCLK/2) */ +#define AO_APB2_PRESCALER	2 +#define AO_RCC_CFGR_PPRE2_DIV	STM_RCC_CFGR_PPRE2_DIV_2 + +#define HAS_SERIAL_1		0 +#define USE_SERIAL_1_STDIN	0 +#define SERIAL_1_PB6_PB7	0 +#define SERIAL_1_PA9_PA10	1 + +#define HAS_SERIAL_2		0 +#define USE_SERIAL_2_STDIN	0 +#define SERIAL_2_PA2_PA3	0 +#define SERIAL_2_PD5_PD6	0 + +#define HAS_SERIAL_3		0 +#define USE_SERIAL_3_STDIN	0 +#define SERIAL_3_PB10_PB11	0 +#define SERIAL_3_PC10_PC11	1 +#define SERIAL_3_PD8_PD9	0 + +#define HAS_EEPROM		1 +#define USE_INTERNAL_FLASH	0 +#define HAS_USB			1 +#define HAS_BEEP		0 +#define HAS_RADIO		0 +#define HAS_TELEMETRY		0 +#define PACKET_HAS_SLAVE	0 + +#define HAS_SPI_1		0 +#define HAS_SPI_SLAVE_1		1 +#define SPI_1_PA5_PA6_PA7	1	 +#define SPI_1_PB3_PB4_PB5	0 +#define SPI_1_PE13_PE14_PE15	0 +#define SPI_1_OSPEEDR		STM_OSPEEDR_10MHz + +#define HAS_SPI_2		1 +#define SPI_2_PB13_PB14_PB15	1 +#define SPI_2_PD1_PD3_PD4	0 +#define SPI_2_OSPEEDR		STM_OSPEEDR_10MHz + +#define SPI_2_PORT		(&stm_gpiob) +#define SPI_2_SCK_PIN		13 +#define SPI_2_MISO_PIN		14 +#define SPI_2_MOSI_PIN		15 +#define SPI_SLAVE_INDEX		1 + +#define HAS_I2C_1		0 +#define I2C_1_PB8_PB9		0 + +#define HAS_I2C_2		0 +#define I2C_2_PB10_PB11		0 + +#define LOW_LEVEL_DEBUG		0 + +#define LED_PORT_0_ENABLE	STM_RCC_AHBENR_GPIOAEN + +#define LED_PORT_0		(&stm_gpioa) +#define LED_PORT_0_MASK		(0xff) +#define LED_PORT_0_SHIFT	0 +#define LED_PIN_RED		8 +#define LED_PIN_GREEN		9 +#define AO_LED_RED		(1 << LED_PIN_RED) +#define AO_LED_GREEN		(1 << LED_PIN_GREEN) + +#define LEDS_AVAILABLE		(AO_LED_RED | AO_LED_GREEN) + +#define HAS_GPS			0 +#define HAS_FLIGHT		0 +#define HAS_ADC			1 +#define HAS_LOG			1 + +/* + * SPI Flash memory + */ + +#define M25_MAX_CHIPS		1 +#define AO_M25_SPI_CS_PORT	(&stm_gpioa) +#define AO_M25_SPI_CS_MASK	(1 << 3) +#define AO_M25_SPI_BUS		AO_SPI_2_PB13_PB14_PB15 + +/* + * ADC + */ + +#define AO_DATA_RING		32 +#define AO_ADC_NUM		1 + +struct ao_adc { +	int16_t			adc[AO_ADC_NUM]; +}; + +#define AO_ADC_TEMP		16 + +#define AO_ADC_RCC_AHBENR	0 + +#define AO_NUM_ADC_PIN		0 + +#define AO_NUM_ADC	       	1 + +#define AO_ADC_SQ1		AO_ADC_TEMP + + +#endif /* _AO_PINS_H_ */ diff --git a/src/telescience-v0.2/ao_telescience.c b/src/telescience-v0.2/ao_telescience.c new file mode 100644 index 00000000..2fb3186a --- /dev/null +++ b/src/telescience-v0.2/ao_telescience.c @@ -0,0 +1,51 @@ +/* + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <ao.h> +#include <ao_exti.h> +#include <ao_packet.h> +#include <ao_send_packet.h> + +int +main(void) +{ +	ao_clock_init(); +	 +#if HAS_STACK_GUARD +	ao_mpu_init(); +#endif + +	ao_task_init(); +	ao_led_init(LEDS_AVAILABLE); +	ao_led_on(AO_LED_GREEN); +	ao_timer_init(); + +	ao_spi_init(); +	ao_spi_slave_init(); +	ao_dma_init(); +	ao_exti_init(); + +	ao_cmd_init(); + +	ao_usb_init(); +	ao_config_init(); +	 +	ao_storage_init(); + +	ao_start_scheduler(); +	return 0; +} | 
