Fix function brace style
[betaflight.git] / src / main / drivers / bus_quadspi.c
blob1ebc4903d513d2d42010733ef621b2361bd5033e
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/>.
20 * Author: Dominic Clifton
23 #include <stdbool.h>
24 #include <stdint.h>
25 #include <string.h>
27 #include "platform.h"
29 #ifdef USE_QUADSPI
31 #include "drivers/bus_quadspi.h"
32 #include "drivers/bus_quadspi_impl.h"
33 #include "drivers/exti.h"
34 #include "drivers/io.h"
35 #include "drivers/rcc.h"
37 #include "pg/bus_quadspi.h"
39 quadSpiDevice_t quadSpiDevice[QUADSPIDEV_COUNT] = { 0 };
41 QUADSPIDevice quadSpiDeviceByInstance(QUADSPI_TypeDef *instance)
43 #ifdef USE_QUADSPI_DEVICE_1
44 if (instance == QUADSPI) {
45 return QUADSPIDEV_1;
47 #endif
49 return QUADSPIINVALID;
52 QUADSPI_TypeDef *quadSpiInstanceByDevice(QUADSPIDevice device)
54 if (device == QUADSPIINVALID || device >= QUADSPIDEV_COUNT) {
55 return NULL;
58 return quadSpiDevice[device].dev;
61 bool quadSpiInit(QUADSPIDevice device)
63 switch (device) {
64 case QUADSPIINVALID:
65 return false;
66 case QUADSPIDEV_1:
67 #ifdef USE_QUADSPI_DEVICE_1
68 quadSpiInitDevice(device);
69 return true;
70 #else
71 break;
72 #endif
74 return false;
77 uint32_t quadSpiTimeoutUserCallback(QUADSPI_TypeDef *instance)
79 QUADSPIDevice device = quadSpiDeviceByInstance(instance);
80 if (device == QUADSPIINVALID) {
81 return -1;
83 quadSpiDevice[device].errorCount++;
84 return quadSpiDevice[device].errorCount;
87 uint16_t quadSpiGetErrorCounter(QUADSPI_TypeDef *instance)
89 QUADSPIDevice device = quadSpiDeviceByInstance(instance);
90 if (device == QUADSPIINVALID) {
91 return 0;
93 return quadSpiDevice[device].errorCount;
96 void quadSpiResetErrorCounter(QUADSPI_TypeDef *instance)
98 QUADSPIDevice device = quadSpiDeviceByInstance(instance);
99 if (device != QUADSPIINVALID) {
100 quadSpiDevice[device].errorCount = 0;
104 const quadSpiHardware_t quadSpiHardware[] = {
105 #ifdef STM32H7
107 .device = QUADSPIDEV_1,
108 .reg = QUADSPI,
109 .clkPins = {
110 { DEFIO_TAG_E(PB2), GPIO_AF9_QUADSPI },
112 .bk1IO0Pins = {
113 { DEFIO_TAG_E(PC9), GPIO_AF9_QUADSPI },
114 { DEFIO_TAG_E(PD11), GPIO_AF9_QUADSPI },
115 { DEFIO_TAG_E(PF8), GPIO_AF10_QUADSPI },
117 .bk1IO1Pins = {
118 { DEFIO_TAG_E(PC10), GPIO_AF9_QUADSPI },
119 { DEFIO_TAG_E(PD12), GPIO_AF9_QUADSPI },
120 { DEFIO_TAG_E(PF9), GPIO_AF10_QUADSPI },
122 .bk1IO2Pins = {
123 { DEFIO_TAG_E(PE2), GPIO_AF9_QUADSPI },
124 { DEFIO_TAG_E(PF7), GPIO_AF9_QUADSPI },
126 .bk1IO3Pins = {
127 { DEFIO_TAG_E(PA1), GPIO_AF9_QUADSPI },
128 { DEFIO_TAG_E(PD13), GPIO_AF9_QUADSPI },
129 { DEFIO_TAG_E(PF6), GPIO_AF9_QUADSPI },
131 .bk1CSPins = {
132 { DEFIO_TAG_E(PB6), GPIO_AF10_QUADSPI },
133 { DEFIO_TAG_E(PB10), GPIO_AF9_QUADSPI },
134 { DEFIO_TAG_E(PG6), GPIO_AF10_QUADSPI },
136 .bk2IO0Pins = {
137 { DEFIO_TAG_E(PE7), GPIO_AF10_QUADSPI },
138 //{ DEFIO_TAG_E(PH7), GPIO_AF9_QUADSPI }, // FIXME regenerate io_def_generated with support for GPIO 'H'
140 .bk2IO1Pins = {
141 { DEFIO_TAG_E(PE8), GPIO_AF10_QUADSPI },
142 //{ DEFIO_TAG_E(PH3), GPIO_AF9_QUADSPI }, // FIXME regenerate io_def_generated with support for GPIO 'H'
144 .bk2IO2Pins = {
145 { DEFIO_TAG_E(PE9), GPIO_AF10_QUADSPI },
146 { DEFIO_TAG_E(PG9), GPIO_AF9_QUADSPI },
148 .bk2IO3Pins = {
149 { DEFIO_TAG_E(PE10), GPIO_AF10_QUADSPI },
150 { DEFIO_TAG_E(PG14), GPIO_AF9_QUADSPI },
152 .bk2CSPins = {
153 { DEFIO_TAG_E(PC11), GPIO_AF9_QUADSPI },
155 .rcc = RCC_AHB3(QSPI),
157 #endif
160 void quadSpiPinConfigure(const quadSpiConfig_t *pConfig)
162 for (size_t hwindex = 0; hwindex < ARRAYLEN(quadSpiHardware); hwindex++) {
163 const quadSpiHardware_t *hw = &quadSpiHardware[hwindex];
165 if (!hw->reg) {
166 continue;
169 QUADSPIDevice device = hw->device;
170 quadSpiDevice_t *pDev = &quadSpiDevice[device];
172 for (int pindex = 0; pindex < MAX_QUADSPI_PIN_SEL; pindex++) {
173 if (pConfig[device].ioTagClk == hw->clkPins[pindex].pin) {
174 pDev->clk = hw->clkPins[pindex].pin;
177 // BK1
179 if (pConfig[device].ioTagBK1IO0 == hw->bk1IO0Pins[pindex].pin) {
180 pDev->bk1IO0 = hw->bk1IO0Pins[pindex].pin;
181 pDev->bk1IO0AF = hw->bk1IO0Pins[pindex].af;
183 if (pConfig[device].ioTagBK1IO1 == hw->bk1IO1Pins[pindex].pin) {
184 pDev->bk1IO1 = hw->bk1IO1Pins[pindex].pin;
185 pDev->bk1IO1AF = hw->bk1IO1Pins[pindex].af;
187 if (pConfig[device].ioTagBK1IO2 == hw->bk1IO2Pins[pindex].pin) {
188 pDev->bk1IO2 = hw->bk1IO2Pins[pindex].pin;
189 pDev->bk1IO2AF = hw->bk1IO2Pins[pindex].af;
191 if (pConfig[device].ioTagBK1IO3 == hw->bk1IO3Pins[pindex].pin) {
192 pDev->bk1IO3 = hw->bk1IO3Pins[pindex].pin;
193 pDev->bk1IO3AF = hw->bk1IO3Pins[pindex].af;
195 if (pConfig[device].ioTagBK1CS == hw->bk1CSPins[pindex].pin) {
196 pDev->bk1CS = hw->bk1CSPins[pindex].pin;
197 pDev->bk1CSAF = hw->bk1CSPins[pindex].af;
200 // BK2
202 if (pConfig[device].ioTagBK2IO0 == hw->bk2IO0Pins[pindex].pin) {
203 pDev->bk2IO0 = hw->bk2IO0Pins[pindex].pin;
204 pDev->bk2IO0AF = hw->bk2IO0Pins[pindex].af;
206 if (pConfig[device].ioTagBK2IO1 == hw->bk2IO1Pins[pindex].pin) {
207 pDev->bk2IO1 = hw->bk2IO1Pins[pindex].pin;
208 pDev->bk2IO1AF = hw->bk2IO1Pins[pindex].af;
210 if (pConfig[device].ioTagBK2IO2 == hw->bk2IO2Pins[pindex].pin) {
211 pDev->bk2IO2 = hw->bk2IO2Pins[pindex].pin;
212 pDev->bk2IO2AF = hw->bk2IO2Pins[pindex].af;
214 if (pConfig[device].ioTagBK2IO3 == hw->bk2IO3Pins[pindex].pin) {
215 pDev->bk2IO3 = hw->bk2IO3Pins[pindex].pin;
216 pDev->bk2IO3AF = hw->bk2IO3Pins[pindex].af;
218 if (pConfig[device].ioTagBK2CS == hw->bk2CSPins[pindex].pin) {
219 pDev->bk2CS = hw->bk2CSPins[pindex].pin;
220 pDev->bk2CSAF = hw->bk2CSPins[pindex].af;
224 if ((quadSpiConfig(device)->csFlags & QUADSPI_BK1_CS_MASK) == QUADSPI_BK1_CS_SOFTWARE) {
225 pDev->bk1CS = pConfig[device].ioTagBK1CS;
227 if ((quadSpiConfig(device)->csFlags & QUADSPI_BK2_CS_MASK) == QUADSPI_BK2_CS_SOFTWARE) {
228 pDev->bk2CS = pConfig[device].ioTagBK2CS;
231 bool haveResources = true;
233 // clock pins
235 haveResources = haveResources && pDev->clk;
237 // data pins
239 bool needBK1 = (pConfig[device].mode == QUADSPI_MODE_DUAL_FLASH) || (pConfig[device].mode == QUADSPI_MODE_BK1_ONLY);
240 if (needBK1) {
241 bool haveBK1Resources = pDev->bk1IO0 && pDev->bk1IO1 && pDev->bk1IO2 && pDev->bk1IO3 && pDev->bk1CS;
242 haveResources = haveResources && haveBK1Resources;
245 bool needBK2 = (pConfig[device].mode == QUADSPI_MODE_DUAL_FLASH) || (pConfig[device].mode == QUADSPI_MODE_BK2_ONLY);
246 if (needBK2) {
247 bool haveBK2Resources = pDev->bk2IO0 && pDev->bk2IO1 && pDev->bk2IO2 && pDev->bk2IO3;
248 haveResources = haveResources && haveBK2Resources;
251 // cs pins
253 if (needBK1) {
254 haveResources = haveResources && pDev->bk1CS;
257 bool needBK2CS =
258 (pConfig[device].mode == QUADSPI_MODE_DUAL_FLASH && (pConfig[device].csFlags & QUADSPI_CS_MODE_MASK) == QUADSPI_CS_MODE_SEPARATE) ||
259 (pConfig[device].mode == QUADSPI_MODE_BK2_ONLY);
261 if (needBK2CS) {
262 haveResources = haveResources && pDev->bk2CS;
266 if (haveResources) {
267 pDev->dev = hw->reg;
268 pDev->rcc = hw->rcc;
273 #endif