54 #include <libopencm3/cm3/nvic.h>
55 #include <libopencm3/stm32/gpio.h>
56 #include <libopencm3/stm32/rcc.h>
57 #include <libopencm3/stm32/exti.h>
58 #include <libopencm3/stm32/spi.h>
59 #include <libopencm3/stm32/dma.h>
68 #ifndef NVIC_SPI_IRQ_PRIO
69 #define NVIC_SPI_IRQ_PRIO 0
109 #error "The STM32 doesn't have SPI0"
266 idx =
p->trans_insert_idx + 1;
281 p->trans[
p->trans_insert_idx] = t;
282 p->trans_insert_idx =
idx;
285 if (
p->status ==
SPIIdle && !
p->suspend) {
296 if (slave < 254 && p->suspend == 0) {
297 p->suspend = slave + 1;
308 if (
p->suspend == slave + 1) {
311 if (
p->trans_extract_idx !=
p->trans_insert_idx &&
p->status ==
SPIIdle) {
329 c->
br = SPI_CR1_BAUDRATE_FPCLK_DIV_64;
330 c->
cpol = SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE;
331 c->
cpha = SPI_CR1_CPHA_CLK_TRANSITION_2;
332 c->
dff = SPI_CR1_DFF_8BIT;
345 if (c->
cpol == SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE) {
350 if (c->
cpha == SPI_CR1_CPHA_CLK_TRANSITION_1) {
355 if (c->
lsbfirst == SPI_CR1_MSBFIRST) {
362 case SPI_CR1_BAUDRATE_FPCLK_DIV_2:
365 case SPI_CR1_BAUDRATE_FPCLK_DIV_4:
368 case SPI_CR1_BAUDRATE_FPCLK_DIV_8:
371 case SPI_CR1_BAUDRATE_FPCLK_DIV_16:
374 case SPI_CR1_BAUDRATE_FPCLK_DIV_32:
377 case SPI_CR1_BAUDRATE_FPCLK_DIV_64:
380 case SPI_CR1_BAUDRATE_FPCLK_DIV_128:
383 case SPI_CR1_BAUDRATE_FPCLK_DIV_256:
390 if (c->
dff == SPI_CR1_DFF_8BIT) {
402 c->
dff = SPI_CR1_DFF_8BIT;
404 c->
dff = SPI_CR1_DFF_16BIT;
412 c->
cpha = SPI_CR1_CPHA_CLK_TRANSITION_1;
414 c->
cpha = SPI_CR1_CPHA_CLK_TRANSITION_2;
417 c->
cpol = SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE;
419 c->
cpol = SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE;
424 c->
br = SPI_CR1_BAUDRATE_FPCLK_DIV_2;
427 c->
br = SPI_CR1_BAUDRATE_FPCLK_DIV_4;
430 c->
br = SPI_CR1_BAUDRATE_FPCLK_DIV_8;
433 c->
br = SPI_CR1_BAUDRATE_FPCLK_DIV_16;
436 c->
br = SPI_CR1_BAUDRATE_FPCLK_DIV_32;
439 c->
br = SPI_CR1_BAUDRATE_FPCLK_DIV_64;
442 c->
br = SPI_CR1_BAUDRATE_FPCLK_DIV_128;
445 c->
br = SPI_CR1_BAUDRATE_FPCLK_DIV_256;
461 rcc_periph_clock_enable(
rcc_dma);
463 dma_channel_reset(
dma, chan);
464 #elif defined STM32F4
465 dma_stream_reset(
dma, chan);
467 dma_set_peripheral_address(
dma, chan, periph_addr);
468 dma_set_memory_address(
dma, chan, buf_addr);
469 dma_set_number_of_data(
dma, chan, len);
474 dma_set_peripheral_size(
dma, chan, DMA_CCR_PSIZE_8BIT);
475 dma_set_memory_size(
dma, chan, DMA_CCR_MSIZE_8BIT);
477 dma_set_peripheral_size(
dma, chan, DMA_CCR_PSIZE_16BIT);
478 dma_set_memory_size(
dma, chan, DMA_CCR_MSIZE_16BIT);
480 #elif defined STM32F4
482 dma_set_peripheral_size(
dma, chan, DMA_SxCR_PSIZE_8BIT);
483 dma_set_memory_size(
dma, chan, DMA_SxCR_MSIZE_8BIT);
485 dma_set_peripheral_size(
dma, chan, DMA_SxCR_PSIZE_16BIT);
486 dma_set_memory_size(
dma, chan, DMA_SxCR_MSIZE_16BIT);
491 dma_enable_memory_increment_mode(
dma, chan);
493 dma_disable_memory_increment_mode(
dma, chan);
554 if (sig !=
dma->comm_sig) {
564 dma->comm.cpha,
dma->comm.dff,
dma->comm.lsbfirst);
606 dma->rx_extra_dummy_dma =
true;
610 dma_set_read_from_peripheral(
dma->dma,
dma->rx_chan);
611 dma_set_priority(
dma->dma,
dma->rx_chan, DMA_CCR_PL_VERY_HIGH);
612 #elif defined STM32F4
613 dma_channel_select(
dma->dma,
dma->rx_chan,
dma->rx_chan_sel);
614 dma_set_transfer_mode(
dma->dma,
dma->rx_chan, DMA_SxCR_DIR_PERIPHERAL_TO_MEM);
615 dma_set_priority(
dma->dma,
dma->rx_chan, DMA_SxCR_PL_VERY_HIGH);
637 dma->tx_extra_dummy_dma =
true;
641 dma_set_read_from_memory(
dma->dma,
dma->tx_chan);
642 dma_set_priority(
dma->dma,
dma->tx_chan, DMA_CCR_PL_MEDIUM);
643 #elif defined STM32F4
644 dma_channel_select(
dma->dma,
dma->tx_chan,
dma->tx_chan_sel);
645 dma_set_transfer_mode(
dma->dma,
dma->tx_chan, DMA_SxCR_DIR_MEM_TO_PERIPHERAL);
646 dma_set_priority(
dma->dma,
dma->tx_chan, DMA_SxCR_PL_MEDIUM);
650 dma_enable_transfer_complete_interrupt(
dma->dma,
dma->rx_chan);
651 dma_enable_transfer_complete_interrupt(
dma->dma,
dma->tx_chan);
655 dma_enable_channel(
dma->dma,
dma->rx_chan);
656 dma_enable_channel(
dma->dma,
dma->tx_chan);
657 #elif defined STM32F4
658 dma_enable_stream(
dma->dma,
dma->rx_chan);
659 dma_enable_stream(
dma->dma,
dma->tx_chan);
687 #elif defined STM32F4
708 spi1.reg_addr = (
void *)SPI1;
710 spi1.trans_insert_idx = 0;
711 spi1.trans_extract_idx = 0;
716 rcc_periph_clock_enable(RCC_SPI1);
723 #elif defined STM32F4
752 spi_enable_software_slave_management(SPI1);
753 spi_set_nss_high(SPI1);
778 #elif defined STM32F4
796 spi2.reg_addr = (
void *)SPI2;
798 spi2.trans_insert_idx = 0;
799 spi2.trans_extract_idx = 0;
804 rcc_periph_clock_enable(RCC_SPI2);
811 #elif defined STM32F4
839 spi_enable_software_slave_management(SPI2);
840 spi_set_nss_high(SPI2);
853 void spi3_arch_init(
void)
857 spi3_dma.spidr = (
uint32_t)&SPI3_DR;
860 spi3_dma.rcc_dma = RCC_DMA2;
861 spi3_dma.rx_chan = DMA_CHANNEL1;
862 spi3_dma.tx_chan = DMA_CHANNEL2;
863 spi3_dma.rx_nvic_irq = NVIC_DMA2_CHANNEL1_IRQ;
864 spi3_dma.tx_nvic_irq = NVIC_DMA2_CHANNEL2_IRQ;
865 #elif defined STM32F4
867 spi3_dma.rcc_dma = RCC_DMA1;
868 spi3_dma.rx_chan = DMA_STREAM0;
869 spi3_dma.tx_chan = DMA_STREAM5;
870 spi3_dma.rx_chan_sel = DMA_SxCR_CHSEL_0;
871 spi3_dma.tx_chan_sel = DMA_SxCR_CHSEL_0;
872 spi3_dma.rx_nvic_irq = NVIC_DMA1_STREAM0_IRQ;
873 spi3_dma.tx_nvic_irq = NVIC_DMA1_STREAM5_IRQ;
875 spi3_dma.tx_dummy_buf = 0;
876 spi3_dma.tx_extra_dummy_dma =
false;
877 spi3_dma.rx_dummy_buf = 0;
878 spi3_dma.rx_extra_dummy_dma =
false;
885 spi3.reg_addr = (
void *)SPI3;
886 spi3.init_struct = &spi3_dma;
887 spi3.trans_insert_idx = 0;
888 spi3.trans_extract_idx = 0;
893 rcc_periph_clock_enable(RCC_SPI3);
900 #elif defined STM32F4
921 spi_init_master(SPI3, spi3_dma.comm.br, spi3_dma.comm.cpol, spi3_dma.comm.cpha,
922 spi3_dma.comm.dff, spi3_dma.comm.lsbfirst);
930 spi_enable_software_slave_management(SPI3);
931 spi_set_nss_high(SPI3);
934 rcc_periph_clock_enable(spi3_dma.rcc_dma);
954 void dma1_channel2_isr(
void)
956 if ((DMA1_ISR & DMA_ISR_TCIF2) != 0) {
958 DMA1_IFCR |= DMA_IFCR_CTCIF2;
960 #elif defined STM32F4
961 void dma2_stream0_isr(
void) {
962 if ((DMA2_LISR & DMA_LISR_TCIF0) != 0) {
964 DMA2_LIFCR |= DMA_LIFCR_CTCIF0;
972 void dma1_channel3_isr(
void) {
973 if ((DMA1_ISR & DMA_ISR_TCIF3) != 0) {
975 DMA1_IFCR |= DMA_IFCR_CTCIF3;
977 #elif defined STM32F4
978 void dma2_stream5_isr(
void) {
979 if ((DMA2_HISR & DMA_HISR_TCIF5) != 0) {
981 DMA2_HIFCR |= DMA_HIFCR_CTCIF5;
992 void dma1_channel4_isr(
void) {
993 if ((DMA1_ISR & DMA_ISR_TCIF4) != 0) {
995 DMA1_IFCR |= DMA_IFCR_CTCIF4;
997 #elif defined STM32F4
998 void dma1_stream3_isr(
void) {
999 if ((DMA1_LISR & DMA_LISR_TCIF3) != 0) {
1001 DMA1_LIFCR |= DMA_LIFCR_CTCIF3;
1009 void dma1_channel5_isr(
void) {
1010 if ((DMA1_ISR & DMA_ISR_TCIF5) != 0) {
1012 DMA1_IFCR |= DMA_IFCR_CTCIF5;
1014 #elif defined STM32F4
1015 void dma1_stream4_isr(
void) {
1016 if ((DMA1_HISR & DMA_HISR_TCIF4) != 0) {
1018 DMA1_HIFCR |= DMA_HIFCR_CTCIF4;
1029 void dma2_channel1_isr(
void) {
1030 if ((DMA2_ISR & DMA_ISR_TCIF1) != 0) {
1032 DMA2_IFCR |= DMA_IFCR_CTCIF1;
1034 #elif defined STM32F4
1035 void dma1_stream0_isr(
void) {
1036 if ((DMA1_LISR & DMA_LISR_TCIF0) != 0) {
1038 DMA1_LIFCR |= DMA_LIFCR_CTCIF0;
1046 void dma2_channel2_isr(
void) {
1047 if ((DMA2_ISR & DMA_ISR_TCIF2) != 0) {
1049 DMA2_IFCR |= DMA_IFCR_CTCIF2;
1051 #elif defined STM32F4
1052 void dma1_stream5_isr(
void) {
1053 if ((DMA1_HISR & DMA_HISR_TCIF5) != 0) {
1055 DMA1_HIFCR |= DMA_HIFCR_CTCIF5;
1069 dma_disable_transfer_complete_interrupt(dma->
dma, dma->
rx_chan);
1077 #elif defined STM32F4
1098 dma_set_read_from_peripheral(dma->
dma, dma->
rx_chan);
1099 dma_set_priority(dma->
dma, dma->
rx_chan, DMA_CCR_PL_HIGH);
1100 #elif defined STM32F4
1102 dma_set_transfer_mode(dma->
dma, dma->
rx_chan, DMA_SxCR_DIR_PERIPHERAL_TO_MEM);
1103 dma_set_priority(dma->
dma, dma->
rx_chan, DMA_SxCR_PL_HIGH);
1107 dma_enable_transfer_complete_interrupt(dma->
dma, dma->
rx_chan);
1111 #elif defined STM32F4
1144 dma_disable_transfer_complete_interrupt(dma->
dma, dma->
tx_chan);
1152 #elif defined STM32F4
1172 dma_set_read_from_memory(dma->
dma, dma->
tx_chan);
1173 dma_set_priority(dma->
dma, dma->
tx_chan, DMA_CCR_PL_MEDIUM);
1174 #elif defined STM32F4
1176 dma_set_transfer_mode(dma->
dma, dma->
tx_chan, DMA_SxCR_DIR_MEM_TO_PERIPHERAL);
1177 dma_set_priority(dma->
dma, dma->
tx_chan, DMA_SxCR_PL_MEDIUM);
1181 dma_enable_transfer_complete_interrupt(dma->
dma, dma->
tx_chan);
1185 #elif defined STM32F4
1210 #warning "SPI1 slave: Untested code!"
1213 #error "Using SPI1 as a slave and master at the same time is not possible."
1218 void spi1_slave_arch_init(
void) {
1228 #elif defined STM32F4
1248 spi1.reg_addr = (
void *)SPI1;
1250 spi1.trans_insert_idx = 0;
1251 spi1.trans_extract_idx = 0;
1255 rcc_periph_clock_enable(RCC_SPI1);
1263 #elif defined STM32F4
1286 spi_disable_software_slave_management(SPI1);
1289 spi_set_slave_mode(SPI1);
1300 void dma1_channel2_isr(
void) {
1301 if ((DMA1_ISR & DMA_ISR_TCIF2) != 0) {
1303 DMA1_IFCR |= DMA_IFCR_CTCIF2;
1305 #elif defined STM32F4
1306 void dma2_stream0_isr(
void) {
1307 if ((DMA2_LISR & DMA_LISR_TCIF0) != 0) {
1309 DMA2_LIFCR |= DMA_LIFCR_CTCIF0;
1317 void dma1_channel3_isr(
void) {
1318 if ((DMA1_ISR & DMA_ISR_TCIF3) != 0) {
1320 DMA1_IFCR |= DMA_IFCR_CTCIF3;
1322 #elif defined STM32F4
1323 void dma2_stream5_isr(
void) {
1324 if ((DMA2_HISR & DMA_HISR_TCIF5) != 0) {
1326 DMA2_HIFCR |= DMA_HIFCR_CTCIF5;
1337 #warning "SPI2 slave only tested on STM32F1!"
1341 #error "Using SPI2 as a slave and master at the same time is not possible."
1346 void spi2_slave_arch_init(
void) {
1356 #elif defined STM32F4
1374 spi2.reg_addr = (
void *)SPI2;
1376 spi2.trans_insert_idx = 0;
1377 spi2.trans_extract_idx = 0;
1381 rcc_periph_clock_enable(RCC_SPI2);
1389 #elif defined STM32F4
1412 spi_disable_software_slave_management(SPI2);
1415 spi_set_slave_mode(SPI2);
1426 void dma1_channel4_isr(
void) {
1427 if ((DMA1_ISR & DMA_ISR_TCIF4) != 0) {
1429 DMA1_IFCR |= DMA_IFCR_CTCIF4;
1431 #elif defined STM32F4
1432 void dma1_stream3_isr(
void) {
1433 if ((DMA1_LISR & DMA_LISR_TCIF3) != 0) {
1435 DMA1_LIFCR |= DMA_LIFCR_CTCIF3;
1443 void dma1_channel5_isr(
void) {
1444 if ((DMA1_ISR & DMA_ISR_TCIF5) != 0) {
1446 DMA1_IFCR |= DMA_IFCR_CTCIF5;
1448 #elif defined STM32F4
1449 void dma1_stream4_isr(
void) {
1450 if ((DMA1_HISR & DMA_HISR_TCIF4) != 0) {
1452 DMA1_HIFCR |= DMA_HIFCR_CTCIF4;
1463 #warning "SPI3 slave only tested on STM32F4!"
1468 #error "Using SPI3 as a slave and master at the same time is not possible."
1473 void spi3_slave_arch_init(
void) {
1477 spi3_dma.dma = DMA2;
1478 spi3_dma.rcc_dma = RCC_DMA2;
1479 spi3_dma.rx_chan = DMA_CHANNEL1;
1480 spi3_dma.tx_chan = DMA_CHANNEL2;
1481 spi3_dma.rx_nvic_irq = NVIC_DMA2_CHANNEL1_IRQ;
1482 spi3_dma.tx_nvic_irq = NVIC_DMA2_CHANNEL2_IRQ;
1483 #elif defined STM32F4
1484 spi3_dma.dma = DMA1;
1485 spi3_dma.rcc_dma = RCC_DMA1;
1486 spi3_dma.rx_chan = DMA_STREAM0;
1487 spi3_dma.tx_chan = DMA_STREAM5;
1488 spi3_dma.rx_chan_sel = DMA_SxCR_CHSEL_0;
1489 spi3_dma.tx_chan_sel = DMA_SxCR_CHSEL_0;
1490 spi3_dma.rx_nvic_irq = NVIC_DMA1_STREAM0_IRQ;
1491 spi3_dma.tx_nvic_irq = NVIC_DMA1_STREAM5_IRQ;
1493 spi3_dma.tx_dummy_buf = 0;
1494 spi3_dma.tx_extra_dummy_dma =
false;
1495 spi3_dma.rx_dummy_buf = 0;
1496 spi3_dma.rx_extra_dummy_dma =
false;
1503 spi3.reg_addr = (
void *)SPI3;
1504 spi3.init_struct = &spi3_dma;
1505 spi3.trans_insert_idx = 0;
1506 spi3.trans_extract_idx = 0;
1510 rcc_periph_clock_enable(RCC_SPI3);
1519 #elif defined STM32F4
1538 spi_init_master(SPI3, spi3_dma.comm.br, spi3_dma.comm.cpol, spi3_dma.comm.cpha,
1539 spi3_dma.comm.dff, spi3_dma.comm.lsbfirst);
1542 spi_disable_software_slave_management(SPI3);
1545 spi_set_slave_mode(SPI3);
1548 rcc_periph_clock_enable(spi3_dma.rcc_dma);
1556 void dma2_channel1_isr(
void) {
1557 if ((DMA2_ISR & DMA_ISR_TCIF1) != 0) {
1559 DMA2_IFCR |= DMA_IFCR_CTCIF1;
1561 #elif defined STM32F4
1562 void dma1_stream0_isr(
void) {
1563 if ((DMA1_LISR & DMA_LISR_TCIF0) != 0) {
1565 DMA1_LIFCR |= DMA_LIFCR_CTCIF0;
1573 void dma2_channel2_isr(
void) {
1574 if ((DMA2_ISR & DMA_ISR_TCIF2) != 0) {
1576 DMA2_IFCR |= DMA_IFCR_CTCIF2;
1578 #elif defined STM32F4
1579 void dma1_stream5_isr(
void) {
1580 if ((DMA1_HISR & DMA_HISR_TCIF5) != 0) {
1582 DMA1_HIFCR |= DMA_HIFCR_CTCIF5;
1605 dma->comm.cpha,
dma->comm.dff,
dma->comm.lsbfirst);
1636 if (sig !=
dma->comm_sig) {
1647 dma_set_read_from_memory(
dma->dma,
dma->tx_chan);
1648 dma_set_priority(
dma->dma,
dma->tx_chan, DMA_CCR_PL_MEDIUM);
1649 #elif defined STM32F4
1650 dma_channel_select(
dma->dma,
dma->tx_chan,
dma->tx_chan_sel);
1651 dma_set_transfer_mode(
dma->dma,
dma->tx_chan, DMA_SxCR_DIR_MEM_TO_PERIPHERAL);
1652 dma_set_priority(
dma->dma,
dma->tx_chan, DMA_SxCR_PL_MEDIUM);
1662 dma_set_read_from_peripheral(
dma->dma,
dma->rx_chan);
1663 dma_set_priority(
dma->dma,
dma->rx_chan, DMA_CCR_PL_VERY_HIGH);
1664 #elif defined STM32F4
1665 dma_channel_select(
dma->dma,
dma->rx_chan,
dma->rx_chan_sel);
1666 dma_set_transfer_mode(
dma->dma,
dma->rx_chan, DMA_SxCR_DIR_PERIPHERAL_TO_MEM);
1667 dma_set_priority(
dma->dma,
dma->rx_chan, DMA_SxCR_PL_VERY_HIGH);
1671 dma_enable_transfer_complete_interrupt(
dma->dma,
dma->tx_chan);
1672 dma_enable_transfer_complete_interrupt(
dma->dma,
dma->rx_chan);
1676 dma_enable_channel(
dma->dma,
dma->tx_chan);
1677 dma_enable_channel(
dma->dma,
dma->rx_chan);
1678 #elif defined STM32F4
1679 dma_enable_stream(
dma->dma,
dma->tx_chan);
1680 dma_enable_stream(
dma->dma,
dma->rx_chan);
1698 dma_disable_transfer_complete_interrupt(dma->
dma, dma->
rx_chan);
1709 #elif defined STM32F4
1725 dma_disable_transfer_complete_interrupt(
dma->dma,
dma->tx_chan);
1732 dma_disable_channel(
dma->dma,
dma->tx_chan);
1733 #elif defined STM32F4
1734 dma_disable_stream(
dma->dma,
dma->tx_chan);
#define SPI_SELECT_SLAVE3_PIN
#define SPI1_GPIO_AF
SPI Config.
#define SPI1_GPIO_PORT_SCK
#define SPI_SELECT_SLAVE0_PORT
#define SPI_SELECT_SLAVE1_PIN
#define SPI_SELECT_SLAVE4_PORT
#define SPI_SELECT_SLAVE0_PIN
#define SPI1_GPIO_PORT_MISO
#define SPI_SELECT_SLAVE4_PIN
#define SPI_SELECT_SLAVE3_PORT
#define SPI_SELECT_SLAVE1_PORT
#define SPI_SELECT_SLAVE2_PORT
#define SPI_SELECT_SLAVE2_PIN
#define SPI1_GPIO_PORT_MOSI
void gpio_setup_pin_af(ioportid_t port, uint16_t pin, uint8_t af, bool is_output)
Setup a gpio for input or output with alternate function.
void gpio_setup_output(ioportid_t port, uint16_t gpios)
Setup one or more pins of the given GPIO port as outputs.
static void gpio_set(ioportid_t port, uint16_t pin)
Set a gpio output to high level.
static void gpio_clear(ioportid_t port, uint16_t pin)
Clear a gpio output to low level.
#define SPI_SELECT_SLAVE5_PIN
#define SPI_SELECT_SLAVE5_PORT
#define SPI2_GPIO_PORT_SCK
#define SPI3_GPIO_PORT_MISO
#define SPI3_GPIO_PORT_SCK
#define SPI2_GPIO_PORT_MOSI
#define SPI3_GPIO_PORT_MOSI
#define SPI2_GPIO_PORT_MISO
#define SPI1_GPIO_PORT_NSS
#define SPI2_GPIO_PORT_NSS
Some architecture independent helper functions for GPIOs.
enum SPIClockPolarity cpol
clock polarity control
enum SPIClockPhase cpha
clock phase control
enum SPISlaveSelect select
slave selection behavior
SPICallback before_cb
NULL or function called before the transaction.
enum SPIStatus status
internal state of the peripheral
SPICallback after_cb
NULL or function called after the transaction.
struct spi_transaction * trans[SPI_TRANSACTION_QUEUE_LEN]
circular buffer holding transactions
enum SPIDataSizeSelect dss
data transfer word size
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
uint16_t input_length
number of data words to read
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
volatile uint8_t * input_buf
pointer to receive buffer for DMA
volatile uint8_t suspend
control for stop/resume of the fifo
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
uint8_t trans_extract_idx
enum SPIBitOrder bitorder
MSB/LSB order.
uint16_t output_length
number of data words to write
enum SPITransactionStatus status
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
bool spi_lock(struct spi_periph *p, uint8_t slave)
spi_lock() function
#define SPI_TRANSACTION_QUEUE_LEN
SPI transaction queue length.
void spi_slave_unselect(uint8_t slave)
spi_slave_unselect() function
void spi1_arch_init(void)
Architecture dependent SPI1 initialization.
SPIDataSizeSelect
SPI data word size of transfer.
process_rx_dma_interrupt & spi2
receive transferred over DMA
bool spi_slave_register(struct spi_periph *periph, struct spi_transaction *trans)
Register a spi transaction in slave mode (only one transaction can be registered).
void spi_slave_select(uint8_t slave)
spi_slave_select() function
void spi2_arch_init(void)
Architecture dependent SPI2 initialization.
process_rx_dma_interrupt & spi1
receive transferred over DMA
bool spi_resume(struct spi_periph *p, uint8_t slave)
spi_resume() function
void spi_init_slaves(void)
spi_init_slaves() function
@ SPICpolIdleLow
CPOL = 0.
@ SPICpolIdleHigh
CPOL = 1.
@ SPISelect
slave is selected before transaction but not unselected
@ SPISelectUnselect
slave is selected before transaction and unselected after
@ SPIUnselect
slave is not selected but unselected after transaction
SPI peripheral structure.
SPI transaction structure.
#define SPI3_GPIO_PORT_NSS
Architecture independent SPI (Serial Peripheral Interface) API.
static uint8_t get_transaction_signature(struct spi_transaction *t)
uint32_t dma
DMA controller base address (DMA1 or DMA2)
uint8_t tx_nvic_irq
transmit interrupt
static uint8_t get_comm_signature(struct locm3_spi_comm *c)
static struct spi_periph_dma spi1_dma
uint16_t rx_dummy_buf
dummy rx buffer for receive only cases
uint8_t tx_chan
transmit DMA channel (or stream on F4) number
struct locm3_spi_comm comm
current communication parameters
static void process_slave_tx_dma_interrupt(struct spi_periph *periph)
SPI_MASTER.
uint32_t dff
data frame format 8/16 bits
static struct spi_periph_dma spi2_dma
static void spi_arch_int_disable(struct spi_periph *spi)
Disable DMA channel interrupts.
static void process_slave_rx_dma_interrupt(struct spi_periph *periph)
static void process_tx_dma_interrupt(struct spi_periph *periph)
Processing done after tx completes.
uint32_t br
baudrate (clock divider)
uint8_t rx_nvic_irq
receive interrupt
uint32_t lsbfirst
frame format lsb/msb first
uint32_t cpol
clock polarity
static void spi_start_dma_transaction(struct spi_periph *periph, struct spi_transaction *_trans)
Start a new transaction with DMA.
#define NVIC_SPI_IRQ_PRIO
uint32_t rx_chan_sel
F4 only: actual receive DMA channel number.
uint32_t spi
SPI peripheral identifier.
static void spi_arch_int_enable(struct spi_periph *spi)
Enable DMA channel interrupts.
static void spi_configure_dma(uint32_t dma, uint32_t rcc_dma, uint8_t chan, uint32_t periph_addr, uint32_t buf_addr, uint16_t len, enum SPIDataSizeSelect dss, bool increment)
uint16_t tx_dummy_buf
dummy tx buffer for receive only cases
static void spi_next_transaction(struct spi_periph *periph)
start next transaction if there is one in the queue
static void spi_slave_set_config(struct spi_periph *periph, struct spi_transaction *trans)
static void SpiSlaveSelect(uint8_t slave)
bool tx_extra_dummy_dma
extra tx dummy dma flag for tx_len < rx_len
static void set_default_comm_config(struct locm3_spi_comm *c)
uint8_t rx_chan
receive DMA channel (or stream on F4) number
uint8_t comm_sig
comm config signature used to check for changes
uint32_t spidr
SPI DataRegister address for DMA.
static void process_rx_dma_interrupt(struct spi_periph *periph)
Processing done after rx completes.
uint32_t tx_chan_sel
F4 only: actual transmit DMA channel number.
uint32_t rcc_dma
RCC DMA enable clock pin (RCC_DMA1 or RCC_DMA2)
static void set_comm_from_transaction(struct locm3_spi_comm *c, struct spi_transaction *t)
Update SPI communication conf from generic paparazzi SPI transaction.
static void SpiSlaveUnselect(uint8_t slave)
bool rx_extra_dummy_dma
extra rx dummy dma flag for tx_len > rx_len
Libopencm3 specifc communication parameters for a SPI peripheral in master mode.
This structure keeps track of specific config for each SPI bus, which allows for more code reuse.
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.