Merge pull request #9742 from mikeller/fix_spi_transaction_support
[betaflight.git] / src / main / drivers / bus.c
blob3469dce0cd7dc012e45fc5d25577c900506a0567
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include <stdbool.h>
22 #include <stdint.h>
24 #include "platform.h"
26 #include "drivers/bus.h"
27 #include "drivers/bus_i2c_busdev.h"
28 #include "drivers/bus_spi.h"
30 bool busRawWriteRegister(const busDevice_t *busdev, uint8_t reg, uint8_t data)
32 #ifdef USE_SPI
33 if (busdev->bustype == BUSTYPE_SPI) {
34 #ifdef USE_SPI_TRANSACTION
35 spiBusTransactionSetup(busdev);
36 #endif
37 return spiBusWriteRegister(busdev, reg, data);
38 } else
39 #endif
41 return busWriteRegister(busdev, reg, data);
45 bool busWriteRegister(const busDevice_t *busdev, uint8_t reg, uint8_t data)
47 #if !defined(USE_SPI) && !defined(USE_I2C)
48 UNUSED(reg);
49 UNUSED(data);
50 #endif
51 switch (busdev->bustype) {
52 #ifdef USE_SPI
53 case BUSTYPE_SPI:
54 #ifdef USE_SPI_TRANSACTION
55 // XXX Watch out fastpath users, if any
56 return spiBusTransactionWriteRegister(busdev, reg & 0x7f, data);
57 #else
58 return spiBusWriteRegister(busdev, reg & 0x7f, data);
59 #endif
60 #endif
61 #ifdef USE_I2C
62 case BUSTYPE_I2C:
63 return i2cBusWriteRegister(busdev, reg, data);
64 #endif
65 default:
66 return false;
70 bool busRawWriteRegisterStart(const busDevice_t *busdev, uint8_t reg, uint8_t data)
72 #ifdef USE_SPI
73 if (busdev->bustype == BUSTYPE_SPI) {
74 #ifdef USE_SPI_TRANSACTION
75 spiBusTransactionSetup(busdev);
76 #endif
77 return spiBusWriteRegister(busdev, reg, data);
78 } else
79 #endif
81 return busWriteRegisterStart(busdev, reg, data);
85 bool busWriteRegisterStart(const busDevice_t *busdev, uint8_t reg, uint8_t data)
87 #if !defined(USE_SPI) && !defined(USE_I2C)
88 UNUSED(reg);
89 UNUSED(data);
90 #endif
91 switch (busdev->bustype) {
92 #ifdef USE_SPI
93 case BUSTYPE_SPI:
94 #ifdef USE_SPI_TRANSACTION
95 // XXX Watch out fastpath users, if any
96 return spiBusTransactionWriteRegister(busdev, reg & 0x7f, data);
97 #else
98 return spiBusWriteRegister(busdev, reg & 0x7f, data);
99 #endif
100 #endif
101 #ifdef USE_I2C
102 case BUSTYPE_I2C:
103 return i2cBusWriteRegisterStart(busdev, reg, data);
104 #endif
105 default:
106 return false;
110 bool busRawReadRegisterBuffer(const busDevice_t *busdev, uint8_t reg, uint8_t *data, uint8_t length)
112 #ifdef USE_SPI
113 if (busdev->bustype == BUSTYPE_SPI) {
114 #ifdef USE_SPI_TRANSACTION
115 spiBusTransactionSetup(busdev);
116 #endif
117 return spiBusRawReadRegisterBuffer(busdev, reg, data, length);
118 } else
119 #endif
121 return busReadRegisterBuffer(busdev, reg, data, length);
125 bool busReadRegisterBuffer(const busDevice_t *busdev, uint8_t reg, uint8_t *data, uint8_t length)
127 #if !defined(USE_SPI) && !defined(USE_I2C)
128 UNUSED(reg);
129 UNUSED(data);
130 UNUSED(length);
131 #endif
132 switch (busdev->bustype) {
133 #ifdef USE_SPI
134 case BUSTYPE_SPI:
135 #ifdef USE_SPI_TRANSACTION
136 // XXX Watch out fastpath users, if any
137 return spiBusTransactionReadRegisterBuffer(busdev, reg | 0x80, data, length);
138 #else
139 return spiBusReadRegisterBuffer(busdev, reg | 0x80, data, length);
140 #endif
141 #endif
142 #ifdef USE_I2C
143 case BUSTYPE_I2C:
144 return i2cBusReadRegisterBuffer(busdev, reg, data, length);
145 #endif
146 default:
147 return false;
151 bool busRawReadRegisterBufferStart(const busDevice_t *busdev, uint8_t reg, uint8_t *data, uint8_t length)
153 #ifdef USE_SPI
154 if (busdev->bustype == BUSTYPE_SPI) {
155 #ifdef USE_SPI_TRANSACTION
156 spiBusTransactionSetup(busdev);
157 #endif
158 return spiBusRawReadRegisterBuffer(busdev, reg, data, length);
159 } else
160 #endif
162 return busReadRegisterBufferStart(busdev, reg, data, length);
166 // Start the I2C read, but do not wait for completion
167 bool busReadRegisterBufferStart(const busDevice_t *busdev, uint8_t reg, uint8_t *data, uint8_t length)
169 #if !defined(USE_SPI) && !defined(USE_I2C)
170 UNUSED(reg);
171 UNUSED(data);
172 UNUSED(length);
173 #endif
174 switch (busdev->bustype) {
175 #ifdef USE_SPI
176 case BUSTYPE_SPI:
177 // For SPI allow the transaction to complete
178 #ifdef USE_SPI_TRANSACTION
179 // XXX Watch out fastpath users, if any
180 return spiBusTransactionReadRegisterBuffer(busdev, reg | 0x80, data, length);
181 #else
182 return spiBusReadRegisterBuffer(busdev, reg | 0x80, data, length);
183 #endif
184 #endif
185 #ifdef USE_I2C
186 case BUSTYPE_I2C:
187 // Initiate the read access
188 return i2cBusReadRegisterBufferStart(busdev, reg, data, length);
189 #endif
190 default:
191 return false;
195 // Returns true if bus is still busy
196 bool busBusy(const busDevice_t *busdev, bool *error)
198 #if !defined(USE_I2C)
199 UNUSED(error);
200 #endif
201 switch (busdev->bustype) {
202 #ifdef USE_SPI
203 case BUSTYPE_SPI:
204 // No waiting on SPI
205 return false;
206 #endif
208 #ifdef USE_I2C
209 case BUSTYPE_I2C:
210 return i2cBusBusy(busdev, error);
211 #endif
213 default:
214 return false;
218 uint8_t busReadRegister(const busDevice_t *busdev, uint8_t reg)
220 #if !defined(USE_SPI) && !defined(USE_I2C)
221 UNUSED(busdev);
222 UNUSED(reg);
223 return false;
224 #else
225 uint8_t data;
226 busReadRegisterBuffer(busdev, reg, &data, 1);
227 return data;
228 #endif