#define _GNU_SOURCE #include #include #include #include #include #include static int stm32f1_spi_tx_rx(struct spi_dev *dev, void *rx_buf, size_t rx_len, const void *tx_buf, size_t tx_len); static struct spi_ops stm32f1_spi_ops = { .tx_rx = stm32f1_spi_tx_rx, }; static void stm32f1_spi_init(void) { spi_reset(SPI1); spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_2, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); spi_enable_software_slave_management(SPI1); spi_set_nss_high(SPI1); spi_enable(SPI1); gpio_set(GPIOA, GPIO_SPI1_NSS); } struct spi_dev *spi_probe(void) { struct spi_dev *dev; if (!(dev = malloc(sizeof *dev))) return NULL; dev->ops = &stm32f1_spi_ops; dev->dev_id = SPI1; stm32f1_spi_init(); return dev; } void spi_release(struct spi_dev *dev) { free(dev); } static int stm32f1_spi_tx_rx(struct spi_dev *dev, void *rx_buf, size_t rx_len, const void *tx_buf, size_t tx_len) { char *rx = rx_buf; const char *tx = tx_buf; size_t i; gpio_clear(GPIOA, GPIO_SPI1_NSS); for (i = 0; i < tx_len; ++i) { spi_send(dev->dev_id, *tx++); (void)spi_read(dev->dev_id); } if (rx_buf) { for (i = 0; i < rx_len; ++i) { spi_send(dev->dev_id, 0); *rx++ = spi_read(dev->dev_id); } } gpio_set(GPIOA, GPIO_SPI1_NSS); return 0; }