Add apm32f405/f407 support (#13796)
[betaflight.git] / src / main / drivers / bus.c
blob031de941175cf8ef5c67da1b9b162a7088e7d9f8
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"
31 // Access routines where the register is accessed directly
32 bool busRawWriteRegister(const extDevice_t *dev, uint8_t reg, uint8_t data)
34 #ifdef USE_SPI
35 if (dev->bus->busType == BUS_TYPE_SPI) {
36 return spiWriteRegRB(dev, reg, data);
37 } else
38 #endif
40 return busWriteRegister(dev, reg, data);
44 bool busRawWriteRegisterStart(const extDevice_t *dev, uint8_t reg, uint8_t data)
46 #ifdef USE_SPI
47 if (dev->bus->busType == BUS_TYPE_SPI) {
48 return spiWriteRegRB(dev, reg, data);
49 } else
50 #endif
52 return busWriteRegisterStart(dev, reg, data);
56 bool busRawReadRegisterBuffer(const extDevice_t *dev, uint8_t reg, uint8_t *data, uint8_t length)
58 #ifdef USE_SPI
59 if (dev->bus->busType == BUS_TYPE_SPI) {
60 return spiReadRegBufRB(dev, reg, data, length);
61 } else
62 #endif
64 return busReadRegisterBuffer(dev, reg, data, length);
68 bool busRawReadRegisterBufferStart(const extDevice_t *dev, uint8_t reg, uint8_t *data, uint8_t length)
70 #ifdef USE_SPI
71 if (dev->bus->busType == BUS_TYPE_SPI) {
72 return spiReadRegBufRB(dev, reg, data, length);
73 } else
74 #endif
76 return busReadRegisterBufferStart(dev, reg, data, length);
81 // Write routines where the register is masked with 0x7f
82 bool busWriteRegister(const extDevice_t *dev, uint8_t reg, uint8_t data)
84 #if !defined(USE_SPI) && !defined(USE_I2C)
85 UNUSED(reg);
86 UNUSED(data);
87 #endif
88 switch (dev->bus->busType) {
89 #ifdef USE_SPI
90 case BUS_TYPE_SPI:
91 return spiWriteRegRB(dev, reg & 0x7f, data);
92 #endif
93 #ifdef USE_I2C
94 case BUS_TYPE_I2C:
95 return i2cBusWriteRegister(dev, reg, data);
96 #endif
97 default:
98 return false;
102 bool busWriteRegisterStart(const extDevice_t *dev, uint8_t reg, uint8_t data)
104 #if !defined(USE_SPI) && !defined(USE_I2C)
105 UNUSED(reg);
106 UNUSED(data);
107 #endif
108 switch (dev->bus->busType) {
109 #ifdef USE_SPI
110 case BUS_TYPE_SPI:
111 return spiWriteRegRB(dev, reg & 0x7f, data);
112 #endif
113 #ifdef USE_I2C
114 case BUS_TYPE_I2C:
115 return i2cBusWriteRegisterStart(dev, reg, data);
116 #endif
117 default:
118 return false;
122 // Read routines where the register is ORed with 0x80
123 bool busReadRegisterBuffer(const extDevice_t *dev, uint8_t reg, uint8_t *data, uint8_t length)
125 #if !defined(USE_SPI) && !defined(USE_I2C)
126 UNUSED(reg);
127 UNUSED(data);
128 UNUSED(length);
129 #endif
130 switch (dev->bus->busType) {
131 #ifdef USE_SPI
132 case BUS_TYPE_SPI:
133 return spiReadRegMskBufRB(dev, reg | 0x80, data, length);
134 #endif
135 #ifdef USE_I2C
136 case BUS_TYPE_I2C:
137 return i2cBusReadRegisterBuffer(dev, reg, data, length);
138 #endif
139 default:
140 return false;
144 // Start the I2C read, but do not wait for completion
145 bool busReadRegisterBufferStart(const extDevice_t *dev, uint8_t reg, uint8_t *data, uint8_t length)
147 #if !defined(USE_SPI) && !defined(USE_I2C)
148 UNUSED(reg);
149 UNUSED(data);
150 UNUSED(length);
151 #endif
152 switch (dev->bus->busType) {
153 #ifdef USE_SPI
154 case BUS_TYPE_SPI:
155 // For SPI allow the transaction to complete
156 return spiReadRegMskBufRB(dev, reg | 0x80, data, length);
157 #endif
158 #ifdef USE_I2C
159 case BUS_TYPE_I2C:
160 // Initiate the read access
161 return i2cBusReadRegisterBufferStart(dev, reg, data, length);
162 #endif
163 default:
164 return false;
168 // Returns true if bus is still busy
169 bool busBusy(const extDevice_t *dev, bool *error)
171 #if !defined(USE_I2C)
172 UNUSED(error);
173 #endif
174 switch (dev->bus->busType) {
175 #ifdef USE_SPI
176 case BUS_TYPE_SPI:
177 // No waiting on SPI
178 return false;
179 #endif
181 #ifdef USE_I2C
182 case BUS_TYPE_I2C:
183 return i2cBusBusy(dev, error);
184 #endif
186 default:
187 return false;
191 uint8_t busReadRegister(const extDevice_t *dev, uint8_t reg)
193 #if !defined(USE_SPI) && !defined(USE_I2C)
194 UNUSED(dev);
195 UNUSED(reg);
196 return false;
197 #else
198 uint8_t data;
199 busReadRegisterBuffer(dev, reg, &data, 1);
200 return data;
201 #endif
204 void busDeviceRegister(const extDevice_t *dev)
206 #if !defined(USE_SPI) && !defined(USE_I2C)
207 UNUSED(dev);
208 #endif
210 switch (dev->bus->busType) {
211 #if defined(USE_SPI)
212 case BUS_TYPE_SPI:
213 spiBusDeviceRegister(dev);
215 break;
216 #endif
217 #if defined(USE_I2C)
218 case BUS_TYPE_I2C:
219 i2cBusDeviceRegister(dev);
221 break;
222 #endif
223 default:
224 break;