struct stm_spi *stm_spi;
};
-uint8_t ao_spi_mutex[STM_NUM_SPI];
-uint16_t ao_spi_speed[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] = {
{
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,
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,
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,
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,
}
void
-ao_spi_get(uint8_t spi_index)
+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 */
(1 << STM_SPI_CR1_SSI) | /* ... */
(0 << STM_SPI_CR1_LSBFIRST) | /* Big endian */
(1 << STM_SPI_CR1_SPE) | /* Enable SPI unit */
- (ao_spi_speed[spi_index] << STM_SPI_CR1_BR) | /* baud rate to pclk/4 */
+ (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));
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;
(0 << STM_SPI_CR2_SSOE) |
(0 << STM_SPI_CR2_TXDMAEN) |
(0 << STM_SPI_CR2_RXDMAEN));
- ao_spi_speed[spi_index] = AO_SPI_SPEED_FAST;
}
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