diff options
| author | Keith Packard <keithp@keithp.com> | 2012-08-18 21:21:58 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2012-08-18 21:21:58 -0700 | 
| commit | a1a48aa9ee0bf7fa6720b34c0f544485caea7cac (patch) | |
| tree | bad7328d3b10f26345d7405c7653e3d41bf354c2 | |
| parent | 00abbbb79de67dc95176fe48b23ce3e8614e8d3a (diff) | |
altos: Allow STM SPI bus on multiple pin sets
This allows multiple STM pin groups to be used for each SPI
bus. Useful for the MS5607 sensor which signals conversion complete on
the MISO line.
Signed-off-by: Keith Packard <keithp@keithp.com>
| -rw-r--r-- | src/megametrum-v0.1/ao_pins.h | 16 | ||||
| -rw-r--r-- | src/stm/ao_arch_funcs.h | 27 | ||||
| -rw-r--r-- | src/stm/ao_spi_stm.c | 162 | 
3 files changed, 148 insertions, 57 deletions
| diff --git a/src/megametrum-v0.1/ao_pins.h b/src/megametrum-v0.1/ao_pins.h index 6b0f9832..42715968 100644 --- a/src/megametrum-v0.1/ao_pins.h +++ b/src/megametrum-v0.1/ao_pins.h @@ -69,13 +69,14 @@  #define HAS_TELEMETRY		1  #define HAS_SPI_1		1 -#define SPI_1_PA5_PA6_PA7	1 +#define SPI_1_PA5_PA6_PA7	1	/* Barometer */  #define SPI_1_PB3_PB4_PB5	0 -#define SPI_1_PE13_PE14_PE15	0 +#define SPI_1_PE13_PE14_PE15	1	/* Accelerometer */  #define HAS_SPI_2		1 -#define SPI_2_PB13_PB14_PB15	1 +#define SPI_2_PB13_PB14_PB15	1	/* Flash, Companion */  #define SPI_2_PD1_PD3_PD4	0 +  #define SPI_2_GPIO		(&stm_gpiob)  #define SPI_2_SCK		13  #define SPI_2_MISO		14 @@ -247,13 +248,14 @@ struct ao_adc {   * Pressure sensor settings   */  #define HAS_MS5607		1 +#define AO_MS5607_PRIVATE_PINS	1  #define AO_MS5607_CS_GPIO	(&stm_gpioc)  #define AO_MS5607_CS		4  #define AO_MS5607_CS_MASK	(1 << AO_MS5607_CS)  #define AO_MS5607_MISO_GPIO	(&stm_gpioa)  #define AO_MS5607_MISO		6  #define AO_MS5607_MISO_MASK	(1 << AO_MS5607_MISO) -#define AO_MS5607_SPI_INDEX	(STM_SPI_INDEX(1)) +#define AO_MS5607_SPI_INDEX	AO_SPI_1_PA5_PA6_PA7  /*   * SPI Flash memory @@ -262,7 +264,7 @@ struct ao_adc {  #define M25_MAX_CHIPS		1  #define AO_M25_SPI_CS_PORT	(&stm_gpiod)  #define AO_M25_SPI_CS_MASK	(1 << 3) -#define AO_M25_SPI_BUS		STM_SPI_INDEX(2) +#define AO_M25_SPI_BUS		AO_SPI_2_PB13_PB14_PB15  /*   * Radio (cc1120) @@ -275,7 +277,7 @@ struct ao_adc {  #define AO_FEC_DEBUG		0  #define AO_CC1120_SPI_CS_PORT	(&stm_gpioc)  #define AO_CC1120_SPI_CS_PIN	5 -#define AO_CC1120_SPI_BUS	STM_SPI_INDEX(2) +#define AO_CC1120_SPI_BUS	AO_SPI_2_PB13_PB14_PB15  #define AO_CC1120_INT_PORT	(&stm_gpioc)  #define AO_CC1120_INT_PIN	14 @@ -311,7 +313,7 @@ struct ao_adc {  #define AO_COMPANION_CS_PORT	(&stm_gpiod)  #define AO_COMPANION_CS_PIN	(0) -#define AO_COMPANION_SPI_BUS	STM_SPI_INDEX(2) +#define AO_COMPANION_SPI_BUS	AO_SPI_2_PB13_PB14_PB15  /*   * Monitor diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 3d8ca1f2..d4fbea37 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -20,12 +20,37 @@  /* ao_spi_stm.c   */ -extern uint8_t	ao_spi_mutex[STM_NUM_SPI];  #define AO_SPI_SPEED_FAST	STM_SPI_CR1_BR_PCLK_4  #define AO_SPI_SPEED_1MHz	STM_SPI_CR1_BR_PCLK_16  #define AO_SPI_SPEED_200kHz	STM_SPI_CR1_BR_PCLK_256 +#define AO_SPI_CONFIG_1		0x00 +#define AO_SPI_1_CONFIG_PA5_PA6_PA7	AO_SPI_CONFIG_1 +#define AO_SPI_2_CONFIG_PB13_PB14_PB15	AO_SPI_CONFIG_1 + +#define AO_SPI_CONFIG_2		0x04 +#define AO_SPI_1_CONFIG_PB3_PB4_PB5	AO_SPI_CONFIG_2 +#define AO_SPI_2_CONFIG_PD1_PD3_PD4	AO_SPI_CONFIG_2 + +#define AO_SPI_CONFIG_3		0x08 +#define AO_SPI_1_CONFIG_PE13_PE14_PE15	AO_SPI_CONFIG_3 + +#define AO_SPI_CONFIG_NONE	0x0c + +#define AO_SPI_INDEX_MASK	0x01 +#define AO_SPI_CONFIG_MASK	0x0c + +#define AO_SPI_1_PA5_PA6_PA7	(STM_SPI_INDEX(1) | AO_SPI_1_CONFIG_PA5_PA6_PA7) +#define AO_SPI_1_PB3_PB4_PB5	(STM_SPI_INDEX(1) | AO_SPI_1_CONFIG_PB3_PB4_PB5) +#define AO_SPI_1_PE13_PE14_PE15	(STM_SPI_INDEX(1) | AO_SPI_1_CONFIG_PE13_PE14_PE15) + +#define AO_SPI_2_PB13_PB14_PB15	(STM_SPI_INDEX(2) | AO_SPI_2_CONFIG_PB13_PB14_PB15) +#define AO_SPI_2_PD1_PD3_PD4	(STM_SPI_INDEX(2) | AO_SPI_2_CONFIG_PD1_PD3_PD4) + +#define AO_SPI_INDEX(id)	((id) & AO_SPI_INDEX_MASK) +#define AO_SPI_CONFIG(id)	((id) & AO_SPI_CONFIG_MASK) +  void  ao_spi_get(uint8_t spi_index, uint32_t speed); diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index 547de9e5..ade86a27 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -23,7 +23,8 @@ struct ao_spi_stm_info {  	struct stm_spi *stm_spi;  }; -uint8_t		ao_spi_mutex[STM_NUM_SPI]; +static uint8_t		ao_spi_mutex[STM_NUM_SPI]; +static uint8_t		ao_spi_config[STM_NUM_SPI];  static const struct ao_spi_stm_info ao_spi_stm_info[STM_NUM_SPI] = {  	{ @@ -43,9 +44,9 @@ static uint8_t	spi_dev_null;  void  ao_spi_send(void *block, uint16_t len, uint8_t spi_index)  { -	struct stm_spi *stm_spi = ao_spi_stm_info[spi_index].stm_spi; -	uint8_t	mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index; -	uint8_t	miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index; +	struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; +	uint8_t	mosi_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].mosi_dma_index; +	uint8_t	miso_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].miso_dma_index;  	/* Set up the transmit DMA to deliver data */  	ao_dma_set_transfer(mosi_dma_index, @@ -99,9 +100,9 @@ ao_spi_send(void *block, uint16_t len, uint8_t spi_index)  void  ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index)  { -	struct stm_spi *stm_spi = ao_spi_stm_info[spi_index].stm_spi; -	uint8_t	mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index; -	uint8_t	miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index; +	struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; +	uint8_t	mosi_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].mosi_dma_index; +	uint8_t	miso_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].miso_dma_index;  	/* Set up the transmit DMA to deliver data */  	ao_dma_set_transfer(mosi_dma_index, @@ -155,9 +156,9 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index)  void  ao_spi_recv(void *block, uint16_t len, uint8_t spi_index)  { -	struct stm_spi *stm_spi = ao_spi_stm_info[spi_index].stm_spi; -	uint8_t	mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index; -	uint8_t	miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index; +	struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; +	uint8_t	mosi_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].mosi_dma_index; +	uint8_t	miso_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].miso_dma_index;  	/* Set up transmit DMA to make the SPI hardware actually run */  	ao_dma_set_transfer(mosi_dma_index, @@ -212,9 +213,9 @@ ao_spi_recv(void *block, uint16_t len, uint8_t spi_index)  void  ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t spi_index)  { -	struct stm_spi *stm_spi = ao_spi_stm_info[spi_index].stm_spi; -	uint8_t	mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index; -	uint8_t	miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index; +	struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; +	uint8_t	mosi_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].mosi_dma_index; +	uint8_t	miso_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].miso_dma_index;  	/* Set up transmit DMA to send data */  	ao_dma_set_transfer(mosi_dma_index, @@ -269,9 +270,94 @@ ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t spi_index)  void  ao_spi_get(uint8_t spi_index, uint32_t speed)  { -	struct stm_spi	*stm_spi = ao_spi_stm_info[spi_index].stm_spi; - -	ao_mutex_get(&ao_spi_mutex[spi_index]); +	struct stm_spi	*stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; +	uint8_t		config = AO_SPI_CONFIG(spi_index); + +	ao_mutex_get(&ao_spi_mutex[AO_SPI_INDEX(spi_index)]); +	if (config != ao_spi_config[AO_SPI_INDEX(spi_index)]) { +		 +		/* Disable current config +		 */ +		switch (AO_SPI_INDEX(spi_index)) { +		case STM_SPI_INDEX(1): +			switch (ao_spi_config[AO_SPI_INDEX(spi_index)]) { +			case AO_SPI_1_CONFIG_PA5_PA6_PA7: +				stm_gpio_set(&stm_gpioa, 5, 0); +				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_CONFIG_PB3_PB4_PB5: +				stm_gpio_set(&stm_gpiob, 3, 0); +				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_CONFIG_PE13_PE14_PE15: +				stm_gpio_set(&stm_gpioe, 13, 0); +				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 (ao_spi_config[AO_SPI_INDEX(spi_index)]) { +			case AO_SPI_2_CONFIG_PB13_PB14_PB15: +				stm_gpio_set(&stm_gpiob, 13, 0); +				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_CONFIG_PD1_PD3_PD4: +				stm_gpio_set(&stm_gpiod, 1, 0); +				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; +		} + +		/* Enable new config +		 */ +		switch (AO_SPI_INDEX(spi_index)) { +		case 0: +			switch (AO_SPI_CONFIG(spi_index)) { +			case AO_SPI_1_CONFIG_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_CONFIG_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_CONFIG_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 1: +			switch (AO_SPI_CONFIG(spi_index)) { +			case AO_SPI_2_CONFIG_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_CONFIG_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; +		} +		ao_spi_config[AO_SPI_INDEX(spi_index)] = AO_SPI_CONFIG(spi_index); +	}  	stm_spi->cr1 = ((0 << STM_SPI_CR1_BIDIMODE) |			/* Three wire mode */  			(0 << STM_SPI_CR1_BIDIOE) |  			(0 << STM_SPI_CR1_CRCEN) |			/* CRC disabled */ @@ -291,16 +377,16 @@ ao_spi_get(uint8_t spi_index, uint32_t speed)  void  ao_spi_put(uint8_t spi_index)  { -	struct stm_spi	*stm_spi = ao_spi_stm_info[spi_index].stm_spi; +	struct stm_spi	*stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi;  	stm_spi->cr1 = 0; -	ao_mutex_put(&ao_spi_mutex[spi_index]); +	ao_mutex_put(&ao_spi_mutex[AO_SPI_INDEX(spi_index)]);  }  static void  ao_spi_channel_init(uint8_t spi_index)  { -	struct stm_spi	*stm_spi = ao_spi_stm_info[spi_index].stm_spi; +	struct stm_spi	*stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi;  	stm_spi->cr1 = 0;  	(void) stm_spi->sr; @@ -318,50 +404,28 @@ ao_spi_init(void)  #if HAS_SPI_1  # if SPI_1_PA5_PA6_PA7  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); -	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); -# else -#  if SPI_1_PB3_PB4_PB5 +# endif +# if SPI_1_PB3_PB4_PB5  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); -	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); -#  else -#   if SPI_1_PE13_PE14_PE15 +# endif +# if SPI_1_PE13_PE14_PE15  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOEEN); -	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); -#   else -#    error "No SPI_1 port configuration specified" -#   endif -#  endif  # endif -  	stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SPI1EN); - +	ao_spi_config[0] = AO_SPI_CONFIG_NONE;  	ao_spi_channel_init(0);  #endif  #if HAS_SPI_2  # if SPI_2_PB13_PB14_PB15  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); -	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); -# else -#  if SPI_2_PPD1_PD3_PD4 +# endif +# if SPI_2_PD1_PD3_PD4  	stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIODEN); -	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); -#  else -#   error "No SPI_2 port configuration specified" -#  endif  # endif  	stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_SPI2EN); +	ao_spi_config[1] = AO_SPI_CONFIG_NONE;  	ao_spi_channel_init(1);  #endif | 
