aboutsummaryrefslogtreecommitdiff
path: root/drivers/chibios/spi_master.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/chibios/spi_master.c')
-rw-r--r--drivers/chibios/spi_master.c148
1 files changed, 0 insertions, 148 deletions
diff --git a/drivers/chibios/spi_master.c b/drivers/chibios/spi_master.c
deleted file mode 100644
index 4852a6eba..000000000
--- a/drivers/chibios/spi_master.c
+++ /dev/null
@@ -1,148 +0,0 @@
1/* Copyright 2020 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <https://www.gnu.org/licenses/>.
15 */
16
17#include "spi_master.h"
18
19#include "timer.h"
20
21static pin_t currentSlavePin = NO_PIN;
22static SPIConfig spiConfig = {false, NULL, 0, 0, 0, 0};
23
24__attribute__((weak)) void spi_init(void) {
25 static bool is_initialised = false;
26 if (!is_initialised) {
27 is_initialised = true;
28
29 // Try releasing special pins for a short time
30 palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_INPUT);
31 palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_INPUT);
32 palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), PAL_MODE_INPUT);
33
34 chThdSleepMilliseconds(10);
35#if defined(USE_GPIOV1)
36 palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL);
37 palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL);
38 palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL);
39#else
40 palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_ALTERNATE(SPI_SCK_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
41 palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_ALTERNATE(SPI_MOSI_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
42 palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), PAL_MODE_ALTERNATE(SPI_MISO_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
43#endif
44 }
45}
46
47bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
48 if (currentSlavePin != NO_PIN || slavePin == NO_PIN) {
49 return false;
50 }
51
52 uint16_t roundedDivisor = 2;
53 while (roundedDivisor < divisor) {
54 roundedDivisor <<= 1;
55 }
56
57 if (roundedDivisor < 2 || roundedDivisor > 256) {
58 return false;
59 }
60
61 spiConfig.cr1 = 0;
62
63 if (lsbFirst) {
64 spiConfig.cr1 |= SPI_CR1_LSBFIRST;
65 }
66
67 switch (mode) {
68 case 0:
69 break;
70 case 1:
71 spiConfig.cr1 |= SPI_CR1_CPHA;
72 break;
73 case 2:
74 spiConfig.cr1 |= SPI_CR1_CPOL;
75 break;
76 case 3:
77 spiConfig.cr1 |= SPI_CR1_CPHA | SPI_CR1_CPOL;
78 break;
79 }
80
81 switch (roundedDivisor) {
82 case 2:
83 break;
84 case 4:
85 spiConfig.cr1 |= SPI_CR1_BR_0;
86 break;
87 case 8:
88 spiConfig.cr1 |= SPI_CR1_BR_1;
89 break;
90 case 16:
91 spiConfig.cr1 |= SPI_CR1_BR_1 | SPI_CR1_BR_0;
92 break;
93 case 32:
94 spiConfig.cr1 |= SPI_CR1_BR_2;
95 break;
96 case 64:
97 spiConfig.cr1 |= SPI_CR1_BR_2 | SPI_CR1_BR_0;
98 break;
99 case 128:
100 spiConfig.cr1 |= SPI_CR1_BR_2 | SPI_CR1_BR_1;
101 break;
102 case 256:
103 spiConfig.cr1 |= SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0;
104 break;
105 }
106
107 currentSlavePin = slavePin;
108 spiConfig.ssport = PAL_PORT(slavePin);
109 spiConfig.sspad = PAL_PAD(slavePin);
110
111 setPinOutput(slavePin);
112 spiStart(&SPI_DRIVER, &spiConfig);
113 spiSelect(&SPI_DRIVER);
114
115 return true;
116}
117
118spi_status_t spi_write(uint8_t data) {
119 uint8_t rxData;
120 spiExchange(&SPI_DRIVER, 1, &data, &rxData);
121
122 return rxData;
123}
124
125spi_status_t spi_read(void) {
126 uint8_t data = 0;
127 spiReceive(&SPI_DRIVER, 1, &data);
128
129 return data;
130}
131
132spi_status_t spi_transmit(const uint8_t *data, uint16_t length) {
133 spiSend(&SPI_DRIVER, length, data);
134 return SPI_STATUS_SUCCESS;
135}
136
137spi_status_t spi_receive(uint8_t *data, uint16_t length) {
138 spiReceive(&SPI_DRIVER, length, data);
139 return SPI_STATUS_SUCCESS;
140}
141
142void spi_stop(void) {
143 if (currentSlavePin != NO_PIN) {
144 spiUnselect(&SPI_DRIVER);
145 spiStop(&SPI_DRIVER);
146 currentSlavePin = NO_PIN;
147 }
148}