From: Keith Packard Date: Sun, 19 Aug 2012 04:21:58 +0000 (-0700) Subject: altos: Allow STM SPI bus on multiple pin sets X-Git-Tag: 1.1~67^2~32 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=a1a48aa9ee0bf7fa6720b34c0f544485caea7cac;ds=sidebyside 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 --- 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