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)
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
30 #include "bus_quadspi.h"
31 #include "bus_quadspi_impl.h"
38 #include "pg/bus_quadspi.h"
40 static void Error_Handler(void) { while (1) { } }
42 void quadSpiInitDevice(QUADSPIDevice device
)
44 quadSpiDevice_t
*quadSpi
= &(quadSpiDevice
[device
]);
46 // Enable QUADSPI clock
47 RCC_ClockCmd(quadSpi
->rcc
, ENABLE
);
48 RCC_ResetCmd(quadSpi
->rcc
, ENABLE
);
50 IOInit(IOGetByTag(quadSpi
->clk
), OWNER_QUADSPI_CLK
, RESOURCE_INDEX(device
));
51 IOInit(IOGetByTag(quadSpi
->bk1IO0
), OWNER_QUADSPI_BK1IO0
, RESOURCE_INDEX(device
));
52 IOInit(IOGetByTag(quadSpi
->bk1IO1
), OWNER_QUADSPI_BK1IO1
, RESOURCE_INDEX(device
));
53 IOInit(IOGetByTag(quadSpi
->bk1IO2
), OWNER_QUADSPI_BK1IO2
, RESOURCE_INDEX(device
));
54 IOInit(IOGetByTag(quadSpi
->bk1IO3
), OWNER_QUADSPI_BK1IO3
, RESOURCE_INDEX(device
));
55 IOInit(IOGetByTag(quadSpi
->bk1CS
), OWNER_QUADSPI_BK1CS
, RESOURCE_INDEX(device
));
57 IOInit(IOGetByTag(quadSpi
->bk2IO0
), OWNER_QUADSPI_BK2IO0
, RESOURCE_INDEX(device
));
58 IOInit(IOGetByTag(quadSpi
->bk2IO1
), OWNER_QUADSPI_BK2IO1
, RESOURCE_INDEX(device
));
59 IOInit(IOGetByTag(quadSpi
->bk2IO2
), OWNER_QUADSPI_BK2IO2
, RESOURCE_INDEX(device
));
60 IOInit(IOGetByTag(quadSpi
->bk2IO3
), OWNER_QUADSPI_BK2IO3
, RESOURCE_INDEX(device
));
61 IOInit(IOGetByTag(quadSpi
->bk2CS
), OWNER_QUADSPI_BK2CS
, RESOURCE_INDEX(device
));
64 // clock is only on AF9
65 // IO and CS lines are on AF9 and AF10
66 IOConfigGPIOAF(IOGetByTag(quadSpi
->clk
), QUADSPI_IO_AF_CLK_CFG
, GPIO_AF9_QUADSPI
);
67 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk1IO0
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk1IO0AF
);
68 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk1IO1
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk1IO1AF
);
69 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk1IO2
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk1IO2AF
);
70 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk1IO3
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk1IO3AF
);
71 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk2IO0
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk2IO0AF
);
72 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk2IO1
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk2IO1AF
);
73 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk2IO2
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk2IO2AF
);
74 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk2IO3
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk2IO3AF
);
76 if ((quadSpiConfig(device
)->csFlags
& QUADSPI_BK1_CS_MASK
) == QUADSPI_BK1_CS_HARDWARE
) {
77 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk1CS
), QUADSPI_IO_AF_BK_CS_CFG
, quadSpi
->bk1CSAF
);
79 IOConfigGPIO(IOGetByTag(quadSpi
->bk1CS
), QUADSPI_IO_BK_CS_CFG
);
82 if ((quadSpiConfig(device
)->csFlags
& QUADSPI_BK2_CS_MASK
) == QUADSPI_BK2_CS_HARDWARE
) {
83 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk2CS
), QUADSPI_IO_AF_BK_CS_CFG
, quadSpi
->bk2CSAF
);
85 IOConfigGPIO(IOGetByTag(quadSpi
->bk2CS
), QUADSPI_IO_BK_CS_CFG
);
89 quadSpi
->hquadSpi
.Instance
= quadSpi
->dev
;
90 // DeInit QUADSPI hardware
91 HAL_QSPI_DeInit(&quadSpi
->hquadSpi
);
93 quadSpi
->hquadSpi
.Init
.ClockPrescaler
= QUADSPI_CLOCK_INITIALISATION
;
94 quadSpi
->hquadSpi
.Init
.FifoThreshold
= 1;
95 quadSpi
->hquadSpi
.Init
.SampleShifting
= QSPI_SAMPLE_SHIFTING_NONE
;
96 quadSpi
->hquadSpi
.Init
.FlashSize
= 23; // address bits + 1
97 quadSpi
->hquadSpi
.Init
.ChipSelectHighTime
= QSPI_CS_HIGH_TIME_1_CYCLE
;
98 quadSpi
->hquadSpi
.Init
.ClockMode
= QSPI_CLOCK_MODE_0
;
100 switch (quadSpiConfig(device
)->mode
) {
101 case QUADSPI_MODE_BK1_ONLY
:
102 quadSpi
->hquadSpi
.Init
.FlashID
= QSPI_FLASH_ID_1
;
103 quadSpi
->hquadSpi
.Init
.DualFlash
= QSPI_DUALFLASH_DISABLE
;
105 case QUADSPI_MODE_BK2_ONLY
:
106 quadSpi
->hquadSpi
.Init
.FlashID
= QSPI_FLASH_ID_2
;
107 quadSpi
->hquadSpi
.Init
.DualFlash
= QSPI_DUALFLASH_DISABLE
;
109 case QUADSPI_MODE_DUAL_FLASH
:
110 quadSpi
->hquadSpi
.Init
.DualFlash
= QSPI_DUALFLASH_ENABLE
;
114 // Init QUADSPI hardware
115 if (HAL_QSPI_Init(&quadSpi
->hquadSpi
) != HAL_OK
)
121 static const uint32_t quadSpi_addressSizeMap
[] = {
123 QSPI_ADDRESS_16_BITS
,
124 QSPI_ADDRESS_24_BITS
,
128 static uint32_t quadSpi_addressSizeFromValue(uint8_t addressSize
)
130 return quadSpi_addressSizeMap
[((addressSize
+ 1) / 8) - 1]; // rounds to nearest QSPI_ADDRESS_* value that will hold the address.
134 * Return true if the bus is currently in the middle of a transmission.
136 bool quadSpiIsBusBusy(QUADSPI_TypeDef
*instance
)
138 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
139 if(quadSpiDevice
[device
].hquadSpi
.State
== HAL_QSPI_STATE_BUSY
)
145 #define QUADSPI_DEFAULT_TIMEOUT 10
147 void quadSpiSelectDevice(QUADSPI_TypeDef
*instance
)
149 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
151 IO_t bk1CS
= IOGetByTag(quadSpiDevice
[device
].bk1CS
);
152 IO_t bk2CS
= IOGetByTag(quadSpiDevice
[device
].bk2CS
);
154 switch(quadSpiConfig(device
)->mode
) {
155 case QUADSPI_MODE_DUAL_FLASH
:
156 if ((quadSpiConfig(device
)->csFlags
& QUADSPI_BK1_CS_MASK
) == QUADSPI_BK1_CS_SOFTWARE
) {
159 if ((quadSpiConfig(device
)->csFlags
& QUADSPI_BK2_CS_MASK
) == QUADSPI_BK2_CS_SOFTWARE
) {
163 case QUADSPI_MODE_BK1_ONLY
:
164 if ((quadSpiConfig(device
)->csFlags
& QUADSPI_BK1_CS_MASK
) == QUADSPI_BK1_CS_SOFTWARE
) {
168 case QUADSPI_MODE_BK2_ONLY
:
169 if ((quadSpiConfig(device
)->csFlags
& QUADSPI_BK2_CS_MASK
) == QUADSPI_BK2_CS_SOFTWARE
) {
176 void quadSpiDeselectDevice(QUADSPI_TypeDef
*instance
)
178 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
180 IO_t bk1CS
= IOGetByTag(quadSpiDevice
[device
].bk1CS
);
181 IO_t bk2CS
= IOGetByTag(quadSpiDevice
[device
].bk2CS
);
183 switch(quadSpiConfig(device
)->mode
) {
184 case QUADSPI_MODE_DUAL_FLASH
:
185 if ((quadSpiConfig(device
)->csFlags
& QUADSPI_BK1_CS_MASK
) == QUADSPI_BK1_CS_SOFTWARE
) {
188 if ((quadSpiConfig(device
)->csFlags
& QUADSPI_BK2_CS_MASK
) == QUADSPI_BK2_CS_SOFTWARE
) {
192 case QUADSPI_MODE_BK1_ONLY
:
193 if ((quadSpiConfig(device
)->csFlags
& QUADSPI_BK1_CS_MASK
) == QUADSPI_BK1_CS_SOFTWARE
) {
197 case QUADSPI_MODE_BK2_ONLY
:
198 if ((quadSpiConfig(device
)->csFlags
& QUADSPI_BK2_CS_MASK
) == QUADSPI_BK2_CS_SOFTWARE
) {
207 bool quadSpiTransmit1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, const uint8_t *out
, int length
)
209 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
210 HAL_StatusTypeDef status
;
213 QSPI_CommandTypeDef cmd
;
214 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
215 cmd
.AddressMode
= QSPI_ADDRESS_NONE
;
216 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
217 cmd
.DataMode
= QSPI_DATA_NONE
;
218 cmd
.DummyCycles
= dummyCycles
;
219 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
220 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
221 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
223 cmd
.Instruction
= instruction
;
227 cmd
.DataMode
= QSPI_DATA_1_LINE
;
230 quadSpiSelectDevice(instance
);
232 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
233 bool timeout
= (status
!= HAL_OK
);
235 if (out
&& length
> 0) {
236 status
= HAL_QSPI_Transmit(&quadSpiDevice
[device
].hquadSpi
, (uint8_t *)out
, QUADSPI_DEFAULT_TIMEOUT
);
237 timeout
= (status
!= HAL_OK
);
241 quadSpiDeselectDevice(instance
);
244 quadSpiTimeoutUserCallback(instance
);
251 bool quadSpiReceive1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint8_t *in
, int length
)
253 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
254 HAL_StatusTypeDef status
;
256 QSPI_CommandTypeDef cmd
;
257 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
258 cmd
.AddressMode
= QSPI_ADDRESS_NONE
;
259 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
260 cmd
.DataMode
= QSPI_DATA_1_LINE
;
261 cmd
.DummyCycles
= dummyCycles
;
262 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
263 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
264 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
266 cmd
.Instruction
= instruction
;
269 quadSpiSelectDevice(instance
);
271 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
272 bool timeout
= (status
!= HAL_OK
);
274 status
= HAL_QSPI_Receive(&quadSpiDevice
[device
].hquadSpi
, in
, QUADSPI_DEFAULT_TIMEOUT
);
276 timeout
= (status
!= HAL_OK
);
279 quadSpiDeselectDevice(instance
);
282 quadSpiTimeoutUserCallback(instance
);
289 bool quadSpiReceive4LINES(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint8_t *in
, int length
)
291 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
292 HAL_StatusTypeDef status
;
294 QSPI_CommandTypeDef cmd
;
295 cmd
.InstructionMode
= QSPI_INSTRUCTION_4_LINES
;
296 cmd
.AddressMode
= QSPI_ADDRESS_NONE
;
297 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
298 cmd
.DataMode
= QSPI_DATA_4_LINES
;
299 cmd
.DummyCycles
= dummyCycles
;
300 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
301 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
302 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
304 cmd
.Instruction
= instruction
;
307 quadSpiSelectDevice(instance
);
309 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
310 bool timeout
= (status
!= HAL_OK
);
312 status
= HAL_QSPI_Receive(&quadSpiDevice
[device
].hquadSpi
, in
, QUADSPI_DEFAULT_TIMEOUT
);
314 timeout
= (status
!= HAL_OK
);
317 quadSpiDeselectDevice(instance
);
320 quadSpiTimeoutUserCallback(instance
);
327 bool quadSpiReceiveWithAddress1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint32_t address
, uint8_t addressSize
, uint8_t *in
, int length
)
329 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
330 HAL_StatusTypeDef status
;
332 QSPI_CommandTypeDef cmd
;
333 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
334 cmd
.AddressMode
= QSPI_ADDRESS_1_LINE
;
335 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
336 cmd
.DataMode
= QSPI_DATA_1_LINE
;
337 cmd
.DummyCycles
= dummyCycles
;
338 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
339 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
340 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
342 cmd
.Instruction
= instruction
;
343 cmd
.Address
= address
;
344 cmd
.AddressSize
= quadSpi_addressSizeFromValue(addressSize
);
347 quadSpiSelectDevice(instance
);
349 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
350 bool timeout
= (status
!= HAL_OK
);
352 status
= HAL_QSPI_Receive(&quadSpiDevice
[device
].hquadSpi
, in
, QUADSPI_DEFAULT_TIMEOUT
);
353 timeout
= (status
!= HAL_OK
);
356 quadSpiDeselectDevice(instance
);
359 quadSpiTimeoutUserCallback(instance
);
367 bool quadSpiReceiveWithAddress4LINES(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint32_t address
, uint8_t addressSize
, uint8_t *in
, int length
)
369 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
370 HAL_StatusTypeDef status
;
372 QSPI_CommandTypeDef cmd
;
373 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
374 cmd
.AddressMode
= QSPI_ADDRESS_1_LINE
;
375 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
376 cmd
.DataMode
= QSPI_DATA_4_LINES
;
377 cmd
.DummyCycles
= dummyCycles
;
378 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
379 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
380 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
382 cmd
.Instruction
= instruction
;
383 cmd
.Address
= address
;
384 cmd
.AddressSize
= quadSpi_addressSizeFromValue(addressSize
);
387 quadSpiSelectDevice(instance
);
389 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
390 bool timeout
= (status
!= HAL_OK
);
392 status
= HAL_QSPI_Receive(&quadSpiDevice
[device
].hquadSpi
, in
, QUADSPI_DEFAULT_TIMEOUT
);
393 timeout
= (status
!= HAL_OK
);
396 quadSpiDeselectDevice(instance
);
399 quadSpiTimeoutUserCallback(instance
);
405 bool quadSpiTransmitWithAddress1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint32_t address
, uint8_t addressSize
, const uint8_t *out
, int length
)
407 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
408 HAL_StatusTypeDef status
;
410 QSPI_CommandTypeDef cmd
;
411 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
412 cmd
.AddressMode
= QSPI_ADDRESS_1_LINE
;
413 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
414 cmd
.DataMode
= QSPI_DATA_1_LINE
;
415 cmd
.DummyCycles
= dummyCycles
;
416 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
417 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
418 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
420 cmd
.Instruction
= instruction
;
421 cmd
.Address
= address
;
422 cmd
.AddressSize
= quadSpi_addressSizeFromValue(addressSize
);
425 quadSpiSelectDevice(instance
);
427 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
428 bool timeout
= (status
!= HAL_OK
);
431 status
= HAL_QSPI_Transmit(&quadSpiDevice
[device
].hquadSpi
, (uint8_t *)out
, QUADSPI_DEFAULT_TIMEOUT
);
432 timeout
= (status
!= HAL_OK
);
435 quadSpiDeselectDevice(instance
);
438 quadSpiTimeoutUserCallback(instance
);
445 bool quadSpiTransmitWithAddress4LINES(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint32_t address
, uint8_t addressSize
, const uint8_t *out
, int length
)
447 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
448 HAL_StatusTypeDef status
;
450 QSPI_CommandTypeDef cmd
;
451 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
452 cmd
.AddressMode
= QSPI_ADDRESS_1_LINE
;
453 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
454 cmd
.DataMode
= QSPI_DATA_4_LINES
;
455 cmd
.DummyCycles
= dummyCycles
;
456 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
457 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
458 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
460 cmd
.Instruction
= instruction
;
461 cmd
.Address
= address
;
462 cmd
.AddressSize
= quadSpi_addressSizeFromValue(addressSize
);
465 quadSpiSelectDevice(instance
);
467 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
468 bool timeout
= (status
!= HAL_OK
);
471 status
= HAL_QSPI_Transmit(&quadSpiDevice
[device
].hquadSpi
, (uint8_t *)out
, QUADSPI_DEFAULT_TIMEOUT
);
472 timeout
= (status
!= HAL_OK
);
475 quadSpiDeselectDevice(instance
);
478 quadSpiTimeoutUserCallback(instance
);
485 bool quadSpiInstructionWithAddress1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint32_t address
, uint8_t addressSize
)
487 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
488 HAL_StatusTypeDef status
;
490 QSPI_CommandTypeDef cmd
;
491 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
492 cmd
.AddressMode
= QSPI_ADDRESS_1_LINE
;
493 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
494 cmd
.DataMode
= QSPI_DATA_NONE
;
495 cmd
.DummyCycles
= dummyCycles
;
496 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
497 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
498 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
500 cmd
.Instruction
= instruction
;
501 cmd
.Address
= address
;
502 cmd
.AddressSize
= quadSpi_addressSizeFromValue(addressSize
);
505 quadSpiSelectDevice(instance
);
507 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
508 bool timeout
= (status
!= HAL_OK
);
510 quadSpiDeselectDevice(instance
);
513 quadSpiTimeoutUserCallback(instance
);
521 bool quadSpiInstructionWithData1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, const uint8_t *out
, int length
)
523 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
524 HAL_StatusTypeDef status
;
526 QSPI_CommandTypeDef cmd
;
527 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
528 cmd
.AddressMode
= QSPI_ADDRESS_NONE
;
529 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
530 cmd
.DataMode
= QSPI_DATA_1_LINE
;
531 cmd
.DummyCycles
= dummyCycles
;
532 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
533 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
534 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
536 cmd
.Instruction
= instruction
;
539 quadSpiSelectDevice(instance
);
541 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
542 bool timeout
=(status
!= HAL_OK
);
545 status
= HAL_QSPI_Transmit(&quadSpiDevice
[device
].hquadSpi
, (uint8_t *)out
, QUADSPI_DEFAULT_TIMEOUT
);
546 timeout
= (status
!= HAL_OK
);
549 quadSpiDeselectDevice(instance
);
552 quadSpiTimeoutUserCallback(instance
);
559 void quadSpiSetDivisor(QUADSPI_TypeDef
*instance
, uint16_t divisor
)
561 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
562 if (HAL_QSPI_DeInit(&quadSpiDevice
[device
].hquadSpi
) != HAL_OK
)
567 quadSpiDevice_t
*quadSpi
= &(quadSpiDevice
[device
]);
569 quadSpi
->hquadSpi
.Init
.ClockPrescaler
= divisor
;
571 HAL_QSPI_Init(&quadSpi
->hquadSpi
);