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"
144 #endif // USE_SPI_SLAVE0
149 #endif //USE_SPI_SLAVE1
154 #endif //USE_SPI_SLAVE2
159 #endif //USE_SPI_SLAVE3
164 #endif //USE_SPI_SLAVE4
169 #endif //USE_SPI_SLAVE5
182 #endif // USE_SPI_SLAVE0
187 #endif //USE_SPI_SLAVE1
192 #endif //USE_SPI_SLAVE2
197 #endif //USE_SPI_SLAVE3
202 #endif //USE_SPI_SLAVE4
207 #endif //USE_SPI_SLAVE5
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;
333 c->lsbfirst = SPI_CR1_MSBFIRST;
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;
407 c->lsbfirst = SPI_CR1_MSBFIRST;
409 c->lsbfirst = SPI_CR1_LSBFIRST;
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
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
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);