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 static void Error_Handler(void) { while (1) { } }
40 void quadSpiInitDevice(QUADSPIDevice device
)
42 quadSpiDevice_t
*quadSpi
= &(quadSpiDevice
[device
]);
44 // Enable QUADSPI clock
45 RCC_ClockCmd(quadSpi
->rcc
, ENABLE
);
46 //RCC_ResetCmd(quadSpi->rcc, ENABLE);
48 IOInit(IOGetByTag(quadSpi
->clk
), OWNER_QUADSPI
, RESOURCE_QUADSPI_CLK
, RESOURCE_INDEX(device
));
49 IOInit(IOGetByTag(quadSpi
->bk1IO0
), OWNER_QUADSPI
, RESOURCE_QUADSPI_BK1IO0
, RESOURCE_INDEX(device
));
50 IOInit(IOGetByTag(quadSpi
->bk1IO1
), OWNER_QUADSPI
, RESOURCE_QUADSPI_BK1IO1
, RESOURCE_INDEX(device
));
51 IOInit(IOGetByTag(quadSpi
->bk1IO2
), OWNER_QUADSPI
, RESOURCE_QUADSPI_BK1IO2
, RESOURCE_INDEX(device
));
52 IOInit(IOGetByTag(quadSpi
->bk1IO3
), OWNER_QUADSPI
, RESOURCE_QUADSPI_BK1IO3
, RESOURCE_INDEX(device
));
53 IOInit(IOGetByTag(quadSpi
->bk1CS
), OWNER_QUADSPI
, RESOURCE_QUADSPI_BK1CS
, RESOURCE_INDEX(device
));
55 IOInit(IOGetByTag(quadSpi
->bk2IO0
), OWNER_QUADSPI
, RESOURCE_QUADSPI_BK2IO0
, RESOURCE_INDEX(device
));
56 IOInit(IOGetByTag(quadSpi
->bk2IO1
), OWNER_QUADSPI
, RESOURCE_QUADSPI_BK2IO1
, RESOURCE_INDEX(device
));
57 IOInit(IOGetByTag(quadSpi
->bk2IO2
), OWNER_QUADSPI
, RESOURCE_QUADSPI_BK2IO2
, RESOURCE_INDEX(device
));
58 IOInit(IOGetByTag(quadSpi
->bk2IO3
), OWNER_QUADSPI
, RESOURCE_QUADSPI_BK2IO3
, RESOURCE_INDEX(device
));
59 IOInit(IOGetByTag(quadSpi
->bk2CS
), OWNER_QUADSPI
, RESOURCE_QUADSPI_BK2CS
, RESOURCE_INDEX(device
));
62 // clock is only on AF9
63 // IO and CS lines are on AF9 and AF10
64 IOConfigGPIOAF(IOGetByTag(quadSpi
->clk
), QUADSPI_IO_AF_CLK_CFG
, GPIO_AF9_QUADSPI
);
65 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk1IO0
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk1IO0AF
);
66 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk1IO1
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk1IO1AF
);
67 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk1IO2
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk1IO2AF
);
68 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk1IO3
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk1IO3AF
);
69 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk2IO0
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk2IO0AF
);
70 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk2IO1
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk2IO1AF
);
71 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk2IO2
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk2IO2AF
);
72 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk2IO3
), QUADSPI_IO_AF_BK_IO_CFG
, quadSpi
->bk2IO3AF
);
74 if ((quadSpi
->csFlags
& QUADSPI_BK1_CS_MASK
) == QUADSPI_BK1_CS_HARDWARE
) {
75 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk1CS
), QUADSPI_IO_AF_BK_CS_CFG
, quadSpi
->bk1CSAF
);
77 IOConfigGPIO(IOGetByTag(quadSpi
->bk1CS
), QUADSPI_IO_BK_CS_CFG
);
80 if ((quadSpi
->csFlags
& QUADSPI_BK2_CS_MASK
) == QUADSPI_BK2_CS_HARDWARE
) {
81 IOConfigGPIOAF(IOGetByTag(quadSpi
->bk2CS
), QUADSPI_IO_AF_BK_CS_CFG
, quadSpi
->bk2CSAF
);
83 IOConfigGPIO(IOGetByTag(quadSpi
->bk2CS
), QUADSPI_IO_BK_CS_CFG
);
87 quadSpi
->hquadSpi
.Instance
= quadSpi
->dev
;
88 // DeInit QUADSPI hardware
89 HAL_QSPI_DeInit(&quadSpi
->hquadSpi
);
91 quadSpi
->hquadSpi
.Init
.ClockPrescaler
= QUADSPI_CLOCK_INITIALISATION
;
92 quadSpi
->hquadSpi
.Init
.FifoThreshold
= 1;
93 quadSpi
->hquadSpi
.Init
.SampleShifting
= QSPI_SAMPLE_SHIFTING_NONE
;
94 quadSpi
->hquadSpi
.Init
.FlashSize
= 23; // address bits + 1
95 quadSpi
->hquadSpi
.Init
.ChipSelectHighTime
= QSPI_CS_HIGH_TIME_1_CYCLE
;
96 quadSpi
->hquadSpi
.Init
.ClockMode
= QSPI_CLOCK_MODE_0
;
98 switch (quadSpi
->mode
) {
99 case QUADSPI_MODE_BK1_ONLY
:
100 quadSpi
->hquadSpi
.Init
.FlashID
= QSPI_FLASH_ID_1
;
101 quadSpi
->hquadSpi
.Init
.DualFlash
= QSPI_DUALFLASH_DISABLE
;
103 case QUADSPI_MODE_BK2_ONLY
:
104 quadSpi
->hquadSpi
.Init
.FlashID
= QSPI_FLASH_ID_2
;
105 quadSpi
->hquadSpi
.Init
.DualFlash
= QSPI_DUALFLASH_DISABLE
;
107 case QUADSPI_MODE_DUAL_FLASH
:
108 quadSpi
->hquadSpi
.Init
.DualFlash
= QSPI_DUALFLASH_ENABLE
;
112 // Init QUADSPI hardware
113 if (HAL_QSPI_Init(&quadSpi
->hquadSpi
) != HAL_OK
)
119 static const uint32_t quadSpi_addressSizeMap
[] = {
121 QSPI_ADDRESS_16_BITS
,
122 QSPI_ADDRESS_24_BITS
,
126 static uint32_t quadSpi_addressSizeFromValue(uint8_t addressSize
)
128 return quadSpi_addressSizeMap
[((addressSize
+ 1) / 8) - 1]; // rounds to nearest QSPI_ADDRESS_* value that will hold the address.
132 * Return true if the bus is currently in the middle of a transmission.
134 bool quadSpiIsBusBusy(QUADSPI_TypeDef
*instance
)
136 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
137 if(quadSpiDevice
[device
].hquadSpi
.State
== HAL_QSPI_STATE_BUSY
)
143 #define QUADSPI_DEFAULT_TIMEOUT 10
145 void quadSpiSelectDevice(QUADSPI_TypeDef
*instance
)
147 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
149 quadSpiDevice_t
*quadSpi
= &(quadSpiDevice
[device
]);
151 IO_t bk1CS
= IOGetByTag(quadSpi
->bk1CS
);
152 IO_t bk2CS
= IOGetByTag(quadSpi
->bk2CS
);
154 switch(quadSpi
->mode
) {
155 case QUADSPI_MODE_DUAL_FLASH
:
156 if ((quadSpi
->csFlags
& QUADSPI_BK1_CS_MASK
) == QUADSPI_BK1_CS_SOFTWARE
) {
159 if ((quadSpi
->csFlags
& QUADSPI_BK2_CS_MASK
) == QUADSPI_BK2_CS_SOFTWARE
) {
163 case QUADSPI_MODE_BK1_ONLY
:
164 if ((quadSpi
->csFlags
& QUADSPI_BK1_CS_MASK
) == QUADSPI_BK1_CS_SOFTWARE
) {
168 case QUADSPI_MODE_BK2_ONLY
:
169 if ((quadSpi
->csFlags
& QUADSPI_BK2_CS_MASK
) == QUADSPI_BK2_CS_SOFTWARE
) {
176 void quadSpiDeselectDevice(QUADSPI_TypeDef
*instance
)
178 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
180 quadSpiDevice_t
*quadSpi
= &(quadSpiDevice
[device
]);
182 IO_t bk1CS
= IOGetByTag(quadSpi
->bk1CS
);
183 IO_t bk2CS
= IOGetByTag(quadSpi
->bk2CS
);
185 switch(quadSpi
->mode
) {
186 case QUADSPI_MODE_DUAL_FLASH
:
187 if ((quadSpi
->csFlags
& QUADSPI_BK1_CS_MASK
) == QUADSPI_BK1_CS_SOFTWARE
) {
190 if ((quadSpi
->csFlags
& QUADSPI_BK2_CS_MASK
) == QUADSPI_BK2_CS_SOFTWARE
) {
194 case QUADSPI_MODE_BK1_ONLY
:
195 if ((quadSpi
->csFlags
& QUADSPI_BK1_CS_MASK
) == QUADSPI_BK1_CS_SOFTWARE
) {
199 case QUADSPI_MODE_BK2_ONLY
:
200 if ((quadSpi
->csFlags
& QUADSPI_BK2_CS_MASK
) == QUADSPI_BK2_CS_SOFTWARE
) {
209 bool quadSpiTransmit1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, const uint8_t *out
, int length
)
211 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
212 HAL_StatusTypeDef status
;
215 QSPI_CommandTypeDef cmd
;
216 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
217 cmd
.AddressMode
= QSPI_ADDRESS_NONE
;
218 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
219 cmd
.DataMode
= QSPI_DATA_NONE
;
220 cmd
.DummyCycles
= dummyCycles
;
221 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
222 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
223 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
225 cmd
.Instruction
= instruction
;
229 cmd
.DataMode
= QSPI_DATA_1_LINE
;
232 quadSpiSelectDevice(instance
);
234 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
235 bool timeout
= (status
!= HAL_OK
);
237 if (out
&& length
> 0) {
238 status
= HAL_QSPI_Transmit(&quadSpiDevice
[device
].hquadSpi
, (uint8_t *)out
, QUADSPI_DEFAULT_TIMEOUT
);
239 timeout
= (status
!= HAL_OK
);
243 quadSpiDeselectDevice(instance
);
246 quadSpiTimeoutUserCallback(instance
);
253 bool quadSpiReceive1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint8_t *in
, int length
)
255 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
256 HAL_StatusTypeDef status
;
258 QSPI_CommandTypeDef cmd
;
259 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
260 cmd
.AddressMode
= QSPI_ADDRESS_NONE
;
261 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
262 cmd
.DataMode
= QSPI_DATA_1_LINE
;
263 cmd
.DummyCycles
= dummyCycles
;
264 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
265 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
266 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
268 cmd
.Instruction
= instruction
;
271 quadSpiSelectDevice(instance
);
273 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
274 bool timeout
= (status
!= HAL_OK
);
276 status
= HAL_QSPI_Receive(&quadSpiDevice
[device
].hquadSpi
, in
, QUADSPI_DEFAULT_TIMEOUT
);
278 timeout
= (status
!= HAL_OK
);
281 quadSpiDeselectDevice(instance
);
284 quadSpiTimeoutUserCallback(instance
);
291 bool quadSpiReceive4LINES(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint8_t *in
, int length
)
293 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
294 HAL_StatusTypeDef status
;
296 QSPI_CommandTypeDef cmd
;
297 cmd
.InstructionMode
= QSPI_INSTRUCTION_4_LINES
;
298 cmd
.AddressMode
= QSPI_ADDRESS_NONE
;
299 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
300 cmd
.DataMode
= QSPI_DATA_4_LINES
;
301 cmd
.DummyCycles
= dummyCycles
;
302 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
303 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
304 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
306 cmd
.Instruction
= instruction
;
309 quadSpiSelectDevice(instance
);
311 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
312 bool timeout
= (status
!= HAL_OK
);
314 status
= HAL_QSPI_Receive(&quadSpiDevice
[device
].hquadSpi
, in
, QUADSPI_DEFAULT_TIMEOUT
);
316 timeout
= (status
!= HAL_OK
);
319 quadSpiDeselectDevice(instance
);
322 quadSpiTimeoutUserCallback(instance
);
329 bool quadSpiReceiveWithAddress1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint32_t address
, uint8_t addressSize
, uint8_t *in
, int length
)
331 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
332 HAL_StatusTypeDef status
;
334 QSPI_CommandTypeDef cmd
;
335 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
336 cmd
.AddressMode
= QSPI_ADDRESS_1_LINE
;
337 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
338 cmd
.DataMode
= QSPI_DATA_1_LINE
;
339 cmd
.DummyCycles
= dummyCycles
;
340 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
341 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
342 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
344 cmd
.Instruction
= instruction
;
345 cmd
.Address
= address
;
346 cmd
.AddressSize
= quadSpi_addressSizeFromValue(addressSize
);
349 quadSpiSelectDevice(instance
);
351 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
352 bool timeout
= (status
!= HAL_OK
);
354 status
= HAL_QSPI_Receive(&quadSpiDevice
[device
].hquadSpi
, in
, QUADSPI_DEFAULT_TIMEOUT
);
355 timeout
= (status
!= HAL_OK
);
358 quadSpiDeselectDevice(instance
);
361 quadSpiTimeoutUserCallback(instance
);
369 bool quadSpiReceiveWithAddress4LINES(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint32_t address
, uint8_t addressSize
, uint8_t *in
, int length
)
371 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
372 HAL_StatusTypeDef status
;
374 QSPI_CommandTypeDef cmd
;
375 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
376 cmd
.AddressMode
= QSPI_ADDRESS_1_LINE
;
377 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
378 cmd
.DataMode
= QSPI_DATA_4_LINES
;
379 cmd
.DummyCycles
= dummyCycles
;
380 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
381 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
382 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
384 cmd
.Instruction
= instruction
;
385 cmd
.Address
= address
;
386 cmd
.AddressSize
= quadSpi_addressSizeFromValue(addressSize
);
389 quadSpiSelectDevice(instance
);
391 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
392 bool timeout
= (status
!= HAL_OK
);
394 status
= HAL_QSPI_Receive(&quadSpiDevice
[device
].hquadSpi
, in
, QUADSPI_DEFAULT_TIMEOUT
);
395 timeout
= (status
!= HAL_OK
);
398 quadSpiDeselectDevice(instance
);
401 quadSpiTimeoutUserCallback(instance
);
407 bool quadSpiTransmitWithAddress1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint32_t address
, uint8_t addressSize
, const uint8_t *out
, int length
)
409 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
410 HAL_StatusTypeDef status
;
412 QSPI_CommandTypeDef cmd
;
413 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
414 cmd
.AddressMode
= QSPI_ADDRESS_1_LINE
;
415 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
416 cmd
.DataMode
= QSPI_DATA_1_LINE
;
417 cmd
.DummyCycles
= dummyCycles
;
418 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
419 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
420 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
422 cmd
.Instruction
= instruction
;
423 cmd
.Address
= address
;
424 cmd
.AddressSize
= quadSpi_addressSizeFromValue(addressSize
);
427 quadSpiSelectDevice(instance
);
429 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
430 bool timeout
= (status
!= HAL_OK
);
433 status
= HAL_QSPI_Transmit(&quadSpiDevice
[device
].hquadSpi
, (uint8_t *)out
, QUADSPI_DEFAULT_TIMEOUT
);
434 timeout
= (status
!= HAL_OK
);
437 quadSpiDeselectDevice(instance
);
440 quadSpiTimeoutUserCallback(instance
);
447 bool quadSpiTransmitWithAddress4LINES(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint32_t address
, uint8_t addressSize
, const uint8_t *out
, int length
)
449 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
450 HAL_StatusTypeDef status
;
452 QSPI_CommandTypeDef cmd
;
453 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
454 cmd
.AddressMode
= QSPI_ADDRESS_1_LINE
;
455 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
456 cmd
.DataMode
= QSPI_DATA_4_LINES
;
457 cmd
.DummyCycles
= dummyCycles
;
458 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
459 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
460 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
462 cmd
.Instruction
= instruction
;
463 cmd
.Address
= address
;
464 cmd
.AddressSize
= quadSpi_addressSizeFromValue(addressSize
);
467 quadSpiSelectDevice(instance
);
469 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
470 bool timeout
= (status
!= HAL_OK
);
473 status
= HAL_QSPI_Transmit(&quadSpiDevice
[device
].hquadSpi
, (uint8_t *)out
, QUADSPI_DEFAULT_TIMEOUT
);
474 timeout
= (status
!= HAL_OK
);
477 quadSpiDeselectDevice(instance
);
480 quadSpiTimeoutUserCallback(instance
);
487 bool quadSpiInstructionWithAddress1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, uint32_t address
, uint8_t addressSize
)
489 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
490 HAL_StatusTypeDef status
;
492 QSPI_CommandTypeDef cmd
;
493 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
494 cmd
.AddressMode
= QSPI_ADDRESS_1_LINE
;
495 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
496 cmd
.DataMode
= QSPI_DATA_NONE
;
497 cmd
.DummyCycles
= dummyCycles
;
498 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
499 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
500 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
502 cmd
.Instruction
= instruction
;
503 cmd
.Address
= address
;
504 cmd
.AddressSize
= quadSpi_addressSizeFromValue(addressSize
);
507 quadSpiSelectDevice(instance
);
509 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
510 bool timeout
= (status
!= HAL_OK
);
512 quadSpiDeselectDevice(instance
);
515 quadSpiTimeoutUserCallback(instance
);
523 bool quadSpiInstructionWithData1LINE(QUADSPI_TypeDef
*instance
, uint8_t instruction
, uint8_t dummyCycles
, const uint8_t *out
, int length
)
525 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
526 HAL_StatusTypeDef status
;
528 QSPI_CommandTypeDef cmd
;
529 cmd
.InstructionMode
= QSPI_INSTRUCTION_1_LINE
;
530 cmd
.AddressMode
= QSPI_ADDRESS_NONE
;
531 cmd
.AlternateByteMode
= QSPI_ALTERNATE_BYTES_NONE
;
532 cmd
.DataMode
= QSPI_DATA_1_LINE
;
533 cmd
.DummyCycles
= dummyCycles
;
534 cmd
.DdrMode
= QSPI_DDR_MODE_DISABLE
;
535 cmd
.DdrHoldHalfCycle
= QSPI_DDR_HHC_ANALOG_DELAY
;
536 cmd
.SIOOMode
= QSPI_SIOO_INST_EVERY_CMD
;
538 cmd
.Instruction
= instruction
;
541 quadSpiSelectDevice(instance
);
543 status
= HAL_QSPI_Command(&quadSpiDevice
[device
].hquadSpi
, &cmd
, QUADSPI_DEFAULT_TIMEOUT
);
544 bool timeout
=(status
!= HAL_OK
);
547 status
= HAL_QSPI_Transmit(&quadSpiDevice
[device
].hquadSpi
, (uint8_t *)out
, QUADSPI_DEFAULT_TIMEOUT
);
548 timeout
= (status
!= HAL_OK
);
551 quadSpiDeselectDevice(instance
);
554 quadSpiTimeoutUserCallback(instance
);
561 void quadSpiSetDivisor(QUADSPI_TypeDef
*instance
, uint16_t divisor
)
563 QUADSPIDevice device
= quadSpiDeviceByInstance(instance
);
564 if (HAL_QSPI_DeInit(&quadSpiDevice
[device
].hquadSpi
) != HAL_OK
)
569 quadSpiDevice_t
*quadSpi
= &(quadSpiDevice
[device
]);
571 quadSpi
->hquadSpi
.Init
.ClockPrescaler
= divisor
;
573 HAL_QSPI_Init(&quadSpi
->hquadSpi
);