Blackbox device type 'file' (SITL) considered working when file handler is available
[inav.git] / src / main / drivers / bus_quadspi.h
blobe267aa24bbd4bc967dd7ff66b6b23167d94d209e
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 #pragma once
25 #include "drivers/io_types.h"
26 #include "drivers/rcc_types.h"
29 * Quad SPI supports 1/2/4 wire modes
31 * 1LINE is like SPI MISO/MOSI using D0 (MOSI)/D1(MISO).
32 * 2LINE uses D0, D1 (bidirectional).
33 * 4LINE uses D0..D3 (bidirectional)
35 * See ST Micros' AN4760 "Quad-SPI (QSPI) interface on STM32 microcontrollers"
38 #ifdef USE_QUADSPI
40 #if !defined(STM32H7)
41 #error Quad SPI unsupported on this MCU
42 #endif
44 #define QUADSPI_IO_AF_BK_IO_CFG IO_CONFIG(GPIO_MODE_AF_PP, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_NOPULL)
45 #define QUADSPI_IO_AF_CLK_CFG IO_CONFIG(GPIO_MODE_AF_PP, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_NOPULL)
46 #define QUADSPI_IO_AF_BK_CS_CFG IO_CONFIG(GPIO_MODE_AF_PP, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_PULLUP)
47 #define QUADSPI_IO_BK_CS_CFG IO_CONFIG(GPIO_MODE_OUTPUT_PP, GPIO_SPEED_FREQ_HIGH, GPIO_PULLUP)
49 typedef enum {
50 /* QSPI freq = CLK /(1 + ClockPrescaler) = 200 MHz/(1+x) */
51 QUADSPI_CLOCK_INITIALISATION = 255, // 0.78125 Mhz
52 QUADSPI_CLOCK_SLOW = 19, // 10.00000 Mhz
53 QUADSPI_CLOCK_STANDARD = 9, // 20.00000 MHz
54 QUADSPI_CLOCK_FAST = 3, // 50.00000 MHz
55 QUADSPI_CLOCK_ULTRAFAST = 1 //100.00000 MHz
56 } QUADSPIClockDivider_e;
58 typedef enum QUADSPIDevice {
59 QUADSPIINVALID = -1,
60 QUADSPIDEV_1 = 0,
61 } QUADSPIDevice;
63 #define QUADSPIDEV_COUNT 1
65 // Macros to convert between CLI bus number and SPIDevice.
66 #define QUADSPI_CFG_TO_DEV(x) ((x) - 1)
67 #define QUADSPI_DEV_TO_CFG(x) ((x) + 1)
69 typedef enum {
70 QUADSPI_MODE_BK1_ONLY = 0,
71 QUADSPI_MODE_BK2_ONLY,
72 QUADSPI_MODE_DUAL_FLASH,
73 } quadSpiMode_e;
76 // QUADSPI1_CS_FLAGS
78 #define QUADSPI_BK1_CS_MASK ((1 << 1) | (1 << 0))
80 #define QUADSPI_BK1_CS_NONE ((0 << 1) | (0 << 0))
81 #define QUADSPI_BK1_CS_HARDWARE ((0 << 1) | (1 << 0)) // pin must support QSPI Alternate function for BK1_NCS
82 #define QUADSPI_BK1_CS_SOFTWARE ((1 << 1) | (0 << 0)) // use any GPIO pin for BK1 CS
84 #define QUADSPI_BK2_CS_MASK ((1 << 3) | (1 << 2))
86 #define QUADSPI_BK2_CS_NONE ((0 << 3) | (0 << 2))
87 #define QUADSPI_BK2_CS_HARDWARE ((0 << 3) | (1 << 2)) // pin must support QSPI Alternate function for BK2_NCS
88 #define QUADSPI_BK2_CS_SOFTWARE ((1 << 3) | (0 << 2)) // use any GPIO pin for BK2 CS
90 #define QUADSPI_CS_MODE_MASK (1 << 4)
92 #define QUADSPI_CS_MODE_SEPARATE (0 << 4)
93 #define QUADSPI_CS_MODE_LINKED (1 << 4)
95 // H7 QSPI notes:
96 // Hardware supports BK1 and BK2 connected to both flash chips when using DUAL FLASH mode.
97 // Hardware does NOT support using BK1_NCS for single flash chip on BK2.
98 // It's possible to use BK1_NCS for single chip on BK2 using software CS via QUADSPI_BK2_CS_SOFTWARE
101 void quadSpiPreInit(void);
103 bool quadSpiInit(QUADSPIDevice device);
104 void quadSpiSetDivisor(QUADSPI_TypeDef *instance, uint16_t divisor);
106 bool quadSpiTransmit1LINE(QUADSPI_TypeDef *instance, uint8_t instruction, uint8_t dummyCycles, const uint8_t *out, int length);
107 bool quadSpiReceive1LINE(QUADSPI_TypeDef *instance, uint8_t instruction, uint8_t dummyCycles, uint8_t *in, int length);
108 bool quadSpiReceive4LINES(QUADSPI_TypeDef *instance, uint8_t instruction, uint8_t dummyCycles, uint8_t *in, int length);
110 bool quadSpiInstructionWithData1LINE(QUADSPI_TypeDef *instance, uint8_t instruction, uint8_t dummyCycles, const uint8_t *out, int length);
112 bool quadSpiReceiveWithAddress1LINE(QUADSPI_TypeDef *instance, uint8_t instruction, uint8_t dummyCycles, uint32_t address, uint8_t addressSize, uint8_t *in, int length);
113 bool quadSpiReceiveWithAddress4LINES(QUADSPI_TypeDef *instance, uint8_t instruction, uint8_t dummyCycles, uint32_t address, uint8_t addressSize, uint8_t *in, int length);
114 bool quadSpiTransmitWithAddress1LINE(QUADSPI_TypeDef *instance, uint8_t instruction, uint8_t dummyCycles, uint32_t address, uint8_t addressSize, const uint8_t *out, int length);
115 bool quadSpiTransmitWithAddress4LINES(QUADSPI_TypeDef *instance, uint8_t instruction, uint8_t dummyCycles, uint32_t address, uint8_t addressSize, const uint8_t *out, int length);
118 bool quadSpiInstructionWithAddress1LINE(QUADSPI_TypeDef *instance, uint8_t instruction, uint8_t dummyCycles, uint32_t address, uint8_t addressSize);
120 //bool quadSpiIsBusBusy(SPI_TypeDef *instance);
122 uint16_t quadSpiGetErrorCounter(QUADSPI_TypeDef *instance);
123 void quadSpiResetErrorCounter(QUADSPI_TypeDef *instance);
125 QUADSPIDevice quadSpiDeviceByInstance(QUADSPI_TypeDef *instance);
126 QUADSPI_TypeDef *quadSpiInstanceByDevice(QUADSPIDevice device);
129 // Config
132 typedef struct quadSpiConfig_s {
133 QUADSPIDevice device;
134 ioTag_t clk;
136 // Note: Either or both CS pin may be used in DUAL_FLASH mode, any unused pins should be IO_NONE
137 ioTag_t bk1IO0;
138 ioTag_t bk1IO1;
139 ioTag_t bk1IO2;
140 ioTag_t bk1IO3;
141 ioTag_t bk1CS;
143 ioTag_t bk2IO0;
144 ioTag_t bk2IO1;
145 ioTag_t bk2IO2;
146 ioTag_t bk2IO3;
147 ioTag_t bk2CS;
149 uint8_t mode;
151 // CS pins can be under software control, useful when using BK1CS as the CS pin for BK2 in non-DUAL-FLASH mode.
152 uint8_t csFlags;
153 } quadSpiConfig_t;
155 const quadSpiConfig_t * getQuadSpiConfig(QUADSPIDevice device);
156 void quadSpiPinConfigure(QUADSPIDevice device);
158 #endif