diff options
Diffstat (limited to 'src/stm/ao_spi_stm.c')
| -rw-r--r-- | src/stm/ao_spi_stm.c | 216 | 
1 files changed, 126 insertions, 90 deletions
diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index ade86a27..56329c24 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -24,7 +24,7 @@ struct ao_spi_stm_info {  };  static uint8_t		ao_spi_mutex[STM_NUM_SPI]; -static uint8_t		ao_spi_config[STM_NUM_SPI]; +static uint8_t		ao_spi_index[STM_NUM_SPI];  static const struct ao_spi_stm_info ao_spi_stm_info[STM_NUM_SPI] = {  	{ @@ -160,6 +160,8 @@ ao_spi_recv(void *block, uint16_t len, uint8_t spi_index)  	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; +	spi_dev_null = 0xff; +  	/* Set up transmit DMA to make the SPI hardware actually run */  	ao_dma_set_transfer(mosi_dma_index,  			    &stm_spi->dr, @@ -267,97 +269,100 @@ ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t spi_index)  	ao_dma_done_transfer(miso_dma_index);  } -void -ao_spi_get(uint8_t spi_index, uint32_t speed) +static void +ao_spi_disable_index(uint8_t 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; -			} +	/* 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; -		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; +	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; +	} +} -		/* 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; -			} +static void +ao_spi_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 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; -			} +		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;  		} -		ao_spi_config[AO_SPI_INDEX(spi_index)] = AO_SPI_CONFIG(spi_index); +		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_get(uint8_t spi_index, uint32_t speed) +{ +	uint8_t		id = AO_SPI_INDEX(spi_index); +	struct stm_spi	*stm_spi = ao_spi_stm_info[id].stm_spi; + +	ao_mutex_get(&ao_spi_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 */ @@ -372,21 +377,39 @@ ao_spi_get(uint8_t spi_index, uint32_t speed)  			(1 << STM_SPI_CR1_MSTR) |  			(0 << STM_SPI_CR1_CPOL) |			/* Format 0 */  			(0 << STM_SPI_CR1_CPHA)); +	if (spi_index != ao_spi_index[id]) { +		 +		/* Disable old config +		 */ +		ao_spi_disable_index(ao_spi_index[id]); + +		/* Enable new config +		 */ +		ao_spi_enable_index(spi_index); +		 +		/* Remember current config +		 */ +		ao_spi_index[id] = spi_index; +	}  }  void  ao_spi_put(uint8_t spi_index)  { -	struct stm_spi	*stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; +	uint8_t		id = AO_SPI_INDEX(spi_index); +	struct stm_spi	*stm_spi = ao_spi_stm_info[id].stm_spi;  	stm_spi->cr1 = 0; -	ao_mutex_put(&ao_spi_mutex[AO_SPI_INDEX(spi_index)]); +	ao_mutex_put(&ao_spi_mutex[id]);  }  static void  ao_spi_channel_init(uint8_t spi_index)  { -	struct stm_spi	*stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; +	uint8_t		id = AO_SPI_INDEX(spi_index); +	struct stm_spi	*stm_spi = ao_spi_stm_info[id].stm_spi; + +	ao_spi_disable_index(spi_index);  	stm_spi->cr1 = 0;  	(void) stm_spi->sr; @@ -404,29 +427,42 @@ 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_config[0] = AO_SPI_CONFIG_NONE; +	ao_spi_index[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_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_config[1] = AO_SPI_CONFIG_NONE; - +	ao_spi_index[1] = AO_SPI_CONFIG_NONE;  	ao_spi_channel_init(1);  #endif  }  | 
